├── .gitignore
├── Dockerfile
├── LICENSE
├── Readme.md
├── accounts
├── __init__.py
├── backends.py
├── forms
│ ├── __init__.py
│ ├── authenticate.py
│ └── register.py
├── logging
│ ├── __init__.py
│ └── signals.py
├── migrations
│ ├── 0001_initial.py
│ └── __init__.py
├── models.py
├── templates
│ ├── base_accounts.html
│ ├── login.html
│ └── register.html
├── tests.py
├── urls.py
└── views.py
├── annotationsets
├── __init__.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20150818_0905.py
│ └── __init__.py
├── models.py
└── tests.py
├── api
├── __init__.py
├── authentication.py
├── serializers.py
├── tests.py
├── urls.py
├── views.py
└── viewsets.py
├── common
├── __init__.py
├── annotation.py
├── exceptions.py
├── knowledge
│ ├── __init__.py
│ ├── provider.py
│ ├── tests.py
│ └── wikidata
│ │ ├── __init__.py
│ │ ├── config.py
│ │ ├── provider.py
│ │ ├── wd_download.py
│ │ ├── wd_extract.py
│ │ └── wd_import.py
├── mixins.py
├── sparql.py
├── statements.py
├── tests.py
├── uri.py
└── vocab.py
├── docker-compose.yml
├── documents
├── __init__.py
├── logging
│ ├── __init__.py
│ └── signals.py
├── migrations
│ ├── 0001_initial.py
│ └── __init__.py
├── models.py
├── tests.py
├── urls.py
└── views.py
├── elasticsearch
└── wikidata
│ └── person.json.bz2
├── endpoint
├── __init__.py
├── tests.py
├── urls.py
└── views.py
├── fixtures
├── accounts.json
├── annotationsets.json
└── documents.json
├── manage.py
├── mapping.json
├── neonion
├── __init__.py
├── processors.py
├── static
│ ├── bootstrap
│ │ ├── fonts
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ └── glyphicons-halflings-regular.woff2
│ │ ├── js
│ │ │ ├── .jscsrc
│ │ │ ├── .jshintrc
│ │ │ ├── affix.js
│ │ │ ├── alert.js
│ │ │ ├── button.js
│ │ │ ├── carousel.js
│ │ │ ├── collapse.js
│ │ │ ├── dropdown.js
│ │ │ ├── modal.js
│ │ │ ├── popover.js
│ │ │ ├── scrollspy.js
│ │ │ ├── tab.js
│ │ │ ├── tests
│ │ │ │ ├── README.md
│ │ │ │ ├── index.html
│ │ │ │ ├── unit
│ │ │ │ │ ├── .jshintrc
│ │ │ │ │ ├── affix.js
│ │ │ │ │ ├── alert.js
│ │ │ │ │ ├── button.js
│ │ │ │ │ ├── carousel.js
│ │ │ │ │ ├── collapse.js
│ │ │ │ │ ├── dropdown.js
│ │ │ │ │ ├── modal.js
│ │ │ │ │ ├── phantom.js
│ │ │ │ │ ├── popover.js
│ │ │ │ │ ├── scrollspy.js
│ │ │ │ │ ├── tab.js
│ │ │ │ │ └── tooltip.js
│ │ │ │ ├── vendor
│ │ │ │ │ ├── jquery.min.js
│ │ │ │ │ ├── qunit.css
│ │ │ │ │ └── qunit.js
│ │ │ │ └── visual
│ │ │ │ │ ├── affix-with-sticky-footer.html
│ │ │ │ │ ├── affix.html
│ │ │ │ │ ├── alert.html
│ │ │ │ │ ├── button.html
│ │ │ │ │ ├── carousel.html
│ │ │ │ │ ├── collapse.html
│ │ │ │ │ ├── dropdown.html
│ │ │ │ │ ├── modal.html
│ │ │ │ │ ├── popover.html
│ │ │ │ │ ├── scrollspy.html
│ │ │ │ │ ├── tab.html
│ │ │ │ │ └── tooltip.html
│ │ │ ├── tooltip.js
│ │ │ └── transition.js
│ │ └── less
│ │ │ ├── .csscomb.json
│ │ │ ├── .csslintrc
│ │ │ ├── alerts.less
│ │ │ ├── badges.less
│ │ │ ├── bootstrap.less
│ │ │ ├── breadcrumbs.less
│ │ │ ├── button-groups.less
│ │ │ ├── buttons.less
│ │ │ ├── carousel.less
│ │ │ ├── close.less
│ │ │ ├── code.less
│ │ │ ├── component-animations.less
│ │ │ ├── dropdowns.less
│ │ │ ├── forms.less
│ │ │ ├── glyphicons.less
│ │ │ ├── grid.less
│ │ │ ├── input-groups.less
│ │ │ ├── jumbotron.less
│ │ │ ├── labels.less
│ │ │ ├── list-group.less
│ │ │ ├── media.less
│ │ │ ├── mixins.less
│ │ │ ├── mixins
│ │ │ ├── alerts.less
│ │ │ ├── background-variant.less
│ │ │ ├── border-radius.less
│ │ │ ├── buttons.less
│ │ │ ├── center-block.less
│ │ │ ├── clearfix.less
│ │ │ ├── forms.less
│ │ │ ├── gradients.less
│ │ │ ├── grid-framework.less
│ │ │ ├── grid.less
│ │ │ ├── hide-text.less
│ │ │ ├── image.less
│ │ │ ├── labels.less
│ │ │ ├── list-group.less
│ │ │ ├── nav-divider.less
│ │ │ ├── nav-vertical-align.less
│ │ │ ├── opacity.less
│ │ │ ├── pagination.less
│ │ │ ├── panels.less
│ │ │ ├── progress-bar.less
│ │ │ ├── reset-filter.less
│ │ │ ├── reset-text.less
│ │ │ ├── resize.less
│ │ │ ├── responsive-visibility.less
│ │ │ ├── size.less
│ │ │ ├── tab-focus.less
│ │ │ ├── table-row.less
│ │ │ ├── text-emphasis.less
│ │ │ ├── text-overflow.less
│ │ │ └── vendor-prefixes.less
│ │ │ ├── modals.less
│ │ │ ├── navbar.less
│ │ │ ├── navs.less
│ │ │ ├── normalize.less
│ │ │ ├── pager.less
│ │ │ ├── pagination.less
│ │ │ ├── panels.less
│ │ │ ├── popovers.less
│ │ │ ├── print.less
│ │ │ ├── progress-bars.less
│ │ │ ├── responsive-embed.less
│ │ │ ├── responsive-utilities.less
│ │ │ ├── scaffolding.less
│ │ │ ├── tables.less
│ │ │ ├── theme.less
│ │ │ ├── thumbnails.less
│ │ │ ├── tooltip.less
│ │ │ ├── type.less
│ │ │ ├── utilities.less
│ │ │ ├── variables.less
│ │ │ └── wells.less
│ ├── favicon.ico
│ ├── fonts
│ │ ├── FontAwesome.otf
│ │ ├── Lato
│ │ │ ├── Lato-Bold-latin-ext.woff2
│ │ │ ├── Lato-Bold-latin.woff2
│ │ │ ├── Lato-Bold.woff
│ │ │ ├── Lato-Light-latin-ext.woff2
│ │ │ ├── Lato-Light-latin.woff2
│ │ │ ├── Lato-Light.woff
│ │ │ ├── Lato-Regular-latin-ext.woff2
│ │ │ ├── Lato-Regular-latin.woff2
│ │ │ └── Lato-Regular.woff
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.svg
│ │ ├── fontawesome-webfont.ttf
│ │ ├── fontawesome-webfont.woff
│ │ └── fontawesome-webfont.woff2
│ ├── gulpfile.js
│ ├── img
│ │ ├── annotator-glyph-sprite.png
│ │ ├── annotator-icon-sprite.png
│ │ ├── annotator
│ │ │ ├── relation_checkmark_black.svg
│ │ │ ├── relation_checkmark_white.svg
│ │ │ ├── relation_create.svg
│ │ │ ├── relation_edit.svg
│ │ │ ├── relation_remove_black.svg
│ │ │ └── relation_remove_white.svg
│ │ ├── logo.png
│ │ └── unknown.png
│ ├── js
│ │ ├── angular
│ │ │ ├── app.js
│ │ │ ├── components.js
│ │ │ ├── controllers
│ │ │ │ ├── accounts
│ │ │ │ │ ├── group-list.js
│ │ │ │ │ └── user-list.js
│ │ │ │ ├── analyze
│ │ │ │ │ └── query.js
│ │ │ │ ├── annotations
│ │ │ │ │ ├── annotation-list.js
│ │ │ │ │ └── occurrence-list.js
│ │ │ │ ├── annotator
│ │ │ │ │ ├── annotator-context.js
│ │ │ │ │ ├── annotator-nav.js
│ │ │ │ │ ├── annotator-render-pdf.js
│ │ │ │ │ └── annotator.js
│ │ │ │ ├── common
│ │ │ │ │ └── main.js
│ │ │ │ ├── settings
│ │ │ │ │ └── metadata.js
│ │ │ │ ├── vocabulary
│ │ │ │ │ ├── concept-detail.js
│ │ │ │ │ ├── concept-list.js
│ │ │ │ │ ├── conceptset-detail.js
│ │ │ │ │ ├── conceptset-list.js
│ │ │ │ │ ├── property-detail.js
│ │ │ │ │ └── property-list.js
│ │ │ │ ├── workbench
│ │ │ │ │ ├── bulk-upload.js
│ │ │ │ │ └── orphaned-annotation-list.js
│ │ │ │ └── workspace
│ │ │ │ │ └── workspace.js
│ │ │ ├── filters.js
│ │ │ ├── lib
│ │ │ │ ├── angular-cookies.js
│ │ │ │ ├── angular-cookies.min.js
│ │ │ │ ├── angular-cookies.min.js.map
│ │ │ │ ├── angular-filter.min.js
│ │ │ │ ├── angular-mocks.js
│ │ │ │ ├── angular-resource.js
│ │ │ │ ├── angular-resource.min.js
│ │ │ │ ├── angular-resource.min.js.map
│ │ │ │ ├── angular.js
│ │ │ │ ├── angular.min.js
│ │ │ │ ├── angular.min.js.map
│ │ │ │ ├── ng-file-upload-shim.min.js
│ │ │ │ └── ng-file-upload.min.js
│ │ │ ├── root.js
│ │ │ └── services
│ │ │ │ ├── annotation-store.js
│ │ │ │ ├── annotator.js
│ │ │ │ ├── common.js
│ │ │ │ ├── concept.js
│ │ │ │ ├── conceptset.js
│ │ │ │ ├── document.js
│ │ │ │ ├── group.js
│ │ │ │ ├── linked-concept.js
│ │ │ │ ├── membership.js
│ │ │ │ ├── property.js
│ │ │ │ ├── user.js
│ │ │ │ └── workspace.js
│ │ ├── annotator
│ │ │ ├── annotator.min.js
│ │ │ ├── annotator.neonion.extensions.js
│ │ │ ├── annotator.neonion.extensions.relation.extraction.js
│ │ │ ├── annotator.neonion.extensions.relations.js
│ │ │ ├── annotator.neonion.js
│ │ │ ├── annotator.ner.js
│ │ │ └── annotator.store.min.js
│ │ ├── bootstrap.min.js
│ │ ├── jquery-ui.min.js
│ │ ├── jquery.min.js
│ │ ├── neonion-context.jsonld
│ │ ├── pdf
│ │ │ ├── pdf.js
│ │ │ ├── pdf.worker.js
│ │ │ ├── text_layer_builder.js
│ │ │ └── ui_utils.js
│ │ └── sgvizler.min.js
│ ├── less
│ │ ├── custom-bootstrap.less
│ │ ├── custom-variables.less
│ │ ├── modules
│ │ │ ├── colors.less
│ │ │ └── variables.less
│ │ ├── my-bootstrap-theme.less
│ │ ├── partials
│ │ │ ├── annotator.neonion.less
│ │ │ ├── base.less
│ │ │ ├── buttons.less
│ │ │ ├── font.less
│ │ │ ├── helper.less
│ │ │ └── links.less
│ │ ├── styleguide.md
│ │ └── vendor
│ │ │ ├── annotator.less
│ │ │ └── font-awesome.min.less
│ ├── main.css
│ ├── partials
│ │ ├── accounts-group-list.html
│ │ ├── accounts-user-list.html
│ │ ├── analyze-query.html
│ │ ├── annotation-list.html
│ │ ├── annotations
│ │ │ ├── annotation-document-list.html
│ │ │ ├── annotation-occurrence-list.html
│ │ │ ├── comment-list.html
│ │ │ ├── concept-list.html
│ │ │ └── highlight-list.html
│ │ ├── annotator
│ │ │ ├── annotator-context.html
│ │ │ ├── annotator-navigation.html
│ │ │ └── annotator.html
│ │ ├── generic-resource-list.html
│ │ ├── import-meta-data.html
│ │ ├── meta_data_in_properties.html
│ │ ├── vocabulary
│ │ │ ├── concept-detail.html
│ │ │ ├── conceptset-detail.html
│ │ │ ├── multiselect.html
│ │ │ └── property-detail.html
│ │ ├── workbench
│ │ │ ├── elasticsearch.html
│ │ │ └── orphaned-annotation-list.html
│ │ └── workspace-document-list.html
│ └── utils
│ │ ├── additional.less
│ │ └── styleguide.scss
├── templates
│ ├── accounts_management.html
│ ├── annotator.html
│ ├── base.html
│ ├── base_annotations.html
│ ├── base_annotations_documents.html
│ ├── base_annotations_occurrences.html
│ ├── base_import.html
│ ├── base_modify.html
│ ├── base_settings.html
│ ├── base_vocabulary.html
│ ├── navigation.html
│ ├── query.html
│ ├── workbench.html
│ └── workspace.html
├── templatetags
│ ├── __init__.py
│ └── custom_filters.py
├── tests.py
├── urls.py
└── views.py
├── requirements.txt
├── settings
├── __init__.py
├── default.py
├── demo.py
├── development.py
├── docker.py
├── production.py
└── test.py
├── store
├── __init__.py
├── decorators.py
├── logging
│ ├── __init__.py
│ └── annotatorLogger.py
├── urls.py
└── views.py
├── wikidata
├── __init__.py
├── models.py
├── static
│ └── js
│ │ └── annotator
│ │ └── annotator.neonion.wikidata.js
├── urls.py
├── views.py
└── wiki.py
├── wsgi_demo.py
├── wsgi_dev.py
├── wsgi_production.py
└── wsgi_test.py
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | venv
3 | *.pyc
4 | *.pyo
5 | db.*
6 | db.sqlite3
7 | staticfiles
8 | __pycache__
9 | *.log
10 | /logs
11 | /plugins/*/*
12 | !plugins/__init__.py
13 | *.*~
14 |
15 | # styleguide
16 | /node_modules
17 | /neonion/static/styleguide
18 |
19 | # converage.py files
20 | .coverage
21 | /htmlcov
22 |
23 | # ignore bash scrips
24 | *.sh
25 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:14.04
2 |
3 | RUN apt-get -y update
4 | RUN apt-get -y upgrade
5 | RUN apt-get -y install python2.7 python2.7-dev python-pip
6 | RUN apt-get -y install ruby
7 | RUN gem install sass
8 |
9 | # RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
10 |
11 | ENV BASEDIR /src
12 | ENV CODEDIR $BASEDIR/code
13 | ENV STATICFILES $CODEDIR/neonion/static/
14 |
15 | COPY . $CODEDIR
16 | # bugfix for hardcoded urls
17 | COPY settings/docker.py $CODEDIR/settings/development.py
18 |
19 | # install requirements
20 | RUN /usr/bin/pip install -r ${CODEDIR}/requirements.txt
21 |
22 | # build css
23 | RUN /usr/local/bin/sass $STATICFILES/stylesheets/main.scss $STATICFILES/css/main.css
24 |
25 | # init djang
26 | WORKDIR $CODEDIR
27 | RUN /usr/bin/python manage.py syncdb --noinput
28 | RUN /usr/bin/python manage.py loaddata fixtures/*.json
29 |
30 | RUN /usr/bin/python manage.py collectstatic --noinput
31 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # neonion
2 |
3 | neonion is a user-centered, web application for the collaborative annotation of texts developed at the [Human-Centered Computing group](https://www.mi.fu-berlin.de/inf/groups/hcc/) at Freie Universität Berlin.
4 |
5 | neonion supports semantic annotations and open standards but does not presuppose any knowledge about the technologies involved. It is the perfect fit for people who want their annotations to be exchangeable between different tools and projects. Moreover, your annotations can be connected to the linked data cloud.
6 |
7 | You can [try a demo](https://demo.neonion.imp.fu-berlin.de) of neonion. The usage is explained in the [user's manual](http://fub-hcc.github.io/neonion/).
8 |
9 |
10 | ## Prerequisites
11 |
12 | For neonion you need Python with Django installed.
13 | In addition, a set of tools and services is needed:
14 |
15 | * [Python](https://www.python.org) (Python 2 >=2.7) with `pip` and `virtualenv`
16 | * [ElasticSearch](https://www.elastic.co) (>=5.x)
17 | * **Optional**
18 | * [Sesame](http://rdf4j.org) (>=2.7)
19 |
20 | If you want to use ports other than the default ports you can change the environment settings under `settings/`.
21 |
22 | ## Getting started
23 |
24 | Create a virtualenv and install the dependencies for neonion:
25 |
26 | ```
27 | virtualenv -p /usr/bin/python2.7 pyenv
28 | source pyenv/bin/activate
29 | pip install -r neonion/requirements.txt
30 | ```
31 |
32 | Setup neonion and startup the server:
33 |
34 | ```
35 | source pyenv/bin/activate
36 | cd neonion
37 | curl -XPUT -H'Content-Type: application/json' 'http://127.0.0.1:9200/neonion/' -d @mapping.json
38 | python manage.py migrate
39 | python manage.py loaddata fixtures/*
40 | python manage.py runserver
41 | ```
42 | You should now see something like:
43 |
44 | ```
45 | Django version 1.7, using settings 'settings.development'
46 | Starting development server at http://127.0.0.1:8000/
47 | ```
48 | Open your browser and navigate to [http://127.0.0.1:8000](http://127.0.0.1:8000).
49 | By default there are two predefined accounts `neonion-admin@fu-berlin.de` and `neonion-test@fu-berlin.de`. Both have the default password `neonion` but different rights.
50 |
51 | ## Import the knowledge base from Wikidata
52 |
53 | When neonion is running you can import the provided person data with:
54 |
55 | ```
56 | source pyenv/bin/activate
57 | cd neonion
58 | python common/knowledge/wikidata/wd_import.py -f elasticsearch/wikidata/
59 | ```
60 | ## License
61 |
62 | GPL2: [http://www.gnu.org/licenses/gpl-2.0.html](http://www.gnu.org/licenses/gpl-2.0.html)
63 |
--------------------------------------------------------------------------------
/accounts/__init__.py:
--------------------------------------------------------------------------------
1 | import logging.signals
2 |
--------------------------------------------------------------------------------
/accounts/backends.py:
--------------------------------------------------------------------------------
1 | from accounts.models import User
2 |
3 |
4 | class EmailAuthBackend(object):
5 | """
6 | A custom authentication backend. Allows users to log in using their email address.
7 | """
8 |
9 | def authenticate(self, username=None, password=None):
10 | """
11 | Authentication method
12 | """
13 | try:
14 | user = User.objects.get(username=username)
15 | if user.check_password(password):
16 | return user
17 | except User.DoesNotExist:
18 | return None
19 |
20 | def get_user(self, user_id):
21 | try:
22 | user = User.objects.get(pk=user_id)
23 | if user.is_active:
24 | return user
25 | return None
26 | except User.DoesNotExist:
27 | return None
28 |
--------------------------------------------------------------------------------
/accounts/forms/__init__.py:
--------------------------------------------------------------------------------
1 | from .register import RegistrationForm
2 | from .authenticate import AuthenticationForm
--------------------------------------------------------------------------------
/accounts/forms/authenticate.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from django.contrib.auth import authenticate
3 |
4 |
5 | class AuthenticationForm(forms.Form):
6 | """
7 | Login form
8 | """
9 | username = forms.CharField(label='User',
10 | max_length=80,
11 | widget=forms.TextInput(
12 | attrs={'class': 'form-control', 'data-h5-errorid': 'invalid_username', 'required': ''}))
13 |
14 | password = forms.CharField(label='Password',
15 | widget=forms.PasswordInput(attrs={'class': 'form-control', 'required': ''}))
16 |
17 | def clean(self):
18 | # print( self.cleaned_data )
19 | username = self.cleaned_data.get('username')
20 | password = self.cleaned_data.get('password')
21 |
22 | user = authenticate(username=username, password=password)
23 | if not user:
24 | raise forms.ValidationError("Sorry, that login was invalid. Please try again.")
25 | elif not user.is_active:
26 | raise forms.ValidationError("An administrator must approve this request before you can login.")
27 | return self.cleaned_data
28 |
29 | class Meta:
30 | fields = ['username', 'password']
31 |
--------------------------------------------------------------------------------
/accounts/forms/register.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from accounts.models import User
3 |
4 |
5 | class RegistrationForm(forms.ModelForm):
6 | """
7 | Form for registering a new account.
8 | """
9 |
10 | email = forms.EmailField(label='Email',
11 | max_length=80,
12 | widget=forms.TextInput(
13 | attrs={'class': 'form-control', 'data-h5-errorid': 'invalid_email', 'required': ''}))
14 |
15 | password = forms.CharField(label='Password',
16 | widget=forms.PasswordInput(attrs={'class': 'form-control', 'required': ''}))
17 |
18 | class Meta:
19 | model = User
20 | fields = ['email', 'password']
21 |
22 | def clean(self):
23 | cleaned_data = super(RegistrationForm, self).clean()
24 | mail = cleaned_data.get('email', '')
25 | password = cleaned_data.get('password', '')
26 |
27 | return self.cleaned_data
28 |
29 | def save(self, commit=True):
30 | user = super(RegistrationForm, self).save(commit=False)
31 | user.username = user.email
32 | user.set_password(self.cleaned_data['password'])
33 | if commit:
34 | user.save()
35 | return user
36 |
--------------------------------------------------------------------------------
/accounts/logging/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/accounts/logging/__init__.py
--------------------------------------------------------------------------------
/accounts/logging/signals.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from accounts.models import User
3 | from django.dispatch import receiver
4 | from django.db.models.signals import post_save
5 | from django.conf import settings
6 |
7 | logger = logging.getLogger(__name__)
8 |
9 |
10 | @receiver(post_save, sender=User)
11 | def user_created(sender, instance, created, **kwargs):
12 | if settings.USER_LOGGING_ENABLED:
13 | if created:
14 | email = instance.email
15 | logger.info('user_created=' + email)
16 | else:
17 | email = instance.email
18 | logger.info('user_signedin=' + email)
19 |
--------------------------------------------------------------------------------
/accounts/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/accounts/migrations/__init__.py
--------------------------------------------------------------------------------
/accounts/templates/base_accounts.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block content %}
6 | {% block registration %}
7 | {% endblock %}
8 | {% endblock %}
--------------------------------------------------------------------------------
/accounts/templates/login.html:
--------------------------------------------------------------------------------
1 | {% extends "base_accounts.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Sign In{% endblock %}
6 | {% block page_id %}signin{% endblock %}
7 |
8 | {% block registration %}
9 |
10 |
11 |
32 |
33 | {% for error in form.non_field_errors %}
34 |
35 | {{ error|escape }}
36 |
37 | {% endfor %}
38 |
39 |
40 | {% endblock %}
--------------------------------------------------------------------------------
/accounts/templates/register.html:
--------------------------------------------------------------------------------
1 | {% extends "base_accounts.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Sign Up{% endblock %}
6 | {% block page_id %}signup{% endblock %}
7 |
8 | {% block registration %}
9 |
10 |
11 |
36 |
37 | {% if success %}
38 | {% if show_activation_info %}
39 |
You have successfully registered. An administrator must approve this request before you can login.
40 | {% else %}
41 |
You have successfully registered.
42 | {% endif %}
43 | {% endif %}
44 |
45 |
46 | {% endblock %}
47 |
--------------------------------------------------------------------------------
/accounts/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import patterns, url
2 |
3 | urlpatterns = [
4 | url(r'^register/?$', 'accounts.views.register'),
5 | url(r'^login/?$', 'accounts.views.login'),
6 | url(r'^logout/?$', 'accounts.views.logout'),
7 | ]
8 |
--------------------------------------------------------------------------------
/accounts/views.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 | from django.shortcuts import render_to_response, redirect
3 | from django.template import RequestContext
4 | from django.contrib.auth import login as django_login, authenticate, logout as django_logout
5 | from accounts.forms import AuthenticationForm, RegistrationForm
6 |
7 |
8 | def login(request):
9 | """
10 | Login view
11 | """
12 | if request.method == 'POST':
13 | form = AuthenticationForm(data=request.POST)
14 | if form.is_valid():
15 | user = authenticate(username=request.POST['username'], password=request.POST['password'])
16 | if user is not None:
17 | if user.is_active:
18 | django_login(request, user)
19 | return redirect('/')
20 | else:
21 | form = AuthenticationForm()
22 |
23 | return render_to_response('login.html', {
24 | 'form': form,
25 | }, context_instance=RequestContext(request))
26 |
27 |
28 | def register(request):
29 | """
30 | User registration view.
31 | """
32 | if 'accounts.backends.EmailAuthBackend' in settings.AUTHENTICATION_BACKENDS:
33 | success = False
34 | show_activation_info = False
35 | if request.method == 'POST':
36 | form = RegistrationForm(data=request.POST)
37 | if form.is_valid():
38 | user = form.save()
39 | success = True
40 | show_activation_info = not user.is_active
41 | else:
42 | form = RegistrationForm()
43 |
44 | return render_to_response('register.html', {
45 | 'form': form, 'success': success, 'show_activation_info': show_activation_info
46 | }, context_instance=RequestContext(request))
47 | else:
48 | return redirect('accounts.views.login')
49 |
50 |
51 | def logout(request):
52 | """
53 | Log out view
54 | """
55 | django_logout(request)
56 | return redirect('accounts.views.login')
--------------------------------------------------------------------------------
/annotationsets/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/annotationsets/__init__.py
--------------------------------------------------------------------------------
/annotationsets/migrations/0002_auto_20150818_0905.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | from django.db import models, migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('annotationsets', '0001_initial'),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name='linkedconcept',
16 | name='custom_query',
17 | field=models.CharField(max_length=500, null=True, blank=True),
18 | preserve_default=True,
19 | ),
20 | migrations.AddField(
21 | model_name='linkedconcept',
22 | name='retrieved_at',
23 | field=models.DateTimeField(null=True, blank=True),
24 | preserve_default=True,
25 | ),
26 | migrations.AlterField(
27 | model_name='linkedconcept',
28 | name='provider_class',
29 | field=models.CharField(max_length=100, null=True, verbose_name=b'provider_class', blank=True),
30 | ),
31 | ]
32 |
--------------------------------------------------------------------------------
/annotationsets/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/annotationsets/migrations/__init__.py
--------------------------------------------------------------------------------
/annotationsets/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from common.vocab import neonion
3 | from common.mixins import ResourceMixin
4 |
5 |
6 | class LinkedProperty(ResourceMixin, models.Model):
7 | # URI to the property in then external ontology
8 | linked_property = models.URLField('linked_property', blank=False, max_length=300)
9 |
10 | class_uri = neonion.LINKED_PROPERTY
11 |
12 | class Meta:
13 | app_label = "annotationsets"
14 |
15 |
16 | class Property(ResourceMixin, models.Model):
17 | range = models.ManyToManyField("Concept", blank=True)
18 | # inverse property is the property to the inverse direction
19 | inverse_property = models.ForeignKey('self', blank=True, null=True, on_delete=models.SET_NULL)
20 | # list of linked properties
21 | linked_properties = models.ManyToManyField("LinkedProperty", blank=True)
22 |
23 | class_uri = neonion.PROPERTY
24 |
25 | class Meta:
26 | app_label = "annotationsets"
27 |
28 |
29 |
30 | class LinkedConcept(ResourceMixin, models.Model):
31 | endpoint = models.URLField('endpoint', null=True, blank=True, max_length=300)
32 | # URI to the concept in then external ontology
33 | linked_type = models.URLField('linked_type', blank=False, max_length=300)
34 | # path to the class which implements the knowledge extraction provider
35 | provider_class = models.CharField('provider_class', null=True, blank=True, max_length=100)
36 | custom_query = models.CharField(null=True, blank=True, max_length=500)
37 | retrieved_at = models.DateTimeField(null=True, blank=True)
38 |
39 | class_uri = neonion.LINKED_CONCEPT
40 |
41 | class Meta:
42 | app_label = "annotationsets"
43 |
44 |
45 |
46 | class Concept(ResourceMixin, models.Model):
47 | # list of resource provider to external knowledge
48 | linked_concepts = models.ManyToManyField("LinkedConcept", blank=True)
49 | properties = models.ManyToManyField("Property", blank=True)
50 |
51 | class_uri = neonion.CONCEPT
52 |
53 | class Meta:
54 | app_label = "annotationsets"
55 |
56 |
57 |
58 | class ConceptSet(ResourceMixin, models.Model):
59 | # list of concepts associated with set
60 | concepts = models.ManyToManyField("Concept", blank=True)
61 |
62 | class_uri = neonion.CONCEPT_SET
63 |
64 | class Meta:
65 | app_label = "annotationsets"
66 |
67 |
68 |
--------------------------------------------------------------------------------
/annotationsets/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from models import ConceptSet, LinkedConcept, Concept
3 |
4 |
5 | class AnnotationSetsTestCase(TestCase):
6 |
7 | def setUp(self):
8 | test_set = {
9 | 'uri': 'http://neonion.org/',
10 | 'label': 'Test Document',
11 | }
12 | self.annotation_set = ConceptSet.objects.create(**test_set)
--------------------------------------------------------------------------------
/api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/api/__init__.py
--------------------------------------------------------------------------------
/api/authentication.py:
--------------------------------------------------------------------------------
1 | from rest_framework.authentication import BaseAuthentication
2 |
3 |
4 | class UnsafeSessionAuthentication(BaseAuthentication):
5 | """
6 | Use Django's session framework for authentication.
7 | """
8 |
9 | def authenticate(self, request):
10 | """
11 | Returns a `User` if the request session currently has a logged in user.
12 | Otherwise returns `None`.
13 | """
14 |
15 | # Get the underlying HttpRequest object
16 | request = request._request
17 | user = getattr(request, 'user', None)
18 |
19 | # Unauthenticated, CSRF validation not required
20 | if not user or not user.is_active:
21 | return None
22 |
23 | return (user, None)
24 |
--------------------------------------------------------------------------------
/api/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from accounts.tests import create_test_user
3 | from documents.tests import create_test_document
4 |
5 |
6 | class DocumentAPITestCase(TestCase):
7 |
8 | def setUp(self):
9 | # create test user
10 | self.test_user = create_test_user()
11 |
12 | # create test document
13 | self.test_document = create_test_document()
14 |
15 | def test_get_documents(self):
16 | self.assertTrue(self.client.login(email='test@neonin.org', password='tester'))
17 | response = self.client.get('/api/documents')
18 | self.assertTrue(len(response.data) == 1)
19 |
20 | def test_get_document(self):
21 | self.assertTrue(self.client.login(email='test@neonin.org', password='tester'))
22 |
23 | response = self.client.get('/api/documents/' + self.test_document.id)
24 | self.assertDictContainsSubset({'id': self.test_document.id}, response.data)
25 |
26 |
27 | class UserAPITestCase(TestCase):
28 |
29 | def setUp(self):
30 | # create test user
31 | self.test_user = create_test_user()
32 |
33 | def test_current_user(self):
34 | self.assertTrue(self.client.login(email='test@neonin.org', password='tester'))
35 |
36 | response = self.client.get('/api/users/current')
37 | self.assertDictContainsSubset({'email': self.test_user.email}, response.data)
38 |
39 |
40 | class WorkingGroupAPITestCase(TestCase):
41 |
42 | def setUp(self):
43 | # create test user
44 | self.test_user = create_test_user()
--------------------------------------------------------------------------------
/api/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url, include
2 | from rest_framework import routers
3 | from viewsets import UserViewSet, WorkingGroupViewSet, DocumentViewSet, ConceptSetViewSet, ConceptViewSet, \
4 | PropertyViewSet, LinkedConceptViewSet, MembershipViewSet
5 |
6 | # Routers provide an easy way of automatically determining the URL conf.
7 | router = routers.DefaultRouter(trailing_slash=False)
8 | router.register(r'users', UserViewSet)
9 | router.register(r'memberships', MembershipViewSet)
10 | router.register(r'groups', WorkingGroupViewSet)
11 | router.register(r'documents', DocumentViewSet)
12 | router.register(r'conceptsets', ConceptSetViewSet)
13 | router.register(r'concepts', ConceptViewSet)
14 | router.register(r'linkedconcepts', LinkedConceptViewSet)
15 | router.register(r'properties', PropertyViewSet)
16 |
17 | urlpatterns = [
18 | url(r'^', include(router.urls)),
19 |
20 | # ElasticSearch proxy
21 | url(r'^es/search/(?P.+)/(?P.+)/(?P.+)$', 'api.views.entity_search'),
22 | url(r'^es/import/(?P.+)/(?P.+)$', 'api.views.entity_bulk_import'),
23 | ]
24 |
--------------------------------------------------------------------------------
/api/views.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | from django.conf import settings
4 | from django.contrib.auth.decorators import login_required
5 | from django.http import HttpResponse
6 | from django.http import JsonResponse
7 | from django.views.decorators.http import require_GET, require_POST
8 | from elasticsearch import Elasticsearch, TransportError, helpers
9 | from elasticsearch.helpers import BulkIndexError
10 |
11 | from common.knowledge.provider import Provider
12 |
13 |
14 | @login_required
15 | @require_POST
16 | def entity_bulk_import(request, index, type):
17 | json_data = ''
18 | # read chunks
19 | f = request.FILES.getlist('file')[0]
20 | for chunk in f.chunks():
21 | json_data += chunk
22 |
23 | data = json.loads(json_data)
24 |
25 | es = Elasticsearch(settings.ELASTICSEARCH_URL)
26 | try:
27 | es.indices.create(index)
28 | except TransportError:
29 | pass
30 |
31 | # clear item of type in document
32 | try:
33 | es.delete_by_query(index=index, doc_type=type, body='{"query":{"match_all":{}}}')
34 | except Exception:
35 | pass
36 |
37 | # https://gist.github.com/jayswan/a8d9920ef74516a02fe1
38 | # create generator
39 | def items():
40 | for item in data:
41 | item['_type'] = type
42 | item['_index'] = index
43 | yield item
44 |
45 | try:
46 | helpers.bulk(es, items())
47 | except BulkIndexError:
48 | pass
49 |
50 | # refresh the index
51 | es.indices.refresh(index=index)
52 |
53 | return HttpResponse(status=201)
54 |
55 |
56 | @login_required
57 | @require_GET
58 | def entity_search(request, index, type, term):
59 | # call search method from provider
60 | provider = Provider(settings.ELASTICSEARCH_URL)
61 | return JsonResponse(provider.search(term, type, index), safe=False)
62 |
--------------------------------------------------------------------------------
/common/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/common/__init__.py
--------------------------------------------------------------------------------
/common/exceptions.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class InvalidAnnotationError(Exception):
4 |
5 | def __init__(self, message, code=None, params=None):
6 | super(InvalidAnnotationError, self).__init__(message, code, params)
7 |
8 | def __str__(self):
9 | if hasattr(self, 'error_dict'):
10 | return repr(dict(self))
11 | return repr(list(self))
12 |
13 | def __repr__(self):
14 | return 'InvalidAnnotationError(%s)' % self
15 |
16 |
17 | class InvalidResourceTypeError(Exception):
18 |
19 | def __init__(self, value):
20 | self.value = value
21 |
22 | def __str__(self):
23 | return repr(self.value)
24 |
--------------------------------------------------------------------------------
/common/knowledge/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/common/knowledge/__init__.py
--------------------------------------------------------------------------------
/common/knowledge/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from provider import Provider
3 |
4 |
5 | class ProviderTestCase(TestCase):
6 |
7 | def setUp(self):
8 | pass
--------------------------------------------------------------------------------
/common/knowledge/wikidata/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/common/knowledge/wikidata/__init__.py
--------------------------------------------------------------------------------
/common/knowledge/wikidata/config.py:
--------------------------------------------------------------------------------
1 | WIKIDATA_DUMPS_URL = 'https://dumps.wikimedia.org/other/wikidata/{}'
2 | ELASTICSEARCH_URL = 'http://localhost:9200/'
3 | LANGUAGES = ['en','de']
--------------------------------------------------------------------------------
/common/mixins.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.conf import settings
3 |
4 |
5 | class ResourceMixin(models.Model):
6 | id = models.CharField('id', primary_key=True, max_length=50)
7 | label = models.CharField('label', max_length=100)
8 | comment = models.CharField('comment', blank=True, max_length=500)
9 |
10 | class Meta:
11 | abstract = True
12 |
13 | def uri(self):
14 | class_name = self.__class__.__name__.lower()
15 | return settings.NEONION_BASE_NAMESPACE.rstrip('/') + '/' + class_name + '/' + self.id
16 |
17 | def __str__(self):
18 | return self.label
19 |
--------------------------------------------------------------------------------
/common/sparql.py:
--------------------------------------------------------------------------------
1 | from SPARQLWrapper import SPARQLWrapper
2 | from django.conf import settings
3 |
4 |
5 | def prepare_sparql(format='json'):
6 | if hasattr(settings, 'ENDPOINT') and hasattr(settings, 'ENDPOINT_UPDATE'):
7 | sparql = SPARQLWrapper(settings.ENDPOINT, settings.ENDPOINT_UPDATE)
8 | sparql.method = 'GET'
9 | sparql.setReturnFormat(format)
10 | return sparql
11 | else:
12 | raise ValueError("Missing parameter for ENDPOINT")
13 |
14 |
15 | def insert_data(query):
16 | if query:
17 | sparql = prepare_sparql()
18 | sparql.method = 'POST'
19 | sparql.setQuery(query)
20 | return sparql.query()
21 |
22 |
23 | def execute_query(query, format='json'):
24 | if query:
25 | sparql = prepare_sparql(format)
26 | sparql.setQuery(query)
27 | return sparql.query().convert()
--------------------------------------------------------------------------------
/common/uri.py:
--------------------------------------------------------------------------------
1 | import uuid
2 |
3 | from django.conf import settings
4 | from django.core.validators import URLValidator
5 | from django.core.exceptions import ValidationError
6 | from common.exceptions import InvalidResourceTypeError
7 |
8 |
9 | def generate_uri(resource_type, name=None):
10 | validate = URLValidator()
11 | try:
12 | validate(resource_type)
13 |
14 | if name is None:
15 | # generate random uuid
16 | resource_id = uuid.uuid1().hex
17 | else:
18 | # generate uuid from provided name
19 | resource_id = uuid.uuid5(uuid.NAMESPACE_URL, name.lower().encode('utf8', 'replace')).hex
20 |
21 | concept_name = resource_type.rstrip('/').rsplit('/', 1)[1]
22 | return '{}/{}/{}'.format(
23 | settings.NEONION_BASE_NAMESPACE.rstrip('/'),
24 | concept_name,
25 | resource_id
26 | )
27 | except ValidationError:
28 | raise InvalidResourceTypeError(resource_type)
29 |
30 |
31 | def generate_urn(name=None):
32 | if name is None:
33 | # generate random uuid
34 | resource_uuid = uuid.uuid1().hex
35 | else:
36 | # generate uuid from provided name
37 | resource_uuid = uuid.uuid5(uuid.NAMESPACE_URL, name.lower().encode('utf8', 'replace')).hex
38 |
39 | return 'urn:uuid:{}'.format(resource_uuid)
40 |
--------------------------------------------------------------------------------
/common/vocab.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 | from enum import Enum
3 |
4 |
5 | class neonion:
6 | USER = settings.NEONION_BASE_NAMESPACE.rstrip('/') + '/ontology/user'
7 | ANNOTATION = settings.NEONION_BASE_NAMESPACE.rstrip('/') + '/ontology/annotation'
8 | CONCEPT_SET = settings.NEONION_BASE_NAMESPACE.rstrip('/') + '/ontology/conceptset'
9 | CONCEPT = settings.NEONION_BASE_NAMESPACE.rstrip('/') + '/ontology/concept'
10 | LINKED_CONCEPT = settings.NEONION_BASE_NAMESPACE.rstrip('/') + '/ontology/linkedconcept'
11 | PROPERTY = settings.NEONION_BASE_NAMESPACE.rstrip('/') + '/ontology/property'
12 | LINKED_PROPERTY = settings.NEONION_BASE_NAMESPACE.rstrip('/') + '/ontology/linkedproperty'
13 | DOCUMENT = settings.NEONION_BASE_NAMESPACE.rstrip('/') + '/ontology/document'
14 |
15 | ANNOTATION_STORE_GRAPH = settings.NEONION_BASE_NAMESPACE.rstrip('/') + '/annotationStore'
16 |
17 |
18 | class OpenAnnotation:
19 | PREFIX = 'oa:'
20 |
21 | class DocumentTypes(Enum):
22 | text = 'dctypes:Text'
23 |
24 | class TagTypes(Enum):
25 | tag = 'oa:Tag'
26 | semanticTag = 'oa:SemanticTag'
27 |
28 | class Motivations(Enum):
29 | commenting = 'oa:commenting'
30 | highlighting = 'oa:highlighting'
31 | tagging = 'oa:tagging'
32 | classifying = 'oa:classifying'
33 | identifying = 'oa:identifying'
34 | linking = 'oa:linking'
35 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | web:
2 | build: .
3 | command: python manage.py runserver 0.0.0.0:8000
4 | links:
5 | - elasticsearch
6 | volumes:
7 | - ./data:/data
8 | ports:
9 | - "8000:8000"
10 |
11 | elasticsearch:
12 | image: elasticsearch
13 | ports:
14 | - "9200:9200"
--------------------------------------------------------------------------------
/documents/__init__.py:
--------------------------------------------------------------------------------
1 | import logging.signals
2 |
--------------------------------------------------------------------------------
/documents/logging/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/documents/logging/__init__.py
--------------------------------------------------------------------------------
/documents/logging/signals.py:
--------------------------------------------------------------------------------
1 | import os, sys
2 | import logging
3 | from documents.models import Document
4 | from django.dispatch import receiver
5 | from django.db.models.signals import post_save
6 | from django.conf import settings
7 |
8 |
9 | log = logging.getLogger(__name__)
10 |
11 |
12 | # Signal which ensures that metadata gets saved automatically after newly created document
13 | @receiver(post_save, sender=Document)
14 | def document_created(sender, instance, created, **kwargs):
15 | if settings.USER_LOGGING_ENABLED:
16 | if created:
17 | try:
18 | title = instance.title
19 | creator = instance.description
20 | log.info('document_created=_%s'%(title))
21 | except Exception as e:
22 | print(e.message)
23 |
24 | def log_document_metadata_request_error(error):
25 | #if settings.USER_LOGGING_ENABLED:
26 | log.error(error)
27 |
--------------------------------------------------------------------------------
/documents/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/documents/migrations/__init__.py
--------------------------------------------------------------------------------
/documents/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from models import Document
3 |
4 |
5 | def create_test_document(doc_id='12345'):
6 | test_document = {
7 | 'id': doc_id,
8 | 'title': 'Test Document',
9 | 'type': 'Article',
10 | 'creator': 'test@nutzer.com'
11 | }
12 | return Document.objects.create(**test_document)
13 |
14 |
15 | class DocumentsTestCase(TestCase):
16 |
17 | def setUp(self):
18 | self.test_document = create_test_document()
--------------------------------------------------------------------------------
/documents/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 |
3 | urlpatterns = [
4 | url(r'^upload$', 'documents.views.upload_file'),
5 | url(r'^(?P.+)/modify$', 'documents.views.modify_document'),
6 | url(r'^search_metadata/(?P.+)$', 'documents.views.search_metadata'),
7 | url(r'^viewer/(?P.+)$', 'documents.views.viewer'),
8 | ]
9 |
--------------------------------------------------------------------------------
/elasticsearch/wikidata/person.json.bz2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/elasticsearch/wikidata/person.json.bz2
--------------------------------------------------------------------------------
/endpoint/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/endpoint/__init__.py
--------------------------------------------------------------------------------
/endpoint/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/endpoint/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 |
3 | urlpatterns = [
4 | url(r'^query$', 'endpoint.views.query'),
5 | ]
--------------------------------------------------------------------------------
/endpoint/views.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.decorators import login_required
2 | from django.views.decorators.http import require_http_methods
3 | from common.sparql import execute_query
4 | from django.http import HttpResponseForbidden, JsonResponse
5 |
6 |
7 | @login_required
8 | @require_http_methods(["GET", "POST"])
9 | def query(request):
10 | sparql_query = ''
11 | sparql_output = 'json'
12 |
13 | if request.method == 'POST':
14 | sparql_query = request.POST.get('query')
15 | sparql_output = request.POST.get('output')
16 | elif request.method == 'GET':
17 | if 'query' in request.GET: sparql_query = request.GET['query']
18 | if 'output' in request.GET: sparql_output = request.GET['output']
19 |
20 | try:
21 | print(request.POST)
22 | # execute query
23 | return JsonResponse(execute_query(sparql_query, sparql_output))
24 | except Exception as e:
25 | return HttpResponseForbidden()
26 |
--------------------------------------------------------------------------------
/fixtures/accounts.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "fields": {
4 | "comment": "",
5 | "owner": 1,
6 | "documents": [
7 | "4e41bee6c28111e4b236c42c0303b893",
8 | "688cea47c27f11e494e4c42c0303b893",
9 | "ba07e20ac28311e4a5bec42c0303b893",
10 | "ac93538cc28a11e4b948c42c0303b893"
11 | ],
12 | "name": "Public"
13 | },
14 | "model": "accounts.workinggroup",
15 | "pk": 1
16 | },
17 | {
18 | "fields": {
19 | "surname": "",
20 | "name": "",
21 | "is_active": true,
22 | "joined": "2014-12-22T14:12:01.868Z",
23 | "last_login": "2014-12-22T14:12:01.743Z",
24 | "is_superuser": false,
25 | "password": "pbkdf2_sha256$12000$ETvI760YU3He$C76eiXw2X8p8OibaZUkXNmKFa0z23MedwveNZC6xivA=",
26 | "email": "neonion-test@fu-berlin.de",
27 | "username": "neonion-test@fu-berlin.de"
28 | },
29 | "model": "accounts.user",
30 | "pk": 1
31 | },
32 | {
33 | "fields": {
34 | "surname": "",
35 | "name": "",
36 | "is_active": true,
37 | "joined": "2014-12-22T14:12:17.516Z",
38 | "last_login": "2014-12-22T14:12:17.402Z",
39 | "is_superuser": true,
40 | "password": "pbkdf2_sha256$12000$TG8p0bASUBWu$0VvZ5qoawys5kyFogTxRDy4pn33Vv4V/Xot//X9MraU=",
41 | "email": "neonion-admin@fu-berlin.de",
42 | "username": "neonion-admin@fu-berlin.de",
43 | "owned_documents": [
44 | "ac93538cc28a11e4b948c42c0303b893"
45 | ]
46 | },
47 | "model": "accounts.user",
48 | "pk": 2
49 | }
50 | ]
51 |
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 |
7 | # set production environment
8 | #os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.production")
9 |
10 | # set development environment
11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.development")
12 |
13 | # set test environment
14 | #os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.test")
15 |
16 | from django.core.management import execute_from_command_line
17 |
18 | execute_from_command_line(sys.argv)
19 |
--------------------------------------------------------------------------------
/neonion/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/__init__.py
--------------------------------------------------------------------------------
/neonion/processors.py:
--------------------------------------------------------------------------------
1 | def system_settings(request):
2 | from django.conf import settings
3 |
4 | return {
5 | 'system': {
6 | 'services': {
7 | 'user_logging': {
8 | 'kibana_url': settings.KIBANA_URL,
9 | 'enabled': settings.USER_LOGGING_ENABLED,
10 | },
11 | 'endpoint': {
12 | 'enabled': settings.ENDPOINT_ENABLED,
13 | }
14 | },
15 | 'annotator': {
16 | 'services': {
17 | 'stanford_ner': {
18 | 'enabled': settings.NER_SERVICE_ENABLED,
19 | 'service_url': settings.NER_SERVICE_URL,
20 | }
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/bootstrap/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/neonion/static/bootstrap/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/bootstrap/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/neonion/static/bootstrap/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/bootstrap/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/neonion/static/bootstrap/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/bootstrap/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/neonion/static/bootstrap/js/.jscsrc:
--------------------------------------------------------------------------------
1 | {
2 | "disallowEmptyBlocks": true,
3 | "disallowKeywords": ["with"],
4 | "disallowMixedSpacesAndTabs": true,
5 | "disallowMultipleLineStrings": true,
6 | "disallowMultipleVarDecl": true,
7 | "disallowQuotedKeysInObjects": "allButReserved",
8 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
9 | "disallowSpaceBeforeBinaryOperators": [","],
10 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
11 | "disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true },
12 | "disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true },
13 | "disallowSpacesInsideArrayBrackets": true,
14 | "disallowSpacesInsideParentheses": true,
15 | "disallowTrailingComma": true,
16 | "disallowTrailingWhitespace": true,
17 | "requireCamelCaseOrUpperCaseIdentifiers": true,
18 | "requireCapitalizedConstructors": true,
19 | "requireCommaBeforeLineBreak": true,
20 | "requireDollarBeforejQueryAssignment": true,
21 | "requireDotNotation": true,
22 | "requireLineFeedAtFileEnd": true,
23 | "requirePaddingNewLinesAfterUseStrict": true,
24 | "requirePaddingNewLinesBeforeExport": true,
25 | "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="],
26 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
27 | "requireSpaceAfterLineComment": true,
28 | "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="],
29 | "requireSpaceBetweenArguments": true,
30 | "requireSpacesInAnonymousFunctionExpression": { "beforeOpeningCurlyBrace": true, "beforeOpeningRoundBrace": true },
31 | "requireSpacesInConditionalExpression": true,
32 | "requireSpacesInForStatement": true,
33 | "requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true },
34 | "requireSpacesInFunctionExpression": { "beforeOpeningCurlyBrace": true },
35 | "requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true },
36 | "requireSpacesInsideObjectBrackets": "allButNested",
37 | "validateAlignedFunctionParameters": true,
38 | "validateIndentation": 2,
39 | "validateLineBreaks": "LF",
40 | "validateNewlineAfterArrayElements": true,
41 | "validateQuoteMarks": "'"
42 | }
43 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/js/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "asi" : true,
3 | "browser" : true,
4 | "eqeqeq" : false,
5 | "eqnull" : true,
6 | "es3" : true,
7 | "expr" : true,
8 | "jquery" : true,
9 | "latedef" : true,
10 | "laxbreak" : true,
11 | "nonbsp" : true,
12 | "strict" : true,
13 | "undef" : true,
14 | "unused" : true
15 | }
16 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/js/alert.js:
--------------------------------------------------------------------------------
1 | /* ========================================================================
2 | * Bootstrap: alert.js v3.3.5
3 | * http://getbootstrap.com/javascript/#alerts
4 | * ========================================================================
5 | * Copyright 2011-2015 Twitter, Inc.
6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7 | * ======================================================================== */
8 |
9 |
10 | +function ($) {
11 | 'use strict';
12 |
13 | // ALERT CLASS DEFINITION
14 | // ======================
15 |
16 | var dismiss = '[data-dismiss="alert"]'
17 | var Alert = function (el) {
18 | $(el).on('click', dismiss, this.close)
19 | }
20 |
21 | Alert.VERSION = '3.3.5'
22 |
23 | Alert.TRANSITION_DURATION = 150
24 |
25 | Alert.prototype.close = function (e) {
26 | var $this = $(this)
27 | var selector = $this.attr('data-target')
28 |
29 | if (!selector) {
30 | selector = $this.attr('href')
31 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
32 | }
33 |
34 | var $parent = $(selector)
35 |
36 | if (e) e.preventDefault()
37 |
38 | if (!$parent.length) {
39 | $parent = $this.closest('.alert')
40 | }
41 |
42 | $parent.trigger(e = $.Event('close.bs.alert'))
43 |
44 | if (e.isDefaultPrevented()) return
45 |
46 | $parent.removeClass('in')
47 |
48 | function removeElement() {
49 | // detach from parent, fire event then clean up data
50 | $parent.detach().trigger('closed.bs.alert').remove()
51 | }
52 |
53 | $.support.transition && $parent.hasClass('fade') ?
54 | $parent
55 | .one('bsTransitionEnd', removeElement)
56 | .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
57 | removeElement()
58 | }
59 |
60 |
61 | // ALERT PLUGIN DEFINITION
62 | // =======================
63 |
64 | function Plugin(option) {
65 | return this.each(function () {
66 | var $this = $(this)
67 | var data = $this.data('bs.alert')
68 |
69 | if (!data) $this.data('bs.alert', (data = new Alert(this)))
70 | if (typeof option == 'string') data[option].call($this)
71 | })
72 | }
73 |
74 | var old = $.fn.alert
75 |
76 | $.fn.alert = Plugin
77 | $.fn.alert.Constructor = Alert
78 |
79 |
80 | // ALERT NO CONFLICT
81 | // =================
82 |
83 | $.fn.alert.noConflict = function () {
84 | $.fn.alert = old
85 | return this
86 | }
87 |
88 |
89 | // ALERT DATA-API
90 | // ==============
91 |
92 | $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
93 |
94 | }(jQuery);
95 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/js/tests/unit/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends" : "../../.jshintrc",
3 | "devel" : true,
4 | "es3" : false,
5 | "qunit" : true
6 | }
7 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/js/tests/unit/phantom.js:
--------------------------------------------------------------------------------
1 | /*
2 | * grunt-contrib-qunit
3 | * http://gruntjs.com/
4 | *
5 | * Copyright (c) 2014 "Cowboy" Ben Alman, contributors
6 | * Licensed under the MIT license.
7 | */
8 |
9 | (function () {
10 | 'use strict';
11 |
12 | // Don't re-order tests.
13 | QUnit.config.reorder = false
14 | // Run tests serially, not in parallel.
15 | QUnit.config.autorun = false
16 |
17 | // Send messages to the parent PhantomJS process via alert! Good times!!
18 | function sendMessage() {
19 | var args = [].slice.call(arguments)
20 | alert(JSON.stringify(args))
21 | }
22 |
23 | // These methods connect QUnit to PhantomJS.
24 | QUnit.log(function (obj) {
25 | // What is this I don’t even
26 | if (obj.message === '[object Object], undefined:undefined') { return }
27 |
28 | // Parse some stuff before sending it.
29 | var actual
30 | var expected
31 | if (!obj.result) {
32 | // Dumping large objects can be very slow, and the dump isn't used for
33 | // passing tests, so only dump if the test failed.
34 | actual = QUnit.dump.parse(obj.actual)
35 | expected = QUnit.dump.parse(obj.expected)
36 | }
37 | // Send it.
38 | sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source)
39 | })
40 |
41 | QUnit.testStart(function (obj) {
42 | sendMessage('qunit.testStart', obj.name)
43 | })
44 |
45 | QUnit.testDone(function (obj) {
46 | sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total, obj.duration)
47 | })
48 |
49 | QUnit.moduleStart(function (obj) {
50 | sendMessage('qunit.moduleStart', obj.name)
51 | })
52 |
53 | QUnit.moduleDone(function (obj) {
54 | if (obj.failed === 0) {
55 | console.log('\r\u221A All tests passed in "' + obj.name + '" module')
56 | } else {
57 | console.log('\u00D7 ' + obj.failed + ' tests failed in "' + obj.name + '" module')
58 | }
59 | sendMessage('qunit.moduleDone', obj.name, obj.failed, obj.passed, obj.total)
60 | })
61 |
62 | QUnit.begin(function () {
63 | sendMessage('qunit.begin')
64 | console.log('\n\nStarting test suite')
65 | console.log('================================================\n')
66 | })
67 |
68 | QUnit.done(function (obj) {
69 | sendMessage('qunit.done', obj.failed, obj.passed, obj.total, obj.runtime)
70 | })
71 |
72 | }())
73 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/js/tests/visual/alert.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Alert
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 | ×
27 | Holy guacamole! Best check yo self, you're not looking too good.
28 |
29 |
30 |
31 |
×
32 |
Oh snap! You got an error!
33 |
Change this and that and try again. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum.
34 |
35 | Take this action
36 | Or do this
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/js/tests/visual/button.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Button
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/js/tests/visual/carousel.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Carousel
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/js/tests/visual/popover.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Popover
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 | Popover on left
27 |
28 |
29 | Popover on top
30 |
31 |
32 | Popover on bottom
33 |
34 |
35 | Popover on right
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/js/transition.js:
--------------------------------------------------------------------------------
1 | /* ========================================================================
2 | * Bootstrap: transition.js v3.3.5
3 | * http://getbootstrap.com/javascript/#transitions
4 | * ========================================================================
5 | * Copyright 2011-2015 Twitter, Inc.
6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7 | * ======================================================================== */
8 |
9 |
10 | +function ($) {
11 | 'use strict';
12 |
13 | // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
14 | // ============================================================
15 |
16 | function transitionEnd() {
17 | var el = document.createElement('bootstrap')
18 |
19 | var transEndEventNames = {
20 | WebkitTransition : 'webkitTransitionEnd',
21 | MozTransition : 'transitionend',
22 | OTransition : 'oTransitionEnd otransitionend',
23 | transition : 'transitionend'
24 | }
25 |
26 | for (var name in transEndEventNames) {
27 | if (el.style[name] !== undefined) {
28 | return { end: transEndEventNames[name] }
29 | }
30 | }
31 |
32 | return false // explicit for ie8 ( ._.)
33 | }
34 |
35 | // http://blog.alexmaccaw.com/css-transitions
36 | $.fn.emulateTransitionEnd = function (duration) {
37 | var called = false
38 | var $el = this
39 | $(this).one('bsTransitionEnd', function () { called = true })
40 | var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
41 | setTimeout(callback, duration)
42 | return this
43 | }
44 |
45 | $(function () {
46 | $.support.transition = transitionEnd()
47 |
48 | if (!$.support.transition) return
49 |
50 | $.event.special.bsTransitionEnd = {
51 | bindType: $.support.transition.end,
52 | delegateType: $.support.transition.end,
53 | handle: function (e) {
54 | if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
55 | }
56 | }
57 | })
58 |
59 | }(jQuery);
60 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/.csslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "adjoining-classes": false,
3 | "box-sizing": false,
4 | "box-model": false,
5 | "compatible-vendor-prefixes": false,
6 | "floats": false,
7 | "font-sizes": false,
8 | "gradients": false,
9 | "important": false,
10 | "known-properties": false,
11 | "outline-none": false,
12 | "qualified-headings": false,
13 | "regex-selectors": false,
14 | "shorthand": false,
15 | "text-indent": false,
16 | "unique-headings": false,
17 | "universal-selector": false,
18 | "unqualified-attributes": false
19 | }
20 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/alerts.less:
--------------------------------------------------------------------------------
1 | //
2 | // Alerts
3 | // --------------------------------------------------
4 |
5 |
6 | // Base styles
7 | // -------------------------
8 |
9 | .alert {
10 | padding: @alert-padding;
11 | margin-bottom: @line-height-computed;
12 | border: 1px solid transparent;
13 | border-radius: @alert-border-radius;
14 |
15 | // Headings for larger alerts
16 | h4 {
17 | margin-top: 0;
18 | // Specified for the h4 to prevent conflicts of changing @headings-color
19 | color: inherit;
20 | }
21 |
22 | // Provide class for links that match alerts
23 | .alert-link {
24 | font-weight: @alert-link-font-weight;
25 | }
26 |
27 | // Improve alignment and spacing of inner content
28 | > p,
29 | > ul {
30 | margin-bottom: 0;
31 | }
32 |
33 | > p + p {
34 | margin-top: 5px;
35 | }
36 | }
37 |
38 | // Dismissible alerts
39 | //
40 | // Expand the right padding and account for the close button's positioning.
41 |
42 | .alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.
43 | .alert-dismissible {
44 | padding-right: (@alert-padding + 20);
45 |
46 | // Adjust close link position
47 | .close {
48 | position: relative;
49 | top: -2px;
50 | right: -21px;
51 | color: inherit;
52 | }
53 | }
54 |
55 | // Alternate styles
56 | //
57 | // Generate contextual modifier classes for colorizing the alert.
58 |
59 | .alert-success {
60 | .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);
61 | }
62 |
63 | .alert-info {
64 | .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);
65 | }
66 |
67 | .alert-warning {
68 | .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);
69 | }
70 |
71 | .alert-danger {
72 | .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);
73 | }
74 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/badges.less:
--------------------------------------------------------------------------------
1 | //
2 | // Badges
3 | // --------------------------------------------------
4 |
5 |
6 | // Base class
7 | .badge {
8 | display: inline-block;
9 | min-width: 10px;
10 | padding: 3px 7px;
11 | font-size: @font-size-small;
12 | font-weight: @badge-font-weight;
13 | color: @badge-color;
14 | line-height: @badge-line-height;
15 | vertical-align: middle;
16 | white-space: nowrap;
17 | text-align: center;
18 | background-color: @badge-bg;
19 | border-radius: @badge-border-radius;
20 |
21 | // Empty badges collapse automatically (not available in IE8)
22 | &:empty {
23 | display: none;
24 | }
25 |
26 | // Quick fix for badges in buttons
27 | .btn & {
28 | position: relative;
29 | top: -1px;
30 | }
31 |
32 | .btn-xs &,
33 | .btn-group-xs > .btn & {
34 | top: 0;
35 | padding: 1px 5px;
36 | }
37 |
38 | // Hover state, but only for links
39 | a& {
40 | &:hover,
41 | &:focus {
42 | color: @badge-link-hover-color;
43 | text-decoration: none;
44 | cursor: pointer;
45 | }
46 | }
47 |
48 | // Account for badges in navs
49 | .list-group-item.active > &,
50 | .nav-pills > .active > a > & {
51 | color: @badge-active-color;
52 | background-color: @badge-active-bg;
53 | }
54 |
55 | .list-group-item > & {
56 | float: right;
57 | }
58 |
59 | .list-group-item > & + & {
60 | margin-right: 5px;
61 | }
62 |
63 | .nav-pills > li > a > & {
64 | margin-left: 3px;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/bootstrap.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v3.3.5 (http://getbootstrap.com)
3 | * Copyright 2011-2015 Twitter, Inc.
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 | */
6 |
7 | // Core variables and mixins
8 | @import "variables.less";
9 | @import "mixins.less";
10 |
11 | // Reset and dependencies
12 | @import "normalize.less";
13 | @import "print.less";
14 | @import "glyphicons.less";
15 |
16 | // Core CSS
17 | @import "scaffolding.less";
18 | @import "type.less";
19 | @import "code.less";
20 | @import "grid.less";
21 | @import "tables.less";
22 | @import "forms.less";
23 | @import "buttons.less";
24 |
25 | // Components
26 | @import "component-animations.less";
27 | @import "dropdowns.less";
28 | @import "button-groups.less";
29 | @import "input-groups.less";
30 | @import "navs.less";
31 | @import "navbar.less";
32 | @import "breadcrumbs.less";
33 | @import "pagination.less";
34 | @import "pager.less";
35 | @import "labels.less";
36 | @import "badges.less";
37 | @import "jumbotron.less";
38 | @import "thumbnails.less";
39 | @import "alerts.less";
40 | @import "progress-bars.less";
41 | @import "media.less";
42 | @import "list-group.less";
43 | @import "panels.less";
44 | @import "responsive-embed.less";
45 | @import "wells.less";
46 | @import "close.less";
47 |
48 | // Components w/ JavaScript
49 | @import "modals.less";
50 | @import "tooltip.less";
51 | @import "popovers.less";
52 | @import "carousel.less";
53 |
54 | // Utility classes
55 | @import "utilities.less";
56 | @import "responsive-utilities.less";
57 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/breadcrumbs.less:
--------------------------------------------------------------------------------
1 | //
2 | // Breadcrumbs
3 | // --------------------------------------------------
4 |
5 |
6 | .breadcrumb {
7 | padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;
8 | margin-bottom: @line-height-computed;
9 | list-style: none;
10 | background-color: @breadcrumb-bg;
11 | border-radius: @border-radius-base;
12 |
13 | > li {
14 | display: inline-block;
15 |
16 | + li:before {
17 | content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space
18 | padding: 0 5px;
19 | color: @breadcrumb-color;
20 | }
21 | }
22 |
23 | > .active {
24 | color: @breadcrumb-active-color;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/close.less:
--------------------------------------------------------------------------------
1 | //
2 | // Close icons
3 | // --------------------------------------------------
4 |
5 |
6 | .close {
7 | float: right;
8 | font-size: (@font-size-base * 1.5);
9 | font-weight: @close-font-weight;
10 | line-height: 1;
11 | color: @close-color;
12 | text-shadow: @close-text-shadow;
13 | .opacity(.2);
14 |
15 | &:hover,
16 | &:focus {
17 | color: @close-color;
18 | text-decoration: none;
19 | cursor: pointer;
20 | .opacity(.5);
21 | }
22 |
23 | // Additional properties for button version
24 | // iOS requires the button element instead of an anchor tag.
25 | // If you want the anchor version, it requires `href="#"`.
26 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
27 | button& {
28 | padding: 0;
29 | cursor: pointer;
30 | background: transparent;
31 | border: 0;
32 | -webkit-appearance: none;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/code.less:
--------------------------------------------------------------------------------
1 | //
2 | // Code (inline and block)
3 | // --------------------------------------------------
4 |
5 |
6 | // Inline and block code styles
7 | code,
8 | kbd,
9 | pre,
10 | samp {
11 | font-family: @font-family-monospace;
12 | }
13 |
14 | // Inline code
15 | code {
16 | padding: 2px 4px;
17 | font-size: 90%;
18 | color: @code-color;
19 | background-color: @code-bg;
20 | border-radius: @border-radius-base;
21 | }
22 |
23 | // User input typically entered via keyboard
24 | kbd {
25 | padding: 2px 4px;
26 | font-size: 90%;
27 | color: @kbd-color;
28 | background-color: @kbd-bg;
29 | border-radius: @border-radius-small;
30 | box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);
31 |
32 | kbd {
33 | padding: 0;
34 | font-size: 100%;
35 | font-weight: bold;
36 | box-shadow: none;
37 | }
38 | }
39 |
40 | // Blocks of code
41 | pre {
42 | display: block;
43 | padding: ((@line-height-computed - 1) / 2);
44 | margin: 0 0 (@line-height-computed / 2);
45 | font-size: (@font-size-base - 1); // 14px to 13px
46 | line-height: @line-height-base;
47 | word-break: break-all;
48 | word-wrap: break-word;
49 | color: @pre-color;
50 | background-color: @pre-bg;
51 | border: 1px solid @pre-border-color;
52 | border-radius: @border-radius-base;
53 |
54 | // Account for some code outputs that place code tags in pre tags
55 | code {
56 | padding: 0;
57 | font-size: inherit;
58 | color: inherit;
59 | white-space: pre-wrap;
60 | background-color: transparent;
61 | border-radius: 0;
62 | }
63 | }
64 |
65 | // Enable scrollable blocks of code
66 | .pre-scrollable {
67 | max-height: @pre-scrollable-max-height;
68 | overflow-y: scroll;
69 | }
70 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/component-animations.less:
--------------------------------------------------------------------------------
1 | //
2 | // Component animations
3 | // --------------------------------------------------
4 |
5 | // Heads up!
6 | //
7 | // We don't use the `.opacity()` mixin here since it causes a bug with text
8 | // fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.
9 |
10 | .fade {
11 | opacity: 0;
12 | .transition(opacity .15s linear);
13 | &.in {
14 | opacity: 1;
15 | }
16 | }
17 |
18 | .collapse {
19 | display: none;
20 |
21 | &.in { display: block; }
22 | tr&.in { display: table-row; }
23 | tbody&.in { display: table-row-group; }
24 | }
25 |
26 | .collapsing {
27 | position: relative;
28 | height: 0;
29 | overflow: hidden;
30 | .transition-property(~"height, visibility");
31 | .transition-duration(.35s);
32 | .transition-timing-function(ease);
33 | }
34 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/grid.less:
--------------------------------------------------------------------------------
1 | //
2 | // Grid system
3 | // --------------------------------------------------
4 |
5 |
6 | // Container widths
7 | //
8 | // Set the container width, and override it for fixed navbars in media queries.
9 |
10 | .container {
11 | .container-fixed();
12 |
13 | @media (min-width: @screen-sm-min) {
14 | width: @container-sm;
15 | }
16 | @media (min-width: @screen-md-min) {
17 | width: @container-md;
18 | }
19 | @media (min-width: @screen-lg-min) {
20 | width: @container-lg;
21 | }
22 | }
23 |
24 |
25 | // Fluid container
26 | //
27 | // Utilizes the mixin meant for fixed width containers, but without any defined
28 | // width for fluid, full width layouts.
29 |
30 | .container-fluid {
31 | .container-fixed();
32 | }
33 |
34 |
35 | // Row
36 | //
37 | // Rows contain and clear the floats of your columns.
38 |
39 | .row {
40 | .make-row();
41 | }
42 |
43 |
44 | // Columns
45 | //
46 | // Common styles for small and large grid columns
47 |
48 | .make-grid-columns();
49 |
50 |
51 | // Extra small grid
52 | //
53 | // Columns, offsets, pushes, and pulls for extra small devices like
54 | // smartphones.
55 |
56 | .make-grid(xs);
57 |
58 |
59 | // Small grid
60 | //
61 | // Columns, offsets, pushes, and pulls for the small device range, from phones
62 | // to tablets.
63 |
64 | @media (min-width: @screen-sm-min) {
65 | .make-grid(sm);
66 | }
67 |
68 |
69 | // Medium grid
70 | //
71 | // Columns, offsets, pushes, and pulls for the desktop device range.
72 |
73 | @media (min-width: @screen-md-min) {
74 | .make-grid(md);
75 | }
76 |
77 |
78 | // Large grid
79 | //
80 | // Columns, offsets, pushes, and pulls for the large desktop device range.
81 |
82 | @media (min-width: @screen-lg-min) {
83 | .make-grid(lg);
84 | }
85 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/jumbotron.less:
--------------------------------------------------------------------------------
1 | //
2 | // Jumbotron
3 | // --------------------------------------------------
4 |
5 |
6 | .jumbotron {
7 | padding-top: @jumbotron-padding;
8 | padding-bottom: @jumbotron-padding;
9 | margin-bottom: @jumbotron-padding;
10 | color: @jumbotron-color;
11 | background-color: @jumbotron-bg;
12 |
13 | h1,
14 | .h1 {
15 | color: @jumbotron-heading-color;
16 | }
17 |
18 | p {
19 | margin-bottom: (@jumbotron-padding / 2);
20 | font-size: @jumbotron-font-size;
21 | font-weight: 200;
22 | }
23 |
24 | > hr {
25 | border-top-color: darken(@jumbotron-bg, 10%);
26 | }
27 |
28 | .container &,
29 | .container-fluid & {
30 | border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container
31 | padding-left: (@grid-gutter-width / 2);
32 | padding-right: (@grid-gutter-width / 2);
33 | }
34 |
35 | .container {
36 | max-width: 100%;
37 | }
38 |
39 | @media screen and (min-width: @screen-sm-min) {
40 | padding-top: (@jumbotron-padding * 1.6);
41 | padding-bottom: (@jumbotron-padding * 1.6);
42 |
43 | .container &,
44 | .container-fluid & {
45 | padding-left: (@jumbotron-padding * 2);
46 | padding-right: (@jumbotron-padding * 2);
47 | }
48 |
49 | h1,
50 | .h1 {
51 | font-size: @jumbotron-heading-font-size;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/labels.less:
--------------------------------------------------------------------------------
1 | //
2 | // Labels
3 | // --------------------------------------------------
4 |
5 | .label {
6 | display: inline;
7 | padding: .2em .6em .3em;
8 | font-size: 75%;
9 | font-weight: bold;
10 | line-height: 1;
11 | color: @label-color;
12 | text-align: center;
13 | white-space: nowrap;
14 | vertical-align: baseline;
15 | border-radius: .25em;
16 |
17 | // Add hover effects, but only for links
18 | a& {
19 | &:hover,
20 | &:focus {
21 | color: @label-link-hover-color;
22 | text-decoration: none;
23 | cursor: pointer;
24 | }
25 | }
26 |
27 | // Empty labels collapse automatically (not available in IE8)
28 | &:empty {
29 | display: none;
30 | }
31 |
32 | // Quick fix for labels in buttons
33 | .btn & {
34 | position: relative;
35 | top: -1px;
36 | }
37 | }
38 |
39 | // Colors
40 | // Contextual variations (linked labels get darker on :hover)
41 |
42 | .label-default {
43 | .label-variant(@label-default-bg);
44 | }
45 |
46 | .label-primary {
47 | .label-variant(@label-primary-bg);
48 | }
49 |
50 | .label-success {
51 | .label-variant(@label-success-bg);
52 | }
53 |
54 | .label-info {
55 | .label-variant(@label-info-bg);
56 | }
57 |
58 | .label-warning {
59 | .label-variant(@label-warning-bg);
60 | }
61 |
62 | .label-danger {
63 | .label-variant(@label-danger-bg);
64 | }
65 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/media.less:
--------------------------------------------------------------------------------
1 | .media {
2 | // Proper spacing between instances of .media
3 | margin-top: 15px;
4 |
5 | &:first-child {
6 | margin-top: 0;
7 | }
8 | }
9 |
10 | .media,
11 | .media-body {
12 | zoom: 1;
13 | overflow: hidden;
14 | }
15 |
16 | .media-body {
17 | width: 10000px;
18 | }
19 |
20 | .media-object {
21 | display: block;
22 |
23 | // Fix collapse in webkit from max-width: 100% and display: table-cell.
24 | &.img-thumbnail {
25 | max-width: none;
26 | }
27 | }
28 |
29 | .media-right,
30 | .media > .pull-right {
31 | padding-left: 10px;
32 | }
33 |
34 | .media-left,
35 | .media > .pull-left {
36 | padding-right: 10px;
37 | }
38 |
39 | .media-left,
40 | .media-right,
41 | .media-body {
42 | display: table-cell;
43 | vertical-align: top;
44 | }
45 |
46 | .media-middle {
47 | vertical-align: middle;
48 | }
49 |
50 | .media-bottom {
51 | vertical-align: bottom;
52 | }
53 |
54 | // Reset margins on headings for tighter default spacing
55 | .media-heading {
56 | margin-top: 0;
57 | margin-bottom: 5px;
58 | }
59 |
60 | // Media list variation
61 | //
62 | // Undo default ul/ol styles
63 | .media-list {
64 | padding-left: 0;
65 | list-style: none;
66 | }
67 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins.less:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------------------------------
3 |
4 | // Utilities
5 | @import "mixins/hide-text.less";
6 | @import "mixins/opacity.less";
7 | @import "mixins/image.less";
8 | @import "mixins/labels.less";
9 | @import "mixins/reset-filter.less";
10 | @import "mixins/resize.less";
11 | @import "mixins/responsive-visibility.less";
12 | @import "mixins/size.less";
13 | @import "mixins/tab-focus.less";
14 | @import "mixins/reset-text.less";
15 | @import "mixins/text-emphasis.less";
16 | @import "mixins/text-overflow.less";
17 | @import "mixins/vendor-prefixes.less";
18 |
19 | // Components
20 | @import "mixins/alerts.less";
21 | @import "mixins/buttons.less";
22 | @import "mixins/panels.less";
23 | @import "mixins/pagination.less";
24 | @import "mixins/list-group.less";
25 | @import "mixins/nav-divider.less";
26 | @import "mixins/forms.less";
27 | @import "mixins/progress-bar.less";
28 | @import "mixins/table-row.less";
29 |
30 | // Skins
31 | @import "mixins/background-variant.less";
32 | @import "mixins/border-radius.less";
33 | @import "mixins/gradients.less";
34 |
35 | // Layout
36 | @import "mixins/clearfix.less";
37 | @import "mixins/center-block.less";
38 | @import "mixins/nav-vertical-align.less";
39 | @import "mixins/grid-framework.less";
40 | @import "mixins/grid.less";
41 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/alerts.less:
--------------------------------------------------------------------------------
1 | // Alerts
2 |
3 | .alert-variant(@background; @border; @text-color) {
4 | background-color: @background;
5 | border-color: @border;
6 | color: @text-color;
7 |
8 | hr {
9 | border-top-color: darken(@border, 5%);
10 | }
11 | .alert-link {
12 | color: darken(@text-color, 10%);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/background-variant.less:
--------------------------------------------------------------------------------
1 | // Contextual backgrounds
2 |
3 | .bg-variant(@color) {
4 | background-color: @color;
5 | a&:hover,
6 | a&:focus {
7 | background-color: darken(@color, 10%);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/border-radius.less:
--------------------------------------------------------------------------------
1 | // Single side border-radius
2 |
3 | .border-top-radius(@radius) {
4 | border-top-right-radius: @radius;
5 | border-top-left-radius: @radius;
6 | }
7 | .border-right-radius(@radius) {
8 | border-bottom-right-radius: @radius;
9 | border-top-right-radius: @radius;
10 | }
11 | .border-bottom-radius(@radius) {
12 | border-bottom-right-radius: @radius;
13 | border-bottom-left-radius: @radius;
14 | }
15 | .border-left-radius(@radius) {
16 | border-bottom-left-radius: @radius;
17 | border-top-left-radius: @radius;
18 | }
19 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/buttons.less:
--------------------------------------------------------------------------------
1 | // Button variants
2 | //
3 | // Easily pump out default styles, as well as :hover, :focus, :active,
4 | // and disabled options for all buttons
5 |
6 | .button-variant(@color; @background; @border) {
7 | color: @color;
8 | background-color: @background;
9 | border-color: @border;
10 |
11 | &:focus,
12 | &.focus {
13 | color: @color;
14 | background-color: darken(@background, 10%);
15 | border-color: darken(@border, 25%);
16 | }
17 | &:hover {
18 | color: @color;
19 | background-color: darken(@background, 10%);
20 | border-color: darken(@border, 12%);
21 | }
22 | &:active,
23 | &.active,
24 | .open > .dropdown-toggle& {
25 | color: @color;
26 | background-color: darken(@background, 10%);
27 | border-color: darken(@border, 12%);
28 |
29 | &:hover,
30 | &:focus,
31 | &.focus {
32 | color: @color;
33 | background-color: darken(@background, 17%);
34 | border-color: darken(@border, 25%);
35 | }
36 | }
37 | &:active,
38 | &.active,
39 | .open > .dropdown-toggle& {
40 | background-image: none;
41 | }
42 | &.disabled,
43 | &[disabled],
44 | fieldset[disabled] & {
45 | &:hover,
46 | &:focus,
47 | &.focus {
48 | background-color: @background;
49 | border-color: @border;
50 | }
51 | }
52 |
53 | .badge {
54 | color: @background;
55 | background-color: @color;
56 | }
57 | }
58 |
59 | // Button sizes
60 | .button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
61 | padding: @padding-vertical @padding-horizontal;
62 | font-size: @font-size;
63 | line-height: @line-height;
64 | border-radius: @border-radius;
65 | }
66 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/center-block.less:
--------------------------------------------------------------------------------
1 | // Center-align a block level element
2 |
3 | .center-block() {
4 | display: block;
5 | margin-left: auto;
6 | margin-right: auto;
7 | }
8 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/clearfix.less:
--------------------------------------------------------------------------------
1 | // Clearfix
2 | //
3 | // For modern browsers
4 | // 1. The space content is one way to avoid an Opera bug when the
5 | // contenteditable attribute is included anywhere else in the document.
6 | // Otherwise it causes space to appear at the top and bottom of elements
7 | // that are clearfixed.
8 | // 2. The use of `table` rather than `block` is only necessary if using
9 | // `:before` to contain the top-margins of child elements.
10 | //
11 | // Source: http://nicolasgallagher.com/micro-clearfix-hack/
12 |
13 | .clearfix() {
14 | &:before,
15 | &:after {
16 | content: " "; // 1
17 | display: table; // 2
18 | }
19 | &:after {
20 | clear: both;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/hide-text.less:
--------------------------------------------------------------------------------
1 | // CSS image replacement
2 | //
3 | // Heads up! v3 launched with only `.hide-text()`, but per our pattern for
4 | // mixins being reused as classes with the same name, this doesn't hold up. As
5 | // of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.
6 | //
7 | // Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
8 |
9 | // Deprecated as of v3.0.1 (will be removed in v4)
10 | .hide-text() {
11 | font: ~"0/0" a;
12 | color: transparent;
13 | text-shadow: none;
14 | background-color: transparent;
15 | border: 0;
16 | }
17 |
18 | // New mixin to use as of v3.0.1
19 | .text-hide() {
20 | .hide-text();
21 | }
22 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/image.less:
--------------------------------------------------------------------------------
1 | // Image Mixins
2 | // - Responsive image
3 | // - Retina image
4 |
5 |
6 | // Responsive image
7 | //
8 | // Keep images from scaling beyond the width of their parents.
9 | .img-responsive(@display: block) {
10 | display: @display;
11 | max-width: 100%; // Part 1: Set a maximum relative to the parent
12 | height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
13 | }
14 |
15 |
16 | // Retina image
17 | //
18 | // Short retina mixin for setting background-image and -size. Note that the
19 | // spelling of `min--moz-device-pixel-ratio` is intentional.
20 | .img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {
21 | background-image: url("@{file-1x}");
22 |
23 | @media
24 | only screen and (-webkit-min-device-pixel-ratio: 2),
25 | only screen and ( min--moz-device-pixel-ratio: 2),
26 | only screen and ( -o-min-device-pixel-ratio: 2/1),
27 | only screen and ( min-device-pixel-ratio: 2),
28 | only screen and ( min-resolution: 192dpi),
29 | only screen and ( min-resolution: 2dppx) {
30 | background-image: url("@{file-2x}");
31 | background-size: @width-1x @height-1x;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/labels.less:
--------------------------------------------------------------------------------
1 | // Labels
2 |
3 | .label-variant(@color) {
4 | background-color: @color;
5 |
6 | &[href] {
7 | &:hover,
8 | &:focus {
9 | background-color: darken(@color, 10%);
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/list-group.less:
--------------------------------------------------------------------------------
1 | // List Groups
2 |
3 | .list-group-item-variant(@state; @background; @color) {
4 | .list-group-item-@{state} {
5 | color: @color;
6 | background-color: @background;
7 |
8 | a&,
9 | button& {
10 | color: @color;
11 |
12 | .list-group-item-heading {
13 | color: inherit;
14 | }
15 |
16 | &:hover,
17 | &:focus {
18 | color: @color;
19 | background-color: darken(@background, 5%);
20 | }
21 | &.active,
22 | &.active:hover,
23 | &.active:focus {
24 | color: #fff;
25 | background-color: @color;
26 | border-color: @color;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/nav-divider.less:
--------------------------------------------------------------------------------
1 | // Horizontal dividers
2 | //
3 | // Dividers (basically an hr) within dropdowns and nav lists
4 |
5 | .nav-divider(@color: #e5e5e5) {
6 | height: 1px;
7 | margin: ((@line-height-computed / 2) - 1) 0;
8 | overflow: hidden;
9 | background-color: @color;
10 | }
11 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/nav-vertical-align.less:
--------------------------------------------------------------------------------
1 | // Navbar vertical align
2 | //
3 | // Vertically center elements in the navbar.
4 | // Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
5 |
6 | .navbar-vertical-align(@element-height) {
7 | margin-top: ((@navbar-height - @element-height) / 2);
8 | margin-bottom: ((@navbar-height - @element-height) / 2);
9 | }
10 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/opacity.less:
--------------------------------------------------------------------------------
1 | // Opacity
2 |
3 | .opacity(@opacity) {
4 | opacity: @opacity;
5 | // IE8 filter
6 | @opacity-ie: (@opacity * 100);
7 | filter: ~"alpha(opacity=@{opacity-ie})";
8 | }
9 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/pagination.less:
--------------------------------------------------------------------------------
1 | // Pagination
2 |
3 | .pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
4 | > li {
5 | > a,
6 | > span {
7 | padding: @padding-vertical @padding-horizontal;
8 | font-size: @font-size;
9 | line-height: @line-height;
10 | }
11 | &:first-child {
12 | > a,
13 | > span {
14 | .border-left-radius(@border-radius);
15 | }
16 | }
17 | &:last-child {
18 | > a,
19 | > span {
20 | .border-right-radius(@border-radius);
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/panels.less:
--------------------------------------------------------------------------------
1 | // Panels
2 |
3 | .panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {
4 | border-color: @border;
5 |
6 | & > .panel-heading {
7 | color: @heading-text-color;
8 | background-color: @heading-bg-color;
9 | border-color: @heading-border;
10 |
11 | + .panel-collapse > .panel-body {
12 | border-top-color: @border;
13 | }
14 | .badge {
15 | color: @heading-bg-color;
16 | background-color: @heading-text-color;
17 | }
18 | }
19 | & > .panel-footer {
20 | + .panel-collapse > .panel-body {
21 | border-bottom-color: @border;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/progress-bar.less:
--------------------------------------------------------------------------------
1 | // Progress bars
2 |
3 | .progress-bar-variant(@color) {
4 | background-color: @color;
5 |
6 | // Deprecated parent class requirement as of v3.2.0
7 | .progress-striped & {
8 | #gradient > .striped();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/reset-filter.less:
--------------------------------------------------------------------------------
1 | // Reset filters for IE
2 | //
3 | // When you need to remove a gradient background, do not forget to use this to reset
4 | // the IE filter for IE9 and below.
5 |
6 | .reset-filter() {
7 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
8 | }
9 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/reset-text.less:
--------------------------------------------------------------------------------
1 | .reset-text() {
2 | font-family: @font-family-base;
3 | // We deliberately do NOT reset font-size.
4 | font-style: normal;
5 | font-weight: normal;
6 | letter-spacing: normal;
7 | line-break: auto;
8 | line-height: @line-height-base;
9 | text-align: left; // Fallback for where `start` is not supported
10 | text-align: start;
11 | text-decoration: none;
12 | text-shadow: none;
13 | text-transform: none;
14 | white-space: normal;
15 | word-break: normal;
16 | word-spacing: normal;
17 | word-wrap: normal;
18 | }
19 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/resize.less:
--------------------------------------------------------------------------------
1 | // Resize anything
2 |
3 | .resizable(@direction) {
4 | resize: @direction; // Options: horizontal, vertical, both
5 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
6 | }
7 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/responsive-visibility.less:
--------------------------------------------------------------------------------
1 | // Responsive utilities
2 |
3 | //
4 | // More easily include all the states for responsive-utilities.less.
5 | .responsive-visibility() {
6 | display: block !important;
7 | table& { display: table !important; }
8 | tr& { display: table-row !important; }
9 | th&,
10 | td& { display: table-cell !important; }
11 | }
12 |
13 | .responsive-invisibility() {
14 | display: none !important;
15 | }
16 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/size.less:
--------------------------------------------------------------------------------
1 | // Sizing shortcuts
2 |
3 | .size(@width; @height) {
4 | width: @width;
5 | height: @height;
6 | }
7 |
8 | .square(@size) {
9 | .size(@size; @size);
10 | }
11 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/tab-focus.less:
--------------------------------------------------------------------------------
1 | // WebKit-style focus
2 |
3 | .tab-focus() {
4 | // Default
5 | outline: thin dotted;
6 | // WebKit
7 | outline: 5px auto -webkit-focus-ring-color;
8 | outline-offset: -2px;
9 | }
10 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/table-row.less:
--------------------------------------------------------------------------------
1 | // Tables
2 |
3 | .table-row-variant(@state; @background) {
4 | // Exact selectors below required to override `.table-striped` and prevent
5 | // inheritance to nested tables.
6 | .table > thead > tr,
7 | .table > tbody > tr,
8 | .table > tfoot > tr {
9 | > td.@{state},
10 | > th.@{state},
11 | &.@{state} > td,
12 | &.@{state} > th {
13 | background-color: @background;
14 | }
15 | }
16 |
17 | // Hover states for `.table-hover`
18 | // Note: this is not available for cells or rows within `thead` or `tfoot`.
19 | .table-hover > tbody > tr {
20 | > td.@{state}:hover,
21 | > th.@{state}:hover,
22 | &.@{state}:hover > td,
23 | &:hover > .@{state},
24 | &.@{state}:hover > th {
25 | background-color: darken(@background, 5%);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/text-emphasis.less:
--------------------------------------------------------------------------------
1 | // Typography
2 |
3 | .text-emphasis-variant(@color) {
4 | color: @color;
5 | a&:hover,
6 | a&:focus {
7 | color: darken(@color, 10%);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/mixins/text-overflow.less:
--------------------------------------------------------------------------------
1 | // Text overflow
2 | // Requires inline-block or block for proper styling
3 |
4 | .text-overflow() {
5 | overflow: hidden;
6 | text-overflow: ellipsis;
7 | white-space: nowrap;
8 | }
9 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/pager.less:
--------------------------------------------------------------------------------
1 | //
2 | // Pager pagination
3 | // --------------------------------------------------
4 |
5 |
6 | .pager {
7 | padding-left: 0;
8 | margin: @line-height-computed 0;
9 | list-style: none;
10 | text-align: center;
11 | &:extend(.clearfix all);
12 | li {
13 | display: inline;
14 | > a,
15 | > span {
16 | display: inline-block;
17 | padding: 5px 14px;
18 | background-color: @pager-bg;
19 | border: 1px solid @pager-border;
20 | border-radius: @pager-border-radius;
21 | }
22 |
23 | > a:hover,
24 | > a:focus {
25 | text-decoration: none;
26 | background-color: @pager-hover-bg;
27 | }
28 | }
29 |
30 | .next {
31 | > a,
32 | > span {
33 | float: right;
34 | }
35 | }
36 |
37 | .previous {
38 | > a,
39 | > span {
40 | float: left;
41 | }
42 | }
43 |
44 | .disabled {
45 | > a,
46 | > a:hover,
47 | > a:focus,
48 | > span {
49 | color: @pager-disabled-color;
50 | background-color: @pager-bg;
51 | cursor: @cursor-disabled;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/pagination.less:
--------------------------------------------------------------------------------
1 | //
2 | // Pagination (multiple pages)
3 | // --------------------------------------------------
4 | .pagination {
5 | display: inline-block;
6 | padding-left: 0;
7 | margin: @line-height-computed 0;
8 | border-radius: @border-radius-base;
9 |
10 | > li {
11 | display: inline; // Remove list-style and block-level defaults
12 | > a,
13 | > span {
14 | position: relative;
15 | float: left; // Collapse white-space
16 | padding: @padding-base-vertical @padding-base-horizontal;
17 | line-height: @line-height-base;
18 | text-decoration: none;
19 | color: @pagination-color;
20 | background-color: @pagination-bg;
21 | border: 1px solid @pagination-border;
22 | margin-left: -1px;
23 | }
24 | &:first-child {
25 | > a,
26 | > span {
27 | margin-left: 0;
28 | .border-left-radius(@border-radius-base);
29 | }
30 | }
31 | &:last-child {
32 | > a,
33 | > span {
34 | .border-right-radius(@border-radius-base);
35 | }
36 | }
37 | }
38 |
39 | > li > a,
40 | > li > span {
41 | &:hover,
42 | &:focus {
43 | z-index: 2;
44 | color: @pagination-hover-color;
45 | background-color: @pagination-hover-bg;
46 | border-color: @pagination-hover-border;
47 | }
48 | }
49 |
50 | > .active > a,
51 | > .active > span {
52 | &,
53 | &:hover,
54 | &:focus {
55 | z-index: 3;
56 | color: @pagination-active-color;
57 | background-color: @pagination-active-bg;
58 | border-color: @pagination-active-border;
59 | cursor: default;
60 | }
61 | }
62 |
63 | > .disabled {
64 | > span,
65 | > span:hover,
66 | > span:focus,
67 | > a,
68 | > a:hover,
69 | > a:focus {
70 | color: @pagination-disabled-color;
71 | background-color: @pagination-disabled-bg;
72 | border-color: @pagination-disabled-border;
73 | cursor: @cursor-disabled;
74 | }
75 | }
76 | }
77 |
78 | // Sizing
79 | // --------------------------------------------------
80 |
81 | // Large
82 | .pagination-lg {
83 | .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
84 | }
85 |
86 | // Small
87 | .pagination-sm {
88 | .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
89 | }
90 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/print.less:
--------------------------------------------------------------------------------
1 | /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
2 |
3 | // ==========================================================================
4 | // Print styles.
5 | // Inlined to avoid the additional HTTP request: h5bp.com/r
6 | // ==========================================================================
7 |
8 | @media print {
9 | *,
10 | *:before,
11 | *:after {
12 | background: transparent !important;
13 | color: #000 !important; // Black prints faster: h5bp.com/s
14 | box-shadow: none !important;
15 | text-shadow: none !important;
16 | }
17 |
18 | a,
19 | a:visited {
20 | text-decoration: underline;
21 | }
22 |
23 | a[href]:after {
24 | content: " (" attr(href) ")";
25 | }
26 |
27 | abbr[title]:after {
28 | content: " (" attr(title) ")";
29 | }
30 |
31 | // Don't show links that are fragment identifiers,
32 | // or use the `javascript:` pseudo protocol
33 | a[href^="#"]:after,
34 | a[href^="javascript:"]:after {
35 | content: "";
36 | }
37 |
38 | pre,
39 | blockquote {
40 | border: 1px solid #999;
41 | page-break-inside: avoid;
42 | }
43 |
44 | thead {
45 | display: table-header-group; // h5bp.com/t
46 | }
47 |
48 | tr,
49 | img {
50 | page-break-inside: avoid;
51 | }
52 |
53 | img {
54 | max-width: 100% !important;
55 | }
56 |
57 | p,
58 | h2,
59 | h3 {
60 | orphans: 3;
61 | widows: 3;
62 | }
63 |
64 | h2,
65 | h3 {
66 | page-break-after: avoid;
67 | }
68 |
69 | // Bootstrap specific changes start
70 |
71 | // Bootstrap components
72 | .navbar {
73 | display: none;
74 | }
75 | .btn,
76 | .dropup > .btn {
77 | > .caret {
78 | border-top-color: #000 !important;
79 | }
80 | }
81 | .label {
82 | border: 1px solid #000;
83 | }
84 |
85 | .table {
86 | border-collapse: collapse !important;
87 |
88 | td,
89 | th {
90 | background-color: #fff !important;
91 | }
92 | }
93 | .table-bordered {
94 | th,
95 | td {
96 | border: 1px solid #ddd !important;
97 | }
98 | }
99 |
100 | // Bootstrap specific changes end
101 | }
102 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/progress-bars.less:
--------------------------------------------------------------------------------
1 | //
2 | // Progress bars
3 | // --------------------------------------------------
4 |
5 |
6 | // Bar animations
7 | // -------------------------
8 |
9 | // WebKit
10 | @-webkit-keyframes progress-bar-stripes {
11 | from { background-position: 40px 0; }
12 | to { background-position: 0 0; }
13 | }
14 |
15 | // Spec and IE10+
16 | @keyframes progress-bar-stripes {
17 | from { background-position: 40px 0; }
18 | to { background-position: 0 0; }
19 | }
20 |
21 |
22 | // Bar itself
23 | // -------------------------
24 |
25 | // Outer container
26 | .progress {
27 | overflow: hidden;
28 | height: @line-height-computed;
29 | margin-bottom: @line-height-computed;
30 | background-color: @progress-bg;
31 | border-radius: @progress-border-radius;
32 | .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
33 | }
34 |
35 | // Bar of progress
36 | .progress-bar {
37 | float: left;
38 | width: 0%;
39 | height: 100%;
40 | font-size: @font-size-small;
41 | line-height: @line-height-computed;
42 | color: @progress-bar-color;
43 | text-align: center;
44 | background-color: @progress-bar-bg;
45 | .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));
46 | .transition(width .6s ease);
47 | }
48 |
49 | // Striped bars
50 | //
51 | // `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the
52 | // `.progress-bar-striped` class, which you just add to an existing
53 | // `.progress-bar`.
54 | .progress-striped .progress-bar,
55 | .progress-bar-striped {
56 | #gradient > .striped();
57 | background-size: 40px 40px;
58 | }
59 |
60 | // Call animation for the active one
61 | //
62 | // `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the
63 | // `.progress-bar.active` approach.
64 | .progress.active .progress-bar,
65 | .progress-bar.active {
66 | .animation(progress-bar-stripes 2s linear infinite);
67 | }
68 |
69 |
70 | // Variations
71 | // -------------------------
72 |
73 | .progress-bar-success {
74 | .progress-bar-variant(@progress-bar-success-bg);
75 | }
76 |
77 | .progress-bar-info {
78 | .progress-bar-variant(@progress-bar-info-bg);
79 | }
80 |
81 | .progress-bar-warning {
82 | .progress-bar-variant(@progress-bar-warning-bg);
83 | }
84 |
85 | .progress-bar-danger {
86 | .progress-bar-variant(@progress-bar-danger-bg);
87 | }
88 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/responsive-embed.less:
--------------------------------------------------------------------------------
1 | // Embeds responsive
2 | //
3 | // Credit: Nicolas Gallagher and SUIT CSS.
4 |
5 | .embed-responsive {
6 | position: relative;
7 | display: block;
8 | height: 0;
9 | padding: 0;
10 | overflow: hidden;
11 |
12 | .embed-responsive-item,
13 | iframe,
14 | embed,
15 | object,
16 | video {
17 | position: absolute;
18 | top: 0;
19 | left: 0;
20 | bottom: 0;
21 | height: 100%;
22 | width: 100%;
23 | border: 0;
24 | }
25 | }
26 |
27 | // Modifier class for 16:9 aspect ratio
28 | .embed-responsive-16by9 {
29 | padding-bottom: 56.25%;
30 | }
31 |
32 | // Modifier class for 4:3 aspect ratio
33 | .embed-responsive-4by3 {
34 | padding-bottom: 75%;
35 | }
36 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/thumbnails.less:
--------------------------------------------------------------------------------
1 | //
2 | // Thumbnails
3 | // --------------------------------------------------
4 |
5 |
6 | // Mixin and adjust the regular image class
7 | .thumbnail {
8 | display: block;
9 | padding: @thumbnail-padding;
10 | margin-bottom: @line-height-computed;
11 | line-height: @line-height-base;
12 | background-color: @thumbnail-bg;
13 | border: 1px solid @thumbnail-border;
14 | border-radius: @thumbnail-border-radius;
15 | .transition(border .2s ease-in-out);
16 |
17 | > img,
18 | a > img {
19 | &:extend(.img-responsive);
20 | margin-left: auto;
21 | margin-right: auto;
22 | }
23 |
24 | // Add a hover state for linked versions only
25 | a&:hover,
26 | a&:focus,
27 | a&.active {
28 | border-color: @link-color;
29 | }
30 |
31 | // Image captions
32 | .caption {
33 | padding: @thumbnail-caption-padding;
34 | color: @thumbnail-caption-color;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/utilities.less:
--------------------------------------------------------------------------------
1 | //
2 | // Utility classes
3 | // --------------------------------------------------
4 |
5 |
6 | // Floats
7 | // -------------------------
8 |
9 | .clearfix {
10 | .clearfix();
11 | }
12 | .center-block {
13 | .center-block();
14 | }
15 | .pull-right {
16 | float: right !important;
17 | }
18 | .pull-left {
19 | float: left !important;
20 | }
21 |
22 |
23 | // Toggling content
24 | // -------------------------
25 |
26 | // Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1
27 | .hide {
28 | display: none !important;
29 | }
30 | .show {
31 | display: block !important;
32 | }
33 | .invisible {
34 | visibility: hidden;
35 | }
36 | .text-hide {
37 | .text-hide();
38 | }
39 |
40 |
41 | // Hide from screenreaders and browsers
42 | //
43 | // Credit: HTML5 Boilerplate
44 |
45 | .hidden {
46 | display: none !important;
47 | }
48 |
49 |
50 | // For Affix plugin
51 | // -------------------------
52 |
53 | .affix {
54 | position: fixed;
55 | }
56 |
--------------------------------------------------------------------------------
/neonion/static/bootstrap/less/wells.less:
--------------------------------------------------------------------------------
1 | //
2 | // Wells
3 | // --------------------------------------------------
4 |
5 |
6 | // Base class
7 | .well {
8 | min-height: 20px;
9 | padding: 19px;
10 | margin-bottom: 20px;
11 | background-color: @well-bg;
12 | border: 1px solid @well-border;
13 | border-radius: @border-radius-base;
14 | .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));
15 | blockquote {
16 | border-color: #ddd;
17 | border-color: rgba(0,0,0,.15);
18 | }
19 | }
20 |
21 | // Sizes
22 | .well-lg {
23 | padding: 24px;
24 | border-radius: @border-radius-large;
25 | }
26 | .well-sm {
27 | padding: 9px;
28 | border-radius: @border-radius-small;
29 | }
30 |
--------------------------------------------------------------------------------
/neonion/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/favicon.ico
--------------------------------------------------------------------------------
/neonion/static/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/neonion/static/fonts/Lato/Lato-Bold-latin-ext.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/Lato/Lato-Bold-latin-ext.woff2
--------------------------------------------------------------------------------
/neonion/static/fonts/Lato/Lato-Bold-latin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/Lato/Lato-Bold-latin.woff2
--------------------------------------------------------------------------------
/neonion/static/fonts/Lato/Lato-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/Lato/Lato-Bold.woff
--------------------------------------------------------------------------------
/neonion/static/fonts/Lato/Lato-Light-latin-ext.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/Lato/Lato-Light-latin-ext.woff2
--------------------------------------------------------------------------------
/neonion/static/fonts/Lato/Lato-Light-latin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/Lato/Lato-Light-latin.woff2
--------------------------------------------------------------------------------
/neonion/static/fonts/Lato/Lato-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/Lato/Lato-Light.woff
--------------------------------------------------------------------------------
/neonion/static/fonts/Lato/Lato-Regular-latin-ext.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/Lato/Lato-Regular-latin-ext.woff2
--------------------------------------------------------------------------------
/neonion/static/fonts/Lato/Lato-Regular-latin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/Lato/Lato-Regular-latin.woff2
--------------------------------------------------------------------------------
/neonion/static/fonts/Lato/Lato-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/Lato/Lato-Regular.woff
--------------------------------------------------------------------------------
/neonion/static/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/neonion/static/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/neonion/static/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/neonion/static/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/neonion/static/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var styleguide = require('sc5-styleguide');
3 | var less = require('gulp-less');
4 | var outputPath = 'styleguide';
5 | var concat = require("gulp-concat");
6 |
7 | gulp.task('styleguide:generate', function() {
8 | return gulp.src('less/**/*.less')
9 | .pipe(styleguide.generate({
10 | title: 'Styleguide for neonion',
11 | server: true,
12 | rootPath: outputPath,
13 | overviewPath: 'less/styleguide.md',
14 | commonClass: 'myfont',
15 | extraHead: [
16 | '',
17 | ''
18 | ],
19 | disableEncapsulation: true,
20 | customColors: 'utils/styleguide.scss'
21 | }))
22 | .pipe(gulp.dest(outputPath));
23 | });
24 |
25 | gulp.task('styleguide:applystyles', function() {
26 | return gulp.src([
27 | 'less/my-bootstrap-theme.less',
28 | 'utils/additional.less'
29 | ])
30 | .pipe(concat('all.less'))
31 | .pipe(less({
32 | errLogToConsole: true
33 | }))
34 | .pipe(styleguide.applyStyles())
35 | .pipe(gulp.dest(outputPath));
36 | });
37 |
38 | gulp.task('styleguide:static', function() {
39 | gulp.src('fonts/**')
40 | .pipe(gulp.dest(outputPath + '/fonts'));
41 | gulp.src('js/jquery.min.js')
42 | .pipe(gulp.dest(outputPath + '/js'));
43 | gulp.src('js/bootstrap.min.js')
44 | .pipe(gulp.dest(outputPath + '/js'));
45 | });
46 |
47 | gulp.task('watch', ['styleguide'], function() {
48 | // Start watching changes and update styleguide whenever changes are detected
49 | // Styleguide automatically detects existing server instance
50 |
51 | gulp.watch(['less/**/*.less'], ['styleguide']);
52 | });
53 |
54 | gulp.task('styleguide', [
55 | 'styleguide:static',
56 | 'styleguide:generate',
57 | 'styleguide:applystyles'
58 | ]);
--------------------------------------------------------------------------------
/neonion/static/img/annotator-glyph-sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/img/annotator-glyph-sprite.png
--------------------------------------------------------------------------------
/neonion/static/img/annotator-icon-sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/img/annotator-icon-sprite.png
--------------------------------------------------------------------------------
/neonion/static/img/annotator/relation_checkmark_black.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/neonion/static/img/annotator/relation_checkmark_white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/neonion/static/img/annotator/relation_create.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/neonion/static/img/annotator/relation_edit.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/neonion/static/img/annotator/relation_remove_black.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/neonion/static/img/annotator/relation_remove_white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/neonion/static/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/img/logo.png
--------------------------------------------------------------------------------
/neonion/static/img/unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/static/img/unknown.png
--------------------------------------------------------------------------------
/neonion/static/js/angular/app.js:
--------------------------------------------------------------------------------
1 | var neonionApp = angular.module('neonionApp', [
2 | 'ngResource', 'ngCookies', 'angular.filter', 'ngFileUpload', 'components'
3 | ])
4 | .config(['$httpProvider', '$locationProvider',
5 | function ($httpProvider, $locationProvider) {
6 | "use strict";
7 | //$locationProvider.html5Mode(false);
8 | // CSRF settings
9 | $httpProvider.defaults.xsrfCookieName = 'csrftoken';
10 | $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
11 | }
12 | ])
13 | .constant("cookieKeys", {
14 | annotationMode: "neonion_annotationMode"
15 | }
16 | )
17 |
--------------------------------------------------------------------------------
/neonion/static/js/angular/components.js:
--------------------------------------------------------------------------------
1 | angular.module('components', [])
2 | // directive for annotator
3 | .directive('annotator', function () {
4 | return {
5 | restrict: 'E',
6 | scope: {
7 | groupId: "@groupId",
8 | documentId: "@documentId"
9 | },
10 | controller: 'AnnotatorCtrl',
11 | templateUrl: '/static/partials/annotator/annotator.html'
12 | };
13 | })
14 |
15 | // directive for annotator context
16 | .directive('annotatorContext', function () {
17 | return {
18 | restrict: 'E',
19 | scope: {
20 | groupId: "@groupId",
21 | documentId: "@documentId"
22 | },
23 | controller: 'ContextInfoCtrl',
24 | templateUrl: '/static/partials/annotator/annotator-context.html'
25 | };
26 | })
27 |
28 | // directive to render a PDF document
29 | .directive('pdfRender', function () {
30 | return {
31 | restrict: 'E',
32 | scope: {
33 | path: "@path"
34 | },
35 | controller: 'AnnotatorPDFCtrl',
36 | template: '
'
37 | };
38 | })
39 |
40 | // directive to render a plain text document
41 | .directive('plainRender', function () {
42 | return {
43 | restrict: 'E',
44 | controller: function ($scope) {
45 | $scope.completed = function () {
46 | $scope.$emit("allPagesRendered");
47 | };
48 | $scope.$emit("renderTemplateLoaded");
49 | },
50 | scope: {
51 | path: "@path"
52 | },
53 | template: ''
56 | };
57 | })
58 |
59 | // directive for filter field
60 | .directive('filter', function () {
61 | return {
62 | restrict: 'E',
63 | scope: false,
64 | template: ' '
66 | };
67 | })
68 |
69 | // directive for logged in user
70 | .directive('loggedUser', function () {
71 | return {
72 | restrict: 'E',
73 | scope: false,
74 | template: ' {{ user.email }}'
75 | };
76 | });
--------------------------------------------------------------------------------
/neonion/static/js/angular/controllers/accounts/user-list.js:
--------------------------------------------------------------------------------
1 | /**
2 | * User list controller
3 | */
4 | neonionApp.controller('UserListCtrl', ['$scope', 'UserService',
5 | function ($scope, UserService) {
6 | "use strict";
7 |
8 | $scope.users = UserService.query();
9 |
10 | $scope.update = function (user, field, value) {
11 | if (user.hasOwnProperty(field) && user[field] != value) {
12 | user[field] = value;
13 | user.$update();
14 | }
15 | };
16 |
17 | $scope.delete = function (user) {
18 | user.$delete().then(function () {
19 | var idx = $scope.users.indexOf(user);
20 | $scope.users.splice(idx, 1);
21 | });
22 | };
23 |
24 | }]);
--------------------------------------------------------------------------------
/neonion/static/js/angular/controllers/annotations/occurrence-list.js:
--------------------------------------------------------------------------------
1 | neonionApp.controller('AnnotationOccurrenceListCtrl', ['$scope', '$location',
2 | 'DocumentService', 'AnnotationStoreService',
3 | function ($scope, $location, DocumentService, AnnotationStoreService) {
4 | "use strict";
5 |
6 | $scope.queryDocumentTitles = function () {
7 | return DocumentService.queryTitles(function (titles) {
8 | $scope.documentTitles = titles;
9 | }).$promise;
10 | }
11 |
12 | $scope.queryAnnotations = function() {
13 | // TODO consider query params to dispatch annotation retrieval method
14 | // case query parm contains 'rdf.uri'
15 | return $scope.getAnnotationsOfConcept();
16 | }
17 |
18 | $scope.getAnnotationsOfConcept = function () {
19 | return AnnotationStoreService.search($location.search(), function (annotations) {
20 | $scope.annotations = annotations.filter(function (item) {
21 | return $scope.documentTitles.hasOwnProperty(item.uri);
22 | });
23 | }).$promise;
24 | };
25 |
26 | // execute promise chain
27 | $scope.queryDocumentTitles()
28 | .then($scope.queryAnnotations);
29 |
30 | }
31 | ]);
--------------------------------------------------------------------------------
/neonion/static/js/angular/controllers/annotator/annotator-context.js:
--------------------------------------------------------------------------------
1 | /*jshint jquery:true */
2 |
3 | /**
4 | * ContextInfo controller
5 | */
6 | neonionApp.controller('ContextInfoCtrl', ['$scope', '$location', 'CommonService', 'AnnotatorService', 'DocumentService', 'GroupService',
7 | function ($scope, $location, CommonService, AnnotatorService, DocumentService, GroupService) {
8 | "use strict";
9 |
10 | $scope.getCurrentUser = function () {
11 | return CommonService.getCurrentUser(function (user) {
12 | $scope.user = user;
13 | }).$promise;
14 | };
15 |
16 | $scope.getDocument = function () {
17 | if ($scope.hasOwnProperty("documentId")) {
18 | return DocumentService.get({id: $scope.documentId}, function (document) {
19 | $scope.document = document;
20 | }).$promise;
21 | }
22 | else {
23 | return Promise.resolve(true);
24 | }
25 | };
26 |
27 | $scope.getGroup = function () {
28 | if ($scope.hasOwnProperty("groupId")) {
29 | var groupId = parseInt($scope.groupId);
30 | if (!isNaN(groupId)) {
31 | // get the group object
32 | return GroupService.get({id: groupId}, function (group) {
33 | $scope.isPrivate = false;
34 | $scope.group = group;
35 | }).$promise;
36 | }
37 | else {
38 | $scope.isPrivate = true;
39 | // no http communication
40 | return Promise.resolve(true);
41 | }
42 | }
43 | else {
44 | return Promise.resolve(true);
45 | }
46 | };
47 |
48 | // execute promise chain
49 | $scope.getCurrentUser()
50 | .then($scope.getDocument)
51 | .then($scope.getGroup)
52 | .then(function () {
53 | $scope.annotatorService = AnnotatorService;
54 | });
55 |
56 | }]);
--------------------------------------------------------------------------------
/neonion/static/js/angular/controllers/common/main.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Main controller for the whole application
3 | */
4 | neonionApp.controller('MainCtrl', ['$scope', 'CommonService',
5 | function ($scope, CommonService) {
6 | "use strict";
7 | $scope.common = CommonService;
8 |
9 | $scope.getCurrentUser = function () {
10 | return CommonService.getCurrentUser(function (user) {
11 | $scope.user = user;
12 | }).$promise;
13 | };
14 |
15 | $scope.getCurrentUser()
16 | }]);
--------------------------------------------------------------------------------
/neonion/static/js/angular/controllers/vocabulary/concept-list.js:
--------------------------------------------------------------------------------
1 | neonionApp.controller('ConceptListCtrl', ['$scope', '$sce', 'CommonService', 'ConceptService', 'PropertyService',
2 | function ($scope, $sce, CommonService, ConceptService, PropertyService) {
3 | "use strict";
4 |
5 | $scope.listModeEnabled = true;
6 | $scope.style = {
7 | compact: true,
8 | allowCreate : true,
9 | detailTemplateUrl : "/static/partials/vocabulary/concept-detail.html"
10 | };
11 | $scope.locales = {
12 | // TODO localize
13 | create: "Create Concept"
14 | };
15 |
16 | $scope.queryConcepts = function () {
17 | return ConceptService.query(function (data) {
18 | $scope.resources = data;
19 | }).$promise;
20 | };
21 |
22 | $scope.queryProperties = function () {
23 | return PropertyService.query(function (data) {
24 | $scope.properties = data;
25 | }).$promise;
26 | };
27 |
28 | $scope.createItem = function() {
29 | $scope.listModeEnabled = false;
30 | $scope.$broadcast("createEvent")
31 | };
32 |
33 | $scope.editItem = function(item) {
34 | $scope.listModeEnabled = false;
35 | $scope.$broadcast("editEvent", item)
36 | };
37 |
38 | $scope.getItemHeader = function (resource) {
39 | return $sce.trustAsHtml(resource.label);
40 | };
41 |
42 | $scope.getItemDescription = function (resource) {
43 | return $sce.trustAsHtml(resource.comment);
44 | };
45 |
46 | $scope.filterResources = function (resource) {
47 | if (CommonService.filter.query.length > 0) {
48 | return resource.label.toLowerCase().indexOf(CommonService.filter.query.toLowerCase()) != -1;
49 | }
50 | return true;
51 | };
52 |
53 | var unbindReturnEvent = $scope.$on('returnEvent', function () {
54 | $scope.queryConcepts();
55 | $scope.listModeEnabled = true;
56 | });
57 | $scope.$on('$destroy', unbindReturnEvent);
58 |
59 | // execute promise chain
60 | $scope.queryConcepts();
61 |
62 | }]
63 | );
--------------------------------------------------------------------------------
/neonion/static/js/angular/controllers/vocabulary/property-list.js:
--------------------------------------------------------------------------------
1 | neonionApp.controller('PropertyListCtrl', ['$scope', '$sce', 'CommonService', 'PropertyService',
2 | function ($scope, $sce, CommonService, PropertyService) {
3 | "use strict";
4 |
5 | $scope.listModeEnabled = true;
6 | $scope.style = {
7 | compact: true,
8 | allowCreate : true,
9 | detailTemplateUrl : "/static/partials/vocabulary/property-detail.html"
10 | };
11 | $scope.locales = {
12 | // TODO localize
13 | create: "Create Property"
14 | };
15 |
16 | $scope.queryProperties = function () {
17 | return PropertyService.query(function (data) {
18 | $scope.resources = data;
19 | }).$promise;
20 | };
21 |
22 | $scope.createItem = function() {
23 | $scope.listModeEnabled = false;
24 | $scope.$broadcast("createEvent")
25 | };
26 |
27 | $scope.editItem = function(item) {
28 | $scope.listModeEnabled = false;
29 | $scope.$broadcast("editEvent", item)
30 | };
31 |
32 | $scope.getItemHeader = function (resource) {
33 | return $sce.trustAsHtml(resource.label);
34 | };
35 |
36 | $scope.getItemDescription = function (resource) {
37 | return $sce.trustAsHtml(resource.comment);
38 | };
39 |
40 | $scope.filterResources = function (resource) {
41 | if (CommonService.filter.query.length > 0) {
42 | return resource.label.toLowerCase().indexOf(CommonService.filter.query.toLowerCase()) != -1;
43 | }
44 | return true;
45 | };
46 |
47 | var unbindReturnEvent = $scope.$on('returnEvent', function () {
48 | $scope.queryProperties();
49 | $scope.listModeEnabled = true;
50 | });
51 | $scope.$on('$destroy', unbindReturnEvent);
52 |
53 | // execute promise chain
54 | $scope.queryProperties();
55 |
56 | }]
57 | );
--------------------------------------------------------------------------------
/neonion/static/js/angular/controllers/workbench/bulk-upload.js:
--------------------------------------------------------------------------------
1 | neonionApp.controller('BulkUploadCtrl', ['$scope', 'Upload',
2 | function ($scope, Upload) {
3 |
4 | $scope.form = {
5 | index: "",
6 | type: "",
7 | upload : {
8 | uploading : false,
9 | progress : 0
10 | }
11 | };
12 | $scope.upload = null;
13 |
14 | $scope.validate = function() {
15 | return !$scope.form.upload.uploading &&
16 | $scope.form.index.length > 0 &&
17 | $scope.form.type.length > 0;
18 | };
19 |
20 | $scope.uploadFile = function (file) {
21 | if ($scope.validate() && file) {
22 | $scope.form.upload.uploading = true;
23 | $scope.form.upload.progress = 0;
24 |
25 | $scope.upload = Upload.upload({
26 | url: 'api/es/import/' + $scope.form.index + "/" + $scope.form.type,
27 | file: file
28 | }).progress(function (evt) {
29 | var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
30 | $scope.form.upload.progress = progressPercentage;
31 | console.log('progress: ' + progressPercentage + '% ' + evt.config.file.name);
32 | }).success(function (data, status, headers, config) {
33 | $scope.form.upload.uploading = false;
34 | console.log('file ' + config.file.name + 'uploaded. Response: ' + data);
35 | }).error(function (data, status, headers, config) {
36 | $scope.form.upload.uploading = false;
37 | console.log('error status: ' + status);
38 | })
39 | }
40 | };
41 |
42 | $scope.cancelUpload = function() {
43 | if ($scope.form.upload.uploading) {
44 | $scope.upload.abort();
45 | $scope.form.upload.uploading = false;
46 | $scope.form.upload.progress = 0;
47 | }
48 | }
49 | }]
50 | );
51 |
--------------------------------------------------------------------------------
/neonion/static/js/angular/controllers/workbench/orphaned-annotation-list.js:
--------------------------------------------------------------------------------
1 | neonionApp.controller('OrphanedAnnotationListCtrl', ['$scope', '$sce', 'DocumentService', 'AnnotationStoreService',
2 | function ($scope, $sce, DocumentService, AnnotationStoreService) {
3 | "use strict";
4 |
5 | $scope.stepSize = 25;
6 | $scope.resources = [];
7 |
8 | $scope.queryDocuments = function () {
9 | return DocumentService.queryTitles(function (data) {
10 | $scope.documentTitles = data;
11 | }).$promise;
12 | };
13 |
14 | $scope.getQueryParams = function (pageNum) {
15 | return {
16 | offset: pageNum * $scope.stepSize,
17 | limit: $scope.stepSize
18 | };
19 | }
20 |
21 | $scope.queryOrphanedAnnotations = function (documentTitles, pageNum) {
22 | pageNum = pageNum | 0;
23 | return AnnotationStoreService.search($scope.getQueryParams(pageNum), function (data) {
24 | if (data.length > 0) {
25 | var orphanedAnnotations = data.filter(function (annotation) {
26 | return !documentTitles.hasOwnProperty(annotation.uri);
27 | });
28 | $scope.resources = $scope.resources.concat(orphanedAnnotations);
29 |
30 | // get next annotations
31 | $scope.queryOrphanedAnnotations(documentTitles, pageNum + 1);
32 | }
33 | }).$promise;
34 | };
35 |
36 | $scope.deleteAnnotation = function (annotation) {
37 | return annotation.$delete(function () {
38 | var annotationIdx = $scope.resources.indexOf(annotation);
39 | $scope.resources.splice(annotationIdx, 1);
40 | }).$promise;
41 | }
42 |
43 | $scope.deleteAnnotations = function (annotations) {
44 | annotations.forEach(function (annotation) {
45 | $scope.deleteAnnotation(annotation);
46 | });
47 | }
48 |
49 | // execute promise chain
50 | $scope.queryDocuments()
51 | .then($scope.queryOrphanedAnnotations);
52 |
53 | }]
54 | );
--------------------------------------------------------------------------------
/neonion/static/js/angular/filters.js:
--------------------------------------------------------------------------------
1 | neonionApp
2 | .filter('escape', function () {
3 | return window.encodeURIComponent;
4 | })
5 | .filter('truncate', function () {
6 | return function (text, position) {
7 | if (position == 'left')
8 | text = '[...]\u00A0' + text;
9 |
10 | if (position == 'right')
11 | text = text + '\u00A0[...]';
12 |
13 | return text;
14 | };
15 | })
16 | .filter('filterByConceptAnnotation', function () {
17 | return function (annotations) {
18 | if (!angular.isUndefined(annotations)) {
19 | return annotations.filter(function (value) {
20 | return (value['oa']['motivatedBy'] == "oa:classifying" ||
21 | value['oa']['motivatedBy'] == "oa:identifying");
22 | });
23 | }
24 | else {
25 | return [];
26 | }
27 | };
28 | })
29 | .filter('filterByLinkedAnnotation', function () {
30 | return function (annotations) {
31 | if (!angular.isUndefined(annotations)) {
32 | return annotations.filter(function (value) {
33 | return (value['oa']['motivatedBy'] == "oa:linking");
34 | });
35 | }
36 | else {
37 | return [];
38 | }
39 | };
40 | })
41 | .filter('filterByCommentAnnotation', function () {
42 | return function (annotations) {
43 | if (!angular.isUndefined(annotations)) {
44 | return annotations.filter(function (value) {
45 | return (value['oa']['motivatedBy'] == "oa:commenting");
46 | });
47 | }
48 | else {
49 | return [];
50 | }
51 | };
52 | })
53 | .filter('filterByHighlightAnnotation', function () {
54 | return function (annotations) {
55 | if (!angular.isUndefined(annotations)) {
56 | return annotations.filter(function (value) {
57 | return (value['oa']['motivatedBy'] == "oa:highlighting");
58 | });
59 | }
60 | else {
61 | return [];
62 | }
63 | };
64 | });
--------------------------------------------------------------------------------
/neonion/static/js/angular/lib/angular-cookies.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.4.3
3 | (c) 2010-2015 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(p,g,l){'use strict';function m(b,a,f){var c=f.baseHref(),k=b[0];return function(b,d,e){var f,h;e=e||{};h=e.expires;f=g.isDefined(e.path)?e.path:c;d===l&&(h="Thu, 01 Jan 1970 00:00:00 GMT",d="");g.isString(h)&&(h=new Date(h));d=encodeURIComponent(b)+"="+encodeURIComponent(d);d=d+(f?";path="+f:"")+(e.domain?";domain="+e.domain:"");d+=h?";expires="+h.toUTCString():"";d+=e.secure?";secure":"";e=d.length+1;4096 4096 bytes)!");k.cookie=d}}g.module("ngCookies",["ng"]).provider("$cookies",[function(){var b=this.defaults={};this.$get=["$$cookieReader","$$cookieWriter",function(a,f){return{get:function(c){return a()[c]},getObject:function(c){return(c=this.get(c))?g.fromJson(c):c},getAll:function(){return a()},put:function(c,a,n){f(c,a,n?g.extend({},b,n):b)},putObject:function(c,b,a){this.put(c,g.toJson(b),a)},remove:function(a,k){f(a,l,k?g.extend({},b,k):b)}}}]}]);g.module("ngCookies").factory("$cookieStore",
8 | ["$cookies",function(b){return{get:function(a){return b.getObject(a)},put:function(a,f){b.putObject(a,f)},remove:function(a){b.remove(a)}}}]);m.$inject=["$document","$log","$browser"];g.module("ngCookies").provider("$$cookieWriter",function(){this.$get=m})})(window,window.angular);
9 | //# sourceMappingURL=angular-cookies.min.js.map
10 |
--------------------------------------------------------------------------------
/neonion/static/js/angular/root.js:
--------------------------------------------------------------------------------
1 | neonionApp
2 | .run(function ($rootScope) {
3 |
4 | /**
5 | * Transform the given data to a CSV export
6 | */
7 | $rootScope.exportCSV = function (data, properties, separator) {
8 | separator = separator || ';'
9 | var csvContent = 'data:text/csv;charset=utf-8,';
10 | // create array to store lines
11 | var lines = [];
12 | // add header information
13 | lines.push(properties.join(separator));
14 | // create array to store each field value
15 | var fields = [];
16 | fields.length = properties.length;
17 |
18 | // iterate over data items
19 | data.forEach(function (item) {
20 | // iterate over specified properties
21 | properties.forEach(function (property, index) {
22 | var subValue = item;
23 | // split property into keys
24 | var keys = property.split('.');
25 | // iterate over keys in current property
26 | for (var i = 0; i < keys.length; i++) {
27 | if (subValue.hasOwnProperty(keys[i])) {
28 | subValue = subValue[keys[i]];
29 | }
30 | else {
31 | subValue = '';
32 | // exit if current key not exists
33 | break;
34 | }
35 | }
36 | // write value to field set
37 | fields[index] = JSON.stringify(subValue);
38 | });
39 | lines.push(fields.join(separator));
40 | });
41 | // closure
42 | return csvContent + lines.join('%0A');
43 | };
44 |
45 | });
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/annotation-store.js:
--------------------------------------------------------------------------------
1 | neonionApp.factory('AnnotationStoreService', ['$resource',
2 | function ($resource) {
3 | return $resource('/store/annotations/:id',
4 | {id: '@id', limit: 999999},
5 | {
6 | 'search': {
7 | method: 'GET',
8 | params: {limit: 999999},
9 | isArray: true,
10 | cache: true,
11 | url: '/store/search',
12 | transformResponse: function (data, headersGetter) {
13 | return angular.fromJson(data)['rows'];
14 | }
15 | }
16 | }
17 | );
18 | }]
19 | );
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/common.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Common Service to share data across controllers
3 | */
4 | neonionApp.factory('CommonService', ['UserService',
5 | function (UserService) {
6 | "use strict";
7 |
8 | var factory = {
9 | filter: {
10 | query: ""
11 | },
12 | search: {
13 | query: "",
14 | enabled: false
15 | }
16 | };
17 |
18 | factory.getCurrentUser = function (onFulfilled) {
19 | return UserService.current(onFulfilled);
20 | };
21 |
22 | return factory;
23 | }]
24 | );
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/concept.js:
--------------------------------------------------------------------------------
1 | neonionApp.factory('ConceptService', ['$resource',
2 | function ($resource) {
3 | return $resource('/api/concepts/:id',
4 | {id: '@id'},
5 | {
6 | 'save': {method: 'POST', url: '/api/concepts/'},
7 | 'update': {method: 'PUT'},
8 | }
9 | );
10 | }]
11 | );
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/conceptset.js:
--------------------------------------------------------------------------------
1 | neonionApp.factory('ConceptSetService', ['$resource',
2 | function ($resource) {
3 | return $resource('/api/conceptsets/:id',
4 | {id: '@id'},
5 | {
6 | 'save': {method: 'POST', url: '/api/conceptsets/'},
7 | 'update': {method: 'PUT'},
8 | 'getDeep': {method: 'GET', isArray: false, params: {deep: true}}
9 | }
10 | );
11 | }]
12 |
13 | );
14 |
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/document.js:
--------------------------------------------------------------------------------
1 | neonionApp.factory('DocumentService', ['$resource',
2 | function ($resource) {
3 | return $resource('/api/documents/:id',
4 | {id: '@id'},
5 | {
6 | 'queryTitles': {
7 | method: 'GET',
8 | params: {},
9 | cache: true,
10 | transformResponse: function (data, header) {
11 | var jsonData = angular.fromJson(data);
12 | var names = {};
13 | angular.forEach(jsonData, function (item) {
14 | names[item.id] = item.title;
15 | });
16 | return names;
17 | }
18 | },
19 | 'save': {method: 'POST', url:'/api/documents/'},
20 | 'update': {method: 'PUT'}
21 | });
22 | }]
23 | );
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/group.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @deprecated Service for groups
3 | */
4 | neonionApp.factory('GroupService', ['$resource',
5 | function ($resource) {
6 | return $resource('/api/groups/:id',
7 | {id: '@id'},
8 | {
9 | 'update': {method: 'PUT'},
10 | 'queryGroupNames': {
11 | method: 'GET',
12 | params: {},
13 | cache: true,
14 | transformResponse: function (data, header) {
15 | var jsonData = angular.fromJson(data);
16 | var names = {};
17 | angular.forEach(jsonData, function (item) {
18 | names[item.id] = item.name;
19 | });
20 | return names;
21 | }
22 | }
23 | });
24 | }]);
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/linked-concept.js:
--------------------------------------------------------------------------------
1 | neonionApp.factory('LinkedConceptService', ['$resource',
2 | function ($resource) {
3 | return $resource('/api/linkedconcepts/:id',
4 | {id: '@id'},
5 | {
6 | 'save': {method: 'POST', url: '/api/linkedconcepts/'},
7 | 'update': {method: 'PUT'},
8 | }
9 | );
10 | }]
11 | );
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/membership.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Service for memberships
3 | */
4 | neonionApp.factory('MembershipService', ['$resource',
5 | function ($resource) {
6 | return $resource('/api/memberships/:id',
7 | {id: '@id'},
8 | {
9 | 'update': {method: 'PUT'}
10 | }
11 | );
12 | }]);
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/property.js:
--------------------------------------------------------------------------------
1 | neonionApp.factory('PropertyService', ['$resource',
2 | function ($resource) {
3 | return $resource('/api/properties/:id',
4 | {id: '@id'},
5 | {
6 | 'save': {method: 'POST', url: '/api/properties/'},
7 | 'update': {method: 'PUT'},
8 | }
9 | );
10 | }]);
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/user.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Service for accounts
3 | */
4 | neonionApp.factory('UserService', ['$resource',
5 | function ($resource) {
6 | return $resource('/api/users/:id',
7 | {id: '@id'},
8 | {
9 | 'update': {method: 'PUT'},
10 | 'current': {
11 | method: 'GET',
12 | params: {},
13 | cache: true,
14 | isArray: false,
15 | url: '/api/users/current'
16 | }
17 | }
18 | );
19 | }]);
--------------------------------------------------------------------------------
/neonion/static/js/angular/services/workspace.js:
--------------------------------------------------------------------------------
1 | neonionApp.factory('WorkspaceService', ['$http', function ($http) {
2 | "use strict";
3 | var factory = {};
4 |
5 | factory.addDocument = function (user, docID) {
6 | return $http.post("api/users/" + user.id + "/add_document", {doc_id: docID});
7 | };
8 |
9 | //TODO Create an Endpoint
10 | factory.modifyDocument = function(user, docID) {
11 | return $http.post("api/documents/" + docID + "/modify_document");
12 | }
13 |
14 | factory.removeDocument = function (user, docID) {
15 | return $http.post("api/users/" + user.id + "/hide_document", {doc_id: docID});
16 | };
17 |
18 | return factory;
19 | }]);
20 |
--------------------------------------------------------------------------------
/neonion/static/js/neonion-context.jsonld:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "http://www.w3.org/ns/oa-context-20130208.json",
4 | {
5 | "@vocab": "http://www.neonion.org/ontology"
6 | }
7 | ]
8 | }
--------------------------------------------------------------------------------
/neonion/static/less/custom-bootstrap.less:
--------------------------------------------------------------------------------
1 | // styleguide:ignore:start//
2 |
3 | /*!
4 | * Bootstrap v3.3.5 (http://getbootstrap.com)
5 | * Copyright 2011-2015 Twitter, Inc.
6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7 | */
8 |
9 | // Core variables and mixins
10 | @import "custom-variables.less";
11 | @import "../bootstrap/less/mixins.less";
12 |
13 | // Reset and dependencies
14 | @import "../bootstrap/less/normalize.less";
15 | @import "../bootstrap/less/print.less";
16 | @import "../bootstrap/less/glyphicons.less";
17 |
18 | // Core CSS
19 | @import "../bootstrap/less/scaffolding.less";
20 | @import "../bootstrap/less/type.less";
21 | @import "../bootstrap/less/code.less";
22 | @import "../bootstrap/less/grid.less";
23 | @import "../bootstrap/less/tables.less";
24 | @import "../bootstrap/less/forms.less";
25 | @import "../bootstrap/less/buttons.less";
26 |
27 | // Components
28 | @import "../bootstrap/less/component-animations.less";
29 | @import "../bootstrap/less/dropdowns.less";
30 | @import "../bootstrap/less/button-groups.less";
31 | @import "../bootstrap/less/input-groups.less";
32 | @import "../bootstrap/less/navs.less";
33 | @import "../bootstrap/less/navbar.less";
34 | @import "../bootstrap/less/breadcrumbs.less";
35 | @import "../bootstrap/less/pagination.less";
36 | @import "../bootstrap/less/pager.less";
37 | @import "../bootstrap/less/labels.less";
38 | @import "../bootstrap/less/badges.less";
39 | @import "../bootstrap/less/jumbotron.less";
40 | @import "../bootstrap/less/thumbnails.less";
41 | @import "../bootstrap/less/alerts.less";
42 | @import "../bootstrap/less/progress-bars.less";
43 | @import "../bootstrap/less/media.less";
44 | @import "../bootstrap/less/list-group.less";
45 | @import "../bootstrap/less/panels.less";
46 | @import "../bootstrap/less/responsive-embed.less";
47 | @import "../bootstrap/less/wells.less";
48 | @import "../bootstrap/less/close.less";
49 |
50 | // Components w/ JavaScript
51 | @import "../bootstrap/less/modals.less";
52 | @import "../bootstrap/less/tooltip.less";
53 | @import "../bootstrap/less/popovers.less";
54 | @import "../bootstrap/less/carousel.less";
55 |
56 | // Utility classes
57 | @import "../bootstrap/less/utilities.less";
58 | @import "../bootstrap/less/responsive-utilities.less";
59 |
60 | // styleguide:ignore:end//
--------------------------------------------------------------------------------
/neonion/static/less/modules/colors.less:
--------------------------------------------------------------------------------
1 | // Primary Colors
2 | //
3 | // These are the main color variables.
4 | // Use those variables instead of using CSS HEX values.
5 | //
6 | // @tangerine - Primar Color
7 | // @azure - Secondary color - not used a lot at the moment.
8 | // @red - This is red - used for warnings in forms and notifications.
9 | // @black - Black
10 | // @white - White
11 | //
12 | // markup:
13 | // {$modifiers}
14 | //
15 | // Styleguide 1.2
16 |
17 | @tangerine: #f39100; // orange
18 | @azure: #008df3; // blue
19 |
20 | @red: #ff3235; // red
21 | @black: #000000; // black
22 | @white: #ffffff; // white
23 |
24 |
25 | // Grey Palette
26 | //
27 | // If you need a shade of grey, choose one of the following
28 | //
29 | // @gallery - Very light grey - used for background of pages and selected
30 | // element in sidebar navigation.
31 | // @silver - Light grey - used for borders e.g: document boxes, tables
32 | // @manatee - Grey - used for hovering borders, disabled buttons or
33 | // navigation elements.
34 | // @dove-gray - Dark grey - used as border color for textinput.
35 | // @mid-gray - Dark dark grey - used as floating label color and placeholder.
36 | // @ship-gray - Dark dark dark grey - general text color on document boxes,
37 | // buttons, links, navigation, subnavigation things which can be
38 | // hovered in general.
39 | //
40 | // markup:
41 | // {$modifiers}
42 | //
43 | // Styleguide 1.1
44 |
45 | @gallery: #eeeeee; // light-grey
46 | @silver: #cdcdcd; // grey
47 | @manatee: #8e8e93; // dark-grey
48 | @dove-gray: #717171; // dark-dark-grey
49 | @mid-gray: #616165; // dark-dark-dark-grey
50 | @ship-gray: #434346; // dark-dark-dark-dark-grey
--------------------------------------------------------------------------------
/neonion/static/less/modules/variables.less:
--------------------------------------------------------------------------------
1 | // Variables
2 | //
3 | // This section descibes used variables.
4 | //
5 | // @lh - Vertical Gap (top to bottom) - Line Height, using the one from
6 | // bootstrap, it is about 20px. Is is like a vertical grid.
7 | // @gap-h - Horizontal Gap (left to right) - Using the one from bootstrap, it
8 | // is 12px. It is used for horizontal gaps.
9 | //
10 | // markup:
11 | // LESS variable
12 | //
13 | // Styleguide 4.1
14 | @lh: @line-height-computed;
15 | @gap-h: @padding-base-horizontal;
--------------------------------------------------------------------------------
/neonion/static/less/partials/buttons.less:
--------------------------------------------------------------------------------
1 | // Buttons
2 | //
3 | // We are using the same buttons as in bootstrap, look [here](http://getbootstrap.com/css/#buttons).
4 | // Buttons can also be styled as links.
5 | // We added a `btn-secondary` for grey buttons on white background used in the annotator.
6 | // `btn-xs` from bootstrap can also be used.
7 | //
8 | // .btn-default - Used for not primary action (e.g. cancel) on grey bg.
9 | // .btn-primary - Used for primary action (e.g. save).
10 | // .btn-secondary - Used for buttons on white background (e.g. in annotator).
11 | // .btn-link - Deemphasize buttons (e.g. delete).
12 | //
13 | // markup:
14 | // Button
15 | //
16 | //
17 | // button with an icon
18 | //
19 | //
20 | //
21 | // Styleguide 3.7
22 |
23 | .btn-secondary {
24 | .button-variant(@btn-secondary-color; @btn-secondary-bg; @btn-secondary-border);
25 | }
26 |
27 | // Size and Spacing
28 | //
29 | // Sometimes buttons need to be smaller, e.g in annotator.
30 | // And also need to have some spacing around them, so when having multiple
31 | // buttons below each other they dont stick together.
32 | //
33 | // .btn-xs - Extra small buttons.
34 | // .btn-spacing - Add some extra spacing around them.
35 | //
36 | // markup:
37 | // Button
38 | // Button
39 | // Button
40 | //
41 | // Styleguide 3.7.1
42 | .btn-spacing {
43 | margin: @gap-h/4;
44 | }
--------------------------------------------------------------------------------
/neonion/static/less/partials/helper.less:
--------------------------------------------------------------------------------
1 | // Vertical Spacing - Helper Classes
2 | // TODO Styleguide
3 | .gap-bottom {
4 | margin-bottom: @lh;
5 | }
6 |
7 | .gap-top {
8 | margin-top: @lh;
9 | }
10 |
11 | .annotator-font {
12 | font-family: 'Lato', sans-serif;
13 | font-weight: 300;
14 | }
15 |
16 | .annotator-basefontsize {
17 | font-size: @font-size-base - 2px;
18 | line-height: @lh;
19 | }
20 |
21 | // https://medium.com/@Florian/freebie-google-material-design-shadow-helper-2a0501295a2d
22 | .shadow {
23 | box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
24 | }
--------------------------------------------------------------------------------
/neonion/static/less/partials/links.less:
--------------------------------------------------------------------------------
1 | // Links
2 | //
3 | // A link can be explicitly styled as a link.
4 | //
5 | // markup:
6 | // this is a link with class link
7 | // this is a link
8 | //
9 | // Styleguide 3.8
10 | .link {
11 | text-decoration: underline;
12 | &:hover { color: darken(@tangerine, 2%); }
13 | }
--------------------------------------------------------------------------------
/neonion/static/partials/accounts-user-list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | User
5 | Account Settings
6 |
7 |
8 |
9 |
10 |
11 | {{ user.email }}
12 |
13 |
38 |
39 |
40 |
42 | Delete
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/neonion/static/partials/analyze-query.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/neonion/static/partials/annotation-list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/neonion/static/partials/annotations/annotation-document-list.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/neonion/static/partials/annotations/annotation-occurrence-list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Annotation Context
5 | Document
6 | Created
7 |
8 |
9 |
10 |
11 | {{ annotation.neonion.context.surrounding.left }} {{ annotation.quote }} {{ annotation.neonion.context.surrounding.right }}
12 | {{ documentTitles[annotation.uri] }}
13 | {{ annotation.created | date : "MM/dd/yyyy 'at' h:mma" }}
14 |
15 |
16 |
--------------------------------------------------------------------------------
/neonion/static/partials/annotations/comment-list.html:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
22 |
23 |
24 |
25 | Context
26 | Comment
27 | Created by
28 |
29 |
30 |
31 |
32 |
33 | {{ annotation.neonion.context.surrounding.left | truncate:'left' }}
34 |
36 | {{ annotation.quote }}
37 |
38 | {{ annotation.neonion.context.surrounding.right | truncate:'right' }}
39 |
40 | {{ annotation.text }}
41 | {{ annotation['neonion']['creator'] }} {{ annotation.created | date : "MM/dd/yyyy 'at' h:mma" }}
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/neonion/static/partials/annotations/concept-list.html:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 | {{ (annotationByConceptType | first)['neonion']['viewer']['conceptLabel'] }}
12 |
13 |
37 |
38 |
--------------------------------------------------------------------------------
/neonion/static/partials/annotations/highlight-list.html:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
22 |
23 |
24 |
25 | Highlight
26 | Created by
27 |
28 |
29 |
30 |
31 |
32 | {{ annotation.neonion.context.surrounding.left | truncate:'left' }}
33 |
35 | {{ annotation.quote }}
36 |
37 | {{ annotation.neonion.context.surrounding.right | truncate:'right' }}
38 |
39 | {{ annotation['neonion']['creator'] }} {{ annotation.created | date : "MM/dd/yyyy 'at' h:mma" }}
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/neonion/static/partials/annotator/annotator-context.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | {{ document.title }}
22 |
23 | Private
24 | {{ group.name }}
25 |
26 |
27 |
--------------------------------------------------------------------------------
/neonion/static/partials/annotator/annotator.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/neonion/static/partials/generic-resource-list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | {{ locales.create }}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
22 |
23 |
24 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/neonion/static/partials/import-meta-data.html:
--------------------------------------------------------------------------------
1 | Document properties
2 | Please choose the properties you want to consider for this document, which correspond to the Dublin Core Metadata Element Set
3 |
4 |
29 |
--------------------------------------------------------------------------------
/neonion/static/partials/meta_data_in_properties.html:
--------------------------------------------------------------------------------
1 | Please choose the properties you want to consider for your documents which correspond to the Dublin Core Metadata Element Set
2 |
3 |
--------------------------------------------------------------------------------
/neonion/static/partials/vocabulary/concept-detail.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Delete
8 |
9 | Cancel
11 |
12 | Create
14 |
15 | Save
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Label
25 |
27 |
28 |
29 |
30 |
31 | URI
32 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | Description
41 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/neonion/static/partials/vocabulary/conceptset-detail.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Delete
8 |
9 | Cancel
11 |
12 | Create
14 |
15 | Save
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Label
25 |
27 |
28 |
29 |
30 |
31 | URI
32 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | Description
41 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/neonion/static/partials/vocabulary/multiselect.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ literals.multiselect.assigned }}
4 |
5 |
6 |
7 |
8 |
9 |
11 |
12 | {{ item.label }}
13 | {{ item.comment }}
14 |
15 | {{ literals.multiselect.nothingAssigned }}
16 |
17 |
18 |
19 |
20 |
21 | {{ literals.multiselect.assignable }}
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
34 |
35 | {{ item.label }}
36 | {{ item.comment }}
37 |
38 | {{ literals.multiselect.nothingAssignable }}
39 |
40 |
41 |
--------------------------------------------------------------------------------
/neonion/static/partials/workbench/elasticsearch.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Bulk Import
6 |
7 | Index
8 |
10 |
11 |
12 | Type
13 |
15 |
16 |
17 | Uploaded File
18 |
20 |
21 |
22 | Submit
24 | Cancel
26 |
27 |
28 |
30 | {{ form.upload.progress }}%
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/neonion/static/partials/workbench/orphaned-annotation-list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | DocumentIdentifer {{ key }}
4 |
5 |
6 |
7 | Created: {{ annotation.created | date : "MM/dd/yyyy 'at' h:mma" }}
8 | Motivation: {{ annotation.oa.motivatedBy }}
9 | {{ annotation.context.left }}{{ annotation.quote }} {{ annotation.context.right }}
10 | AnnotationIdentifier {{ annotation.uri }}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/neonion/static/partials/workspace-document-list.html:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/neonion/static/utils/additional.less:
--------------------------------------------------------------------------------
1 | .myfont {
2 | font-family: 'Lato', sans-serif;
3 | font-weight: 300;
4 | font-size: 18px;
5 | }
6 |
7 | .grey-bg {
8 | background-color: @gallery;
9 | }
10 |
11 | .half-size {
12 | width: 50%;
13 | }
14 |
15 | .margin {
16 | padding: @lh !important;
17 | }
--------------------------------------------------------------------------------
/neonion/static/utils/styleguide.scss:
--------------------------------------------------------------------------------
1 | // Main color definitions
2 | $primary-color: #434346 !default; // @ship-gray: dark-dark-dark-dark-grey
3 | $secondary-color: #cdcdcd !default; // @silver: grey
4 | $tertiary-color: #cdcdcd !default; // @silver: grey
5 |
6 | // Button and link colors
7 | $primary-action-color: #f39100 !default; // @tangerine: orange
8 | $default-action-color: #f39100 !default; // @tangerine: orange
9 | $action-color-change: 15% !default;
--------------------------------------------------------------------------------
/neonion/templates/accounts_management.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Accounts{% endblock %}
6 | {% block page_id %}userlist{% endblock %}
7 |
8 | {% block content %}
9 |
10 |
11 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | {% endblock %}
--------------------------------------------------------------------------------
/neonion/templates/annotator.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 | {% load pipeline %}
5 |
6 | {% block title %}Annotator{% endblock %}
7 | {% block page_id %}annotator{% endblock %}
8 |
9 | {% block left %}
10 |
15 | {% endblock %}
16 |
17 | {% block right %}
18 |
30 | {% endblock %}
31 |
32 | {% block content %}
33 | {% endblock %}
34 |
35 | {% block scripts %}
36 | {% javascript 'annotator' %}
37 | {% endblock %}
--------------------------------------------------------------------------------
/neonion/templates/base_annotations.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Annotations{% endblock %}
6 | {% block page_id %}Annotations{% endblock %}
7 |
8 | {% block content %}
9 |
10 |
11 |
12 | {% endblock %}
--------------------------------------------------------------------------------
/neonion/templates/base_annotations_documents.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Documents{% endblock %}
6 | {% block page_id %}Documents{% endblock %}
7 |
8 | {% block content %}
9 |
10 | {% endblock %}
--------------------------------------------------------------------------------
/neonion/templates/base_annotations_occurrences.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}All Occurrences{% endblock %}
6 | {% block page_id %}allOccurrences{% endblock %}
7 |
8 | {% block content %}
9 |
10 | {% endblock %}
--------------------------------------------------------------------------------
/neonion/templates/base_modify.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Modify Document Meta Data{% endblock %}
6 | {% block page_id %}Modify Document Meta Data{% endblock %}
7 |
8 | {% block content %}
9 |
10 |
28 |
29 | {% for error in errors %}
30 | {{error}}
31 | {% endfor %}
32 |
33 |
34 |
35 | {% csrf_token %}
36 |
37 |
38 |
39 |
40 |
41 |
42 | {% endblock %}
43 |
--------------------------------------------------------------------------------
/neonion/templates/base_settings.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Settings{% endblock %}
6 | {% block page_id %}settings{% endblock %}
7 |
8 | {% block content %}
9 |
10 |
11 |
16 |
17 |
18 |
23 |
24 | {% endblock %}
--------------------------------------------------------------------------------
/neonion/templates/base_vocabulary.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Vocabulary{% endblock %}
6 | {% block page_id %}vocabulary{% endblock %}
7 |
8 | {% block content %}
9 |
10 |
11 |
21 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
33 |
34 |
35 |
38 |
39 |
40 |
41 |
42 | {% endblock %}
43 |
44 | {% block scripts %}
45 | {% endblock %}
--------------------------------------------------------------------------------
/neonion/templates/query.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Query{% endblock %}
6 |
7 | {% block content %}
8 |
9 | {% endblock %}
10 |
11 | {% block scripts %}
12 |
13 |
14 | {% endblock %}
--------------------------------------------------------------------------------
/neonion/templates/workbench.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Workbench{% endblock %}
6 | {% block page_id %}workbench{% endblock %}
7 |
8 | {% block content %}
9 |
10 |
11 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {% endblock %}
--------------------------------------------------------------------------------
/neonion/templates/workspace.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}Documents{% endblock %}
6 |
7 | {% block content %}
8 |
9 |
10 |
20 |
21 |
22 |
23 |
27 |
28 |
29 |
33 |
34 |
35 |
39 |
40 |
41 |
42 | {% endblock %}
--------------------------------------------------------------------------------
/neonion/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/neonion/templatetags/__init__.py
--------------------------------------------------------------------------------
/neonion/templatetags/custom_filters.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | from django import template
4 | from django.utils.html import mark_safe
5 |
6 | register = template.Library()
7 |
8 |
9 | @register.filter
10 | def toJSON(value):
11 | return mark_safe(json.dumps(value))
12 |
--------------------------------------------------------------------------------
/neonion/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from django.core.urlresolvers import reverse
3 | from accounts.tests import create_test_user
4 | from documents.tests import create_test_document
5 | from neonion import views
6 |
7 |
8 | class ViewTestCase(TestCase):
9 |
10 | def setUp(self):
11 | # create test user
12 | self.test_user = create_test_user()
13 |
14 | # create test document
15 | self.test_document = create_test_document()
16 |
17 | def test_neonion_views(self):
18 | self.assertTrue(self.client.login(email='test@neonin.org', password='tester'))
19 |
20 | # annotator - success
21 | response = self.client.get(reverse(views.render_annotator, args=[self.test_document.id]))
22 | self.assertEqual(response.status_code, 200)
23 |
24 | # annotator - fail
25 | response = self.client.get(reverse(views.render_annotator, args=[-1]))
26 | self.assertEqual(response.status_code, 404)
27 |
28 | # home
29 | response = self.client.get(reverse(views.render_home))
30 | self.assertEqual(response.status_code, 200)
31 |
32 | # my annotations
33 | response = self.client.get(reverse(views.annotations))
34 | self.assertEqual(response.status_code, 200)
35 |
36 | # accounts
37 | response = self.client.get(reverse(views.accounts_management))
38 | self.assertEqual(response.status_code, 200)
39 |
40 | # query
41 | response = self.client.get(reverse(views.render_query))
42 | self.assertEqual(response.status_code, 200)
43 |
44 | # import
45 | response = self.client.get(reverse(views.import_document))
46 | self.assertEqual(response.status_code, 200)
47 |
48 | # settings
49 | response = self.client.get(reverse(views.render_settings))
50 | self.assertEqual(response.status_code, 200)
--------------------------------------------------------------------------------
/neonion/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import include, url
2 | from django.contrib import admin
3 | from django.contrib.staticfiles.urls import staticfiles_urlpatterns
4 |
5 | admin.autodiscover()
6 |
7 | urlpatterns = [
8 | url(r'^$', 'neonion.views.render_home'),
9 | url(r'^annotations/$', 'neonion.views.annotations'),
10 | url(r'^annotation_occurrences$', 'neonion.views.annotation_occurrences'),
11 | url(r'^annotation_documents$', 'neonion.views.annotation_documents'),
12 | url(r'^import/$', 'neonion.views.import_document'),
13 | url(r'^modify/(?P.+)$', 'neonion.views.modify_document'),
14 | url(r'^vocabulary/$', 'neonion.views.render_vocabulary'),
15 | url(r'^settings/$', 'neonion.views.render_settings'),
16 | url(r'^query$', 'neonion.views.render_query'),
17 | url(r'^workbench$', 'neonion.views.render_workbench'),
18 |
19 | url(r'^management/?$', 'neonion.views.accounts_management'),
20 |
21 | url(r'^annotator/(?P.+)/(?P.+)$', 'neonion.views.render_annotator'),
22 |
23 | url(r'^api/', include('api.urls')),
24 | url(r'^store/', include('store.urls')),
25 | url(r'^accounts/', include('accounts.urls')),
26 | url(r'^documents/', include('documents.urls')),
27 | url(r'^endpoint/', include('endpoint.urls')),
28 |
29 | # wikidata application
30 | url(r'^wikidata/', include('wikidata.urls')),
31 |
32 |
33 | # Django rest
34 | url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
35 | ]
36 |
37 | urlpatterns += staticfiles_urlpatterns()
38 | #urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
39 |
--------------------------------------------------------------------------------
/neonion/views.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 | from django.shortcuts import render_to_response
3 | from django.template import RequestContext
4 | from django.contrib.auth.decorators import login_required
5 | from documents.models import Document
6 | from django.shortcuts import get_object_or_404
7 |
8 |
9 | # Create your views here.
10 | @login_required
11 | def render_home(request):
12 | return render_to_response('workspace.html', context_instance=RequestContext(request))
13 |
14 |
15 | @login_required
16 | def render_annotator(request, group_pk, document_pk):
17 | get_object_or_404(Document, id=document_pk)
18 |
19 | data = {
20 | 'group_pk': group_pk,
21 | 'document_pk': document_pk,
22 | }
23 | return render_to_response('annotator.html', data, context_instance=RequestContext(request))
24 |
25 |
26 | @login_required
27 | def annotations(request):
28 | return render_to_response('base_annotations.html', context_instance=RequestContext(request))
29 |
30 |
31 | @login_required
32 | def annotation_occurrences(request):
33 | return render_to_response('base_annotations_occurrences.html', context_instance=RequestContext(request))
34 |
35 |
36 | @login_required
37 | def annotation_documents(request):
38 | return render_to_response('base_annotations_documents.html', context_instance=RequestContext(request))
39 |
40 |
41 | @login_required
42 | def render_vocabulary(request):
43 | return render_to_response('base_vocabulary.html', context_instance=RequestContext(request))
44 |
45 |
46 | @login_required
47 | def render_settings(request):
48 | return render_to_response('base_settings.html', context_instance=RequestContext(request))
49 |
50 |
51 | @login_required
52 | def accounts_management(request):
53 | return render_to_response('accounts_management.html', context_instance=RequestContext(request))
54 |
55 |
56 | @login_required
57 | def render_query(request):
58 | return render_to_response('query.html', context_instance=RequestContext(request))
59 |
60 |
61 | @login_required
62 | def render_workbench(request):
63 | return render_to_response('workbench.html', context_instance=RequestContext(request))
64 |
65 |
66 | @login_required
67 | def import_document(request):
68 | return render_to_response('base_import.html', context_instance=RequestContext(request))
69 |
70 | @login_required
71 | def modify_document(request,document_pk):
72 | if Document.objects.filter(id=document_pk).exists():
73 | document = Document.objects.get(id=document_pk)
74 | return render_to_response('base_modify.html', context_instance=RequestContext(request, {"doc_id" : document_pk,"doc" : document}))
75 | return render_to_response("/",context_instance=RequestContext(request))
76 |
77 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Django==1.8.19
2 | djangorestframework==3.2.3
3 | django-pipeline==1.5.1
4 | requests==2.20.0
5 | elasticsearch==6.0.0
6 | enum34==1.0.4
7 | SPARQLWrapper==1.6.4
8 | beautifulsoup4==4.3.2
9 | pywikibot==3.0.20180204
10 | six==1.10.0
11 | packaging==16.8
12 | appdirs==1.4.3
13 |
--------------------------------------------------------------------------------
/settings/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/settings/__init__.py
--------------------------------------------------------------------------------
/settings/demo.py:
--------------------------------------------------------------------------------
1 | from settings.default import *
2 |
3 | # neonion specific
4 | DEFAULT_USER_ACTIVE_STATE = True
5 | ELASTICSEARCH_INDEX = "neonion-demo"
--------------------------------------------------------------------------------
/settings/development.py:
--------------------------------------------------------------------------------
1 | from settings.default import *
2 |
3 | # neonion specific
4 | DEFAULT_USER_ACTIVE_STATE = True
5 |
6 | # # settings for serialization to triple store
7 | # ENDPOINT_ENABLED = False
8 | # ENDPOINT = 'http://localhost:8080/openrdf-sesame/repositories/neonion'
9 | # ENDPOINT_UPDATE = 'http://localhost:8080/openrdf-sesame/repositories/neonion/statements'
10 | #
11 | # # settings for NER service
12 | # NER_SERVICE_ENABLED = False
13 | # NER_SERVICE_URL = 'http://localhost:5000'
14 |
15 | # set environment
16 | DEBUG = True
17 |
--------------------------------------------------------------------------------
/settings/docker.py:
--------------------------------------------------------------------------------
1 | # neonion specific
2 | DEFAULT_USER_ACTIVE_STATE = True
3 |
--------------------------------------------------------------------------------
/settings/production.py:
--------------------------------------------------------------------------------
1 | from settings.default import *
2 |
3 | STATIC_ROOT = "/var/www/neonion/static/"
4 |
5 | # neonion specific
6 | DEFAULT_USER_ACTIVE_STATE = False
7 |
--------------------------------------------------------------------------------
/settings/test.py:
--------------------------------------------------------------------------------
1 | # neonion specific
2 | DEFAULT_USER_ACTIVE_STATE = True
3 |
--------------------------------------------------------------------------------
/store/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/store/__init__.py
--------------------------------------------------------------------------------
/store/decorators.py:
--------------------------------------------------------------------------------
1 | from accounts.models import WorkingGroup
2 | from documents.models import Document
3 | from django.http import HttpResponseForbidden
4 |
5 |
6 | def require_group_permission(view_func, group_key='group_pk', document_key='document_pk'):
7 | """Requires user membership in the groups passed in."""
8 | def _decorated(view, request, *args, **kwargs):
9 | # check if the group is not private
10 | if kwargs[group_key] != request.user.email:
11 | group = WorkingGroup.objects.get(pk=kwargs[group_key])
12 | document = Document.objects.get(pk=kwargs[document_key])
13 |
14 | # check if the user is entitled in the group and the group contains the document
15 | if request.user in group.members.all() and document in group.documents.all():
16 | return view_func(view, request, *args, **kwargs)
17 | else:
18 | return HttpResponseForbidden()
19 | else:
20 | return view_func(view, request, *args, **kwargs)
21 |
22 | return _decorated
23 |
--------------------------------------------------------------------------------
/store/logging/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/store/logging/__init__.py
--------------------------------------------------------------------------------
/store/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 | from store import views
3 |
4 | urlpatterns = [
5 | # AnnotationStore API
6 | url(r'^$', 'store.views.root'),
7 | url(r'^search$', 'store.views.search'),
8 |
9 | url(r'^(?P.+)/(?P.+)/annotations$', views.AnnotationListView.as_view()),
10 | url(r'^(?P.+)/(?P.+)/annotations/(?P.+)$', views.AnnotationDetailView.as_view()),
11 | url(r'^(?P.+)/(?P.+)/search$', views.SearchView.as_view()),
12 | ]
13 |
--------------------------------------------------------------------------------
/wikidata/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FUB-HCC/neonion/f2007a7cde80cf8ed93d64f870aef9b2d0bd1bde/wikidata/__init__.py
--------------------------------------------------------------------------------
/wikidata/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | # Create your models here.
4 |
--------------------------------------------------------------------------------
/wikidata/static/js/annotator/annotator.neonion.wikidata.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | "use strict";
3 |
4 |
5 | Annotator.Plugin.neonion.prototype.widgets['wikidataLiveEntitySearch'] = function (scope, options) {
6 | var factory = {};
7 |
8 | factory.load = function () {
9 |
10 | // overwrite local endpoint called for entity search
11 | scope.options.lookup = {
12 | prefix: '/wikidata',
13 | urls: {
14 | search: "/itemsearch"
15 | }
16 | };
17 |
18 | scope.annotator.subscribe('annotationEditorShown', function (editor, annotation) {
19 |
20 | console.log(annotation);
21 | console.log(scope.options);
22 |
23 | });
24 |
25 | scope.annotator.subscribe('annotationEditorHidden', function () {
26 |
27 |
28 | });
29 |
30 | };
31 |
32 | return factory;
33 |
34 | }
35 | })();
36 |
--------------------------------------------------------------------------------
/wikidata/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 |
3 |
4 | urlpatterns = [
5 | url(r'^itemsearch/(?P.*)/(?P.*)/(?P.*)$', 'wikidata.views.search_typed_items'),
6 | ]
7 |
--------------------------------------------------------------------------------
/wsgi_demo.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for neonion project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 | from django.core.wsgi import get_wsgi_application
12 |
13 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.demo")
14 |
15 | application = get_wsgi_application()
16 |
--------------------------------------------------------------------------------
/wsgi_dev.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for neonion project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 | from django.core.wsgi import get_wsgi_application
12 |
13 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.development")
14 |
15 | application = get_wsgi_application()
16 |
--------------------------------------------------------------------------------
/wsgi_production.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for neonion project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 | from django.core.wsgi import get_wsgi_application
12 |
13 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.production")
14 |
15 | application = get_wsgi_application()
--------------------------------------------------------------------------------
/wsgi_test.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for neonion project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 | from django.core.wsgi import get_wsgi_application
12 |
13 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.test")
14 |
15 | application = get_wsgi_application()
16 |
--------------------------------------------------------------------------------