├── .gitignore ├── README.md ├── Vagrantfile ├── ansible └── deployment │ ├── roles │ ├── common │ │ └── tasks │ │ │ └── main.yml │ ├── dbserver │ │ └── tasks │ │ │ └── main.yaml │ ├── geoserver │ │ ├── tasks │ │ │ └── main.yml │ │ └── templates │ │ │ ├── geoserver_supervisor.conf.j2 │ │ │ └── tomcat_users.xml.j2 │ ├── hadoopserver │ │ ├── tasks │ │ │ ├── basic_server_config.yaml │ │ │ ├── configure_hadoop_files.yaml │ │ │ ├── download_and_extract_hadoop.yaml │ │ │ ├── install_java.yaml │ │ │ ├── main.yaml │ │ │ └── start_hadoop.yaml │ │ └── templates │ │ │ ├── core-site.xml.j2 │ │ │ ├── create_id_rsa.sh.j2 │ │ │ ├── format_hadoop_and_start_for_the_first_time.sh.j2 │ │ │ ├── hadoop-env.sh.j2 │ │ │ ├── hdfs-site.xml.j2 │ │ │ ├── mapred-site.xml.j2 │ │ │ └── yarn-site.xml.j2 │ ├── hiveserver │ │ ├── tasks │ │ │ ├── basic_server_config.yaml │ │ │ ├── configure_hive_files.yaml │ │ │ ├── download_and_extract_hive.yaml │ │ │ ├── install_java.yaml │ │ │ └── main.yaml │ │ └── templates │ │ │ └── hive-env.sh.j2 │ ├── rserver │ │ └── tasks │ │ │ └── main.yml │ └── webserver │ │ ├── tasks │ │ ├── basic_server_config.yaml │ │ ├── collect_django_static_and_fix_permissions.yaml │ │ ├── create_directory_and_config_files_for_webservers.yaml │ │ ├── create_django_project.yaml │ │ ├── create_venv.yaml │ │ ├── link_nginx_file_and_start_webservers.yaml │ │ ├── main.yml │ │ ├── migrate_new_django_project.yaml │ │ └── old.yaml │ │ └── templates │ │ ├── bash_profile.j2 │ │ ├── draft_django_settings.py.j2 │ │ ├── gunicorn.service.j2 │ │ ├── gunicorn.socket.j2 │ │ ├── nginx.j2 │ │ └── package.json │ ├── site.retry │ ├── site.yml │ └── vars.yml ├── ballista ├── ballista │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── static │ ├── admin │ ├── css │ │ ├── autocomplete.css │ │ ├── base.css │ │ ├── changelists.css │ │ ├── dashboard.css │ │ ├── fonts.css │ │ ├── forms.css │ │ ├── login.css │ │ ├── responsive.css │ │ ├── responsive_rtl.css │ │ ├── rtl.css │ │ ├── vendor │ │ │ └── select2 │ │ │ │ ├── LICENSE-SELECT2.md │ │ │ │ ├── select2.css │ │ │ │ └── select2.min.css │ │ └── widgets.css │ ├── fonts │ │ ├── LICENSE.txt │ │ ├── README.txt │ │ ├── Roboto-Bold-webfont.woff │ │ ├── Roboto-Light-webfont.woff │ │ └── Roboto-Regular-webfont.woff │ ├── img │ │ ├── LICENSE │ │ ├── README.txt │ │ ├── calendar-icons.svg │ │ ├── gis │ │ │ ├── move_vertex_off.svg │ │ │ └── move_vertex_on.svg │ │ ├── icon-addlink.svg │ │ ├── icon-alert.svg │ │ ├── icon-calendar.svg │ │ ├── icon-changelink.svg │ │ ├── icon-clock.svg │ │ ├── icon-deletelink.svg │ │ ├── icon-no.svg │ │ ├── icon-unknown-alt.svg │ │ ├── icon-unknown.svg │ │ ├── icon-viewlink.svg │ │ ├── icon-yes.svg │ │ ├── inline-delete.svg │ │ ├── search.svg │ │ ├── selector-icons.svg │ │ ├── sorting-icons.svg │ │ ├── tooltag-add.svg │ │ └── tooltag-arrowright.svg │ └── js │ │ ├── SelectBox.js │ │ ├── SelectFilter2.js │ │ ├── actions.js │ │ ├── actions.min.js │ │ ├── admin │ │ ├── DateTimeShortcuts.js │ │ └── RelatedObjectLookups.js │ │ ├── autocomplete.js │ │ ├── calendar.js │ │ ├── cancel.js │ │ ├── change_form.js │ │ ├── collapse.js │ │ ├── collapse.min.js │ │ ├── core.js │ │ ├── inlines.js │ │ ├── inlines.min.js │ │ ├── jquery.init.js │ │ ├── popup_response.js │ │ ├── prepopulate.js │ │ ├── prepopulate.min.js │ │ ├── prepopulate_init.js │ │ ├── timeparse.js │ │ ├── urlify.js │ │ └── vendor │ │ ├── jquery │ │ ├── LICENSE.txt │ │ ├── jquery.js │ │ └── jquery.min.js │ │ ├── select2 │ │ ├── LICENSE.md │ │ ├── i18n │ │ │ ├── ar.js │ │ │ ├── az.js │ │ │ ├── bg.js │ │ │ ├── ca.js │ │ │ ├── cs.js │ │ │ ├── da.js │ │ │ ├── de.js │ │ │ ├── el.js │ │ │ ├── en.js │ │ │ ├── es.js │ │ │ ├── et.js │ │ │ ├── eu.js │ │ │ ├── fa.js │ │ │ ├── fi.js │ │ │ ├── fr.js │ │ │ ├── gl.js │ │ │ ├── he.js │ │ │ ├── hi.js │ │ │ ├── hr.js │ │ │ ├── hu.js │ │ │ ├── id.js │ │ │ ├── is.js │ │ │ ├── it.js │ │ │ ├── ja.js │ │ │ ├── km.js │ │ │ ├── ko.js │ │ │ ├── lt.js │ │ │ ├── lv.js │ │ │ ├── mk.js │ │ │ ├── ms.js │ │ │ ├── nb.js │ │ │ ├── nl.js │ │ │ ├── pl.js │ │ │ ├── pt-BR.js │ │ │ ├── pt.js │ │ │ ├── ro.js │ │ │ ├── ru.js │ │ │ ├── sk.js │ │ │ ├── sr-Cyrl.js │ │ │ ├── sr.js │ │ │ ├── sv.js │ │ │ ├── th.js │ │ │ ├── tr.js │ │ │ ├── uk.js │ │ │ ├── vi.js │ │ │ ├── zh-CN.js │ │ │ └── zh-TW.js │ │ ├── select2.full.js │ │ └── select2.full.min.js │ │ └── xregexp │ │ ├── LICENSE.txt │ │ ├── xregexp.js │ │ └── xregexp.min.js │ └── gis │ ├── css │ └── ol3.css │ ├── img │ ├── draw_line_off.svg │ ├── draw_line_on.svg │ ├── draw_point_off.svg │ ├── draw_point_on.svg │ ├── draw_polygon_off.svg │ └── draw_polygon_on.svg │ └── js │ └── OLMapWidget.js └── resources ├── python_requirements.txt ├── r-requirements.R └── spf13-script.sh /README.md: -------------------------------------------------------------------------------- 1 | # Welcome To The Generic Django Development Environment 2 | 3 | This is a GIS project template written by Dheeraj Chand of [Clarity and Rigour](http://www.clarityandrigour.com) (email: first_initial+last_name AT clarity and rigour DOT COM, strip the spaces and do the subs). 4 | This template: 5 | 6 | 1. Is written in [Python](http://www.python.org), 7 | 2. Uses [PostgreSQL](http://www.postgresql.org) as the database, with [PostGIS](http://www.postgis.net) extensions, 8 | 3. Uses [GeoDjango](http://www.geodjango.org) as the application framework and 9 | 4. Uses [R](http://www.r-project.org) for computations. 10 | 5. Uses [Hadoop](http://hadoop.apache.org) and [Hive](https://hive.apache.org) 11 | 12 | ## The purpose of this project. 13 | 14 | This project allows you to have a new Django project from scratch via Ansible + Vagrant. The main components are: 15 | 16 | - [Ubuntu 18.04](http://www.ubuntu.com) 17 | - [Python 3.6.7](http://www.python.org) 18 | - [PostgreSQL 10.8](http://www.postgresql.org) 19 | - [PostGIS 2](http://www.postgis.net) 20 | - [GeoServer](http:///www.geoserver.org) 21 | - [nginx](http://www.nginx.org) 22 | - [gunicorn](http://gunicorn-docs.readthedocs.org/en/19.3/) 23 | - [R](http://www.r-project.org) 24 | - [npm](http://www.npmjs.com) 25 | 26 | ### Sources 27 | 28 | Nothing happens in a vacuum. I got a lot of help. Here are some of the references I used that warrant special mention. The general inspiration came from [Wercker](http://blog.wercker.com/2013/11/25/django-16-part3.html) and the set of instructions that I modified slightly came from [Digital Ocean](https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-16-04?comment=47694). Specific problems I found either by googling for Ansible techniques, asking Jonathan for help or by using the following links: 29 | 30 | 31 | 1. [Installing JRE 7 in Vagrant](https://gist.github.com/arturaz/5243940) 32 | 2. [Setting the Java Home variable correctly](https://www.digitalocean.com/community/tutorials/how-to-install-java-on-ubuntu-with-apt-get) 33 | 3. [Installing Tomcat for GeoServer](https://www.digitalocean.com/community/tutorials/how-to-install-apache-tomcat-7-on-ubuntu-14-04-via-apt-get) 34 | 4. [Hadoop](https://www.tutorialspoint.com/hadoop/hadoop_enviornment_setup.htm) 35 | 5. [Hive](https://www.tutorialspoint.com/hive/hive_installation.htm) 36 | 6. [Getting Django to Work In Ubuntu 18](https://www.cloudbooklet.com/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04-in-google-cloud/) 37 | 38 | ## Repo Contents 39 | 40 | 1. Vagrantfile + Ansible Playbook for virtual machine config. Ansible inspiration from [this project], and configuration instructions modified from 41 | 2. Code for a generic Django 2.10 project at the top level of the repo, which you can configure to your liking. 42 | 43 | ## Host Environment 44 | 45 | ### Install VirtualBox 46 | https://www.virtualbox.org/wiki/Downloads 47 | 48 | ### Install Vagrant 49 | https://www.vagrantup.com/downloads.html 50 | 51 | ### Install Ansible 52 | http://docs.ansible.com/intro_installation.html 53 | 54 | ## Development Environment 55 | Make sure git doesn't change line endings: 56 | ``` 57 | git config --global core.autocrlf input 58 | ``` 59 | 60 | ## Startup 61 | You will need to edit the vars.yaml file. This file contains the project name, user names and passwords. Please set them according to your preferences. ***THIS IS NON-DISCRETIONARY. Tomcat will not run correctly without this.*** 62 | 63 | Start VM with Vagrant. This will use Ansible to install dependencies and run a script to set up virtual environment and pip requirements. 64 | ``` 65 | vagrant up --provision 66 | ``` 67 | Open browser to http://localhost:8080 to check that everything works. It should show the Django start page that tells you to configure URL's. 68 | 69 | You will also need to create your own Django superuser for the project. You can do that by: 70 | 71 | ``` 72 | vagrant ssh 73 | sudo su 74 | cd /opt/venv/$projectname 75 | source /opt/venv/bin/activate 76 | python manage.py createsuperuser 77 | ``` 78 | 79 | or by using the manage.py tool in your IDE. [PyCharm](https://www.jetbrains.com/pycharm/) has that built in! 80 | 81 | To configure your GeoServer, you will need to go to [http://localhost:8081/geoserver](http://localhost:8081/geoserver) and log in. The default credentials are *admin* , *geoserver*. From there, you can do whatever you need. 82 | 83 | ## Management 84 | If you make any changes to Vagrantfile, requirements.txt, or default.pp: 85 | ``` 86 | vagrant reload --provision 87 | ``` 88 | If you need to shut down or reboot your laptop, or just want to stop the VM: 89 | ``` 90 | vagrant halt 91 | ``` 92 | To log onto VM: 93 | ``` 94 | vagrant ssh 95 | ``` 96 | To get rid of a VM if you are done or it was corrupted: 97 | ``` 98 | vagrant destroy 99 | ``` 100 | If you a change is made to Vagrantfile or requirements.txt, do 101 | ``` 102 | vagrant reload -–provision 103 | ``` -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure("2") do |config| 5 | 6 | config.vm.box = "ubuntu/bionic64" 7 | config.vm.provider :virtualbox do |v| 8 | host = RbConfig::CONFIG['host_os'] 9 | if host =~ /darwin/ 10 | mem = `sysctl -n hw.memsize`.to_i / 1024 11 | elsif host =~ /linux/ 12 | mem = `grep 'MemTotal' /proc/meminfo | sed -e 's/MemTotal://' -e 's kB//'`.to_i 13 | elsif host =~ /mswin|mingw|cygwin/ 14 | mem = `wmic computersystem Get TotalPhysicalMemory`.split[1].to_i / 1024 15 | end 16 | 17 | mem = mem / 1024 / 4 18 | v.customize ["modifyvm", :id, "--memory", mem] 19 | 20 | # basic networking 21 | config.vm.network :private_network, ip: "192.168.33.10" 22 | 23 | # Basic web port for Django 24 | config.vm.network "forwarded_port", guest: 80, host: 8080 25 | 26 | # This is port for GeoServer, which is normally 8080 when installed locally, so I am offsetting by 1 27 | config.vm.network "forwarded_port", guest: 8080, host: 8081 28 | 29 | # Hadoop ports, which I am similarly offsetting by 1 30 | 31 | 32 | config.vm.network "forwarded_port", guest: 9870, host: 9871 # hadoop port 33 | config.vm.network "forwarded_port", guest: 8088, host: 8089 # Resource Manager 34 | 35 | config.ssh.forward_x11 = true 36 | 37 | config.vm.hostname = "vagrant-gisvm" 38 | config.vm.synced_folder ".", "/vagrant", 39 | owner: "vagrant" 40 | 41 | config.vm.provision "ansible" do |ansible| 42 | ansible.playbook = "ansible/deployment/site.yml" 43 | ansible.verbose = "vv" 44 | ansible.extra_vars = { 45 | ansible_python_interpreter: "/usr/bin/python3", 46 | } 47 | 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /ansible/deployment/roles/common/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: set locale to {{locale}} 3 | command: /usr/sbin/update-locale LANG={{locale}} LC_ALL={{locale}} 4 | become: true 5 | 6 | - name: ensure aptitude is present 7 | apt: 8 | pkg: aptitude 9 | state: present 10 | install_recommends: yes 11 | update-cache: yes 12 | become: true 13 | 14 | - name: update pre-installed packages after installing aptitude 15 | become: true 16 | apt: upgrade=full update_cache=yes 17 | 18 | - name: install apt-file 19 | apt: 20 | pkg: apt-file 21 | state: present 22 | install_recommends: yes 23 | become: true 24 | 25 | - name: install required system packages. 26 | apt: 27 | pkg: "{{ packages }}" 28 | state: present 29 | install_recommends: yes 30 | update-cache: yes 31 | become: true 32 | vars: 33 | - packages: 34 | - apt-file 35 | - build-essential 36 | - default-jdk 37 | - python3-setuptools 38 | - python3-pip 39 | - python3-apt 40 | - python3-pycurl 41 | - python3-software-properties 42 | - python3-virtualenv 43 | - python3-dev 44 | - vim 45 | - libpq-dev 46 | - python3-psycopg2 47 | - git 48 | - gdal-bin 49 | - postgresql 50 | - postgresql-contrib 51 | - postgis 52 | - postgis-doc 53 | 54 | - name: do upgrades to newly installed packages 55 | apt: upgrade=yes 56 | become: true 57 | 58 | - name: fix /etc/environment file 59 | lineinfile: 60 | path: /etc/environment 61 | regexp: '^PATH' 62 | line: 'PATH="$HOME/bin:$HOME/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"' 63 | become: true 64 | 65 | - name: remove a src directory if it exists 66 | file: 67 | path: /vagrant/resources/src 68 | state: absent 69 | become: true 70 | 71 | - name: create a src directory for downloaded code 72 | file: 73 | path: /vagrant/resources/src 74 | state: directory 75 | owner: "{{ remote_web_user }}" 76 | mode: 0775 77 | register: srcdirectoryexists 78 | ignore_errors: true 79 | when: srcdirectoryexists.changed 80 | become: true 81 | 82 | - name: create a directory for hadoop expansion 83 | file: 84 | path: /vagrant/resources/src/hadoop 85 | state: directory 86 | owner: "{{ remote_web_user }}" 87 | mode: 0775 88 | ignore_errors: true 89 | become: true 90 | 91 | - name: create a directory for hive expansion 92 | file: 93 | path: /vagrant/resources/src/hive 94 | state: directory 95 | owner: "{{ remote_web_user }}" 96 | mode: 0775 97 | ignore_errors: true 98 | become: true -------------------------------------------------------------------------------- /ansible/deployment/roles/dbserver/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: ensure postgres is installed 3 | apt: 4 | name: ['postgresql', 'postgresql-contrib', 'postgis', 'postgis-doc', 'python3-psycopg2'] 5 | state: present 6 | install_recommends: yes 7 | update-cache: yes 8 | become: true 9 | 10 | - name: do upgrades to newly installed postgresql and postgis packages 11 | apt: upgrade=dist 12 | become: true 13 | 14 | - name: create postgresql user 15 | postgresql_user: 16 | user: "{{dbuser}}" 17 | password: "{{dbpassword}}" 18 | role_attr_flags: LOGIN,CREATEDB,SUPERUSER 19 | become_user: postgres 20 | 21 | - name: ensure database is created 22 | postgresql_db: 23 | db: "{{dbname}}" 24 | login_password: "{{dbpassword}}" 25 | encoding: 'UTF-8' 26 | lc_ctype: 'en_US.UTF-8' 27 | lc_collate: 'en_US.UTF-8' 28 | become_user: postgres 29 | register: db_created 30 | 31 | - name: create postgis extension in db 32 | command: psql -c "CREATE EXTENSION postgis; CREATE EXTENSION postgis_topology; CREATE EXTENSION fuzzystrmatch; CREATE EXTENSION postgis_tiger_geocoder;" --dbname={{dbname}} 33 | become_user: postgres 34 | when: db_created.changed 35 | 36 | - name: ensure user has access to database 37 | become_user: postgres 38 | postgresql_user: 39 | db: "{{dbname}}" 40 | user: "{{dbuser}}" 41 | password: "{{dbpassword}}" 42 | priv: ALL 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /ansible/deployment/roles/geoserver/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # basic system tasks 4 | 5 | - name: set locale to {{locale}} 6 | action: command /usr/sbin/update-locale LANG={{locale}} LC_ALL={{locale}} 7 | become: true 8 | 9 | - name: get tomcat packages for geoserver 10 | apt: 11 | name: ['build-essential','unzip', 'tomcat7', 'tomcat7-admin', 'tomcat7-docs', 'tomcat7-admin', 'tomcat7-examples', 'git', 'ant', 'default-jdk'] 12 | state: latest 13 | install_recommends: yes 14 | update_cache: yes 15 | become: true 16 | 17 | # just tomcat things 18 | 19 | - name: create tomcat_users.xml from template 20 | template: 21 | src: tomcat_users.xml.j2 22 | dest: /etc/tomcat7/tomcat-users.xml 23 | owner: root 24 | group: root 25 | mode: 0644 26 | become: true 27 | 28 | - name: restart tomcat 29 | service: name=tomcat7 state=restarted 30 | become: true 31 | 32 | - name: get the geoserver .war 33 | get_url: 34 | url: http://sourceforge.net/projects/geoserver/files/GeoServer/2.15.0/geoserver-2.15.0-war.zip 35 | dest: /vagrant/resources/src/geoserver.war.zip 36 | force: no 37 | validate_certs: no 38 | ignore_errors: yes 39 | register: geoserverwarexists 40 | when: geoserverwarexists is not defined 41 | 42 | - name: unzip the geoserver .war file into its destination directory 43 | unarchive: 44 | src: /vagrant/resources/src/geoserver.war.zip 45 | dest: /var/lib/tomcat7/webapps 46 | remote_src: yes 47 | become: true 48 | when: geoserverwarexists 49 | 50 | - name: restart tomcat 51 | service: name=tomcat7 state=restarted 52 | become: true 53 | 54 | -------------------------------------------------------------------------------- /ansible/deployment/roles/geoserver/templates/geoserver_supervisor.conf.j2: -------------------------------------------------------------------------------- 1 | [program:geoserver] 2 | command = /usr/local/geoserver/bin/startup.sh 3 | autostart = true 4 | autorestart = true 5 | redirect_stderr = true 6 | environment=JAVA_HOME="/usr/lib/jvm/java-7-oracle",GEOSERVER_HOME="/usr/local/geoserver" -------------------------------------------------------------------------------- /ansible/deployment/roles/geoserver/templates/tomcat_users.xml.j2: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/tasks/basic_server_config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # basic system tasks 3 | 4 | - name: set locale to {{locale}} 5 | action: command /usr/sbin/update-locale LANG={{locale}} LC_ALL={{locale}} 6 | become: true 7 | 8 | - name: get ubuntu packages for hadoop 9 | apt: 10 | name: ['build-essential', 'unzip', 'git', 'default-jdk', 'ssh', 'pdsh'] 11 | state: latest 12 | install_recommends: yes 13 | update_cache: yes 14 | become: true 15 | 16 | - name: Make sure that we have a 'hadoop' group 17 | group: 18 | name=hadoop 19 | state=present 20 | 21 | - name: Make sure that we have a 'wheel' group 22 | group: 23 | name=wheel 24 | state=present 25 | 26 | - name: Make sure that vagrant user belongs to correct groups 27 | user: 28 | name: vagrant 29 | groups: wheel,hadoop 30 | append: yes 31 | 32 | - name: create an id_rsa script from a template 33 | template: 34 | src: create_id_rsa.sh.j2 35 | dest: /home/vagrant/create_id_rsa.sh 36 | mode: "u+rwx" 37 | 38 | - name: execute the create rsa script 39 | command: sh /home/vagrant/create_id_rsa.sh 40 | become: true 41 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/tasks/configure_hadoop_files.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # add values to hadoop configuration files 3 | 4 | - name: add parameters to /etc/environment 5 | blockinfile: 6 | path: /home/vagrant/.bashrc 7 | insertafter: EOF 8 | block: |2 9 | export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 10 | export HADOOP_HOME=/usr/local/hadoop 11 | export HADOOP_MAPRED_HOME=$HADOOP_HOME 12 | export HADOOP_COMMON_HOME=$HADOOP_HOME 13 | export HADOOP_HDFS_HOME=$HADOOP_HOME 14 | export YARN_HOME=$HADOOP_HOME 15 | export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native 16 | export HDFS_NAMENODE_USER="vagrant" 17 | export HDFS_DATANODE_USER="vagrant" 18 | export HDFS_SECONDARYNAMENODE_USER="vagrant" 19 | export YARN_RESOURCEMANAGER_USER="vagrant" 20 | export YARN_NODEMANAGER_USER="vagrant" 21 | export PDSH_RCMD_TYPE=ssh 22 | PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin 23 | become: true 24 | 25 | - name: add parameters to hadoop-env.sh via template 26 | template: 27 | src: hadoop-env.sh.j2 28 | dest: /usr/local/hadoop/etc/hadoop/hadoop-env.sh 29 | owner: vagrant 30 | group: hadoop 31 | become: true 32 | 33 | - name: add parameters to core-site.xml via template 34 | template: 35 | src: core-site.xml.j2 36 | dest: /usr/local/hadoop/etc/hadoop/core-site.xml 37 | owner: vagrant 38 | group: hadoop 39 | become: true 40 | 41 | - name: add parameters to hdfs-site.xml via template 42 | template: 43 | src: hdfs-site.xml.j2 44 | dest: /usr/local/hadoop/etc/hadoop/hdfs-site.xml 45 | owner: vagrant 46 | group: hadoop 47 | become: true 48 | 49 | - name: add parameters to yarn-site.xml via template 50 | template: 51 | src: yarn-site.xml.j2 52 | dest: /usr/local/hadoop/etc/hadoop/yarn-site.xml 53 | owner: vagrant 54 | group: hadoop 55 | become: true 56 | 57 | - name: add parameters to mapred-site.xml via template 58 | template: 59 | src: mapred-site.xml.j2 60 | dest: /usr/local/hadoop/etc/hadoop/mapred-site.xml 61 | owner: vagrant 62 | group: hadoop 63 | become: true -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/tasks/download_and_extract_hadoop.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # download the Hadoop 3.1.1 directory 3 | 4 | - name: get the Hadoop 3.1.1 code 5 | get_url: 6 | url: http://mirror.olnevhost.net/pub/apache/hadoop/common/hadoop-{{hadoop_version}}/hadoop-{{hadoop_version}}.tar.gz 7 | dest: /vagrant/resources/hadoop.tar.gz 8 | force: no 9 | become: true 10 | ignore_errors: yes 11 | register: hadoopdownloadexists 12 | when: hadoopdownloadexists is not defined 13 | 14 | - name: unarchive the hadoop code 15 | unarchive: 16 | src: /vagrant/resources/hadoop.tar.gz 17 | dest: /vagrant/resources/src/hadoop 18 | group: hadoop 19 | remote_src: yes 20 | become: true 21 | when: hadoopdownloadexists 22 | 23 | - name: create link to /usr/local/hadoop from /resources/src/hadoop 24 | file: 25 | src: /vagrant/resources/src/hadoop/hadoop-3.1.1 26 | dest: /usr/local/hadoop 27 | state: link 28 | owner: vagrant 29 | group: hadoop 30 | ignore_errors: true 31 | become: true -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/tasks/install_java.yaml: -------------------------------------------------------------------------------- 1 | # Get Java ready for Hadoop 2 | 3 | - name: Install add-apt-repostory 4 | become: yes 5 | apt: name=software-properties-common state=latest 6 | 7 | - name: Add Oracle Java Repository 8 | become: yes 9 | apt_repository: 10 | repo: 'ppa:linuxuprising/java' 11 | 12 | - name: Accept Java 11 License 13 | become: yes 14 | debconf: 15 | name: 'oracle-java11-installer' 16 | question: 'shared/accepted-oracle-license-v1-1' 17 | value: 'true' 18 | vtype: 'select' 19 | 20 | - name: Install Oracle Java 11 21 | become: true 22 | apt: 23 | name: ['oracle-java11-installer', 'ca-certificates'] 24 | state: latest 25 | 26 | - name: correct java version selected 27 | alternatives: 28 | name: java 29 | path: "{{java_version_for_alternatives}}" 30 | 31 | - name: correct java compiler version selected 32 | alternatives: 33 | name: javac 34 | path: "{{javac_version_for_alternatives}}" 35 | 36 | - name: set JAVA_HOME variable 37 | lineinfile: 38 | path: /etc/environment 39 | insertafter: EOF 40 | line: 'JAVA_HOME="{{java_home}}"' -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # sequential links to installation instructions 3 | 4 | - include: ./roles/hadoopserver/tasks/basic_server_config.yaml 5 | 6 | - include: ./roles/hadoopserver/tasks/install_java.yaml 7 | 8 | - include: ./roles/hadoopserver/tasks/download_and_extract_hadoop.yaml 9 | 10 | - include: ./roles/hadoopserver/tasks/configure_hadoop_files.yaml 11 | 12 | #- include: ./roles/hadoopserver/tasks/start_hadoop.yaml -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/tasks/start_hadoop.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # initialise and start up hadoop 3 | 4 | - name: create a script to start initialise the hard drive and start hadoop 5 | template: 6 | src: format_hadoop_and_start_for_the_first_time.sh.j2 7 | dest: /home/vagrant/format_hadoop_and_start_for_the_first_time.sh 8 | mode: "u+rwx" 9 | 10 | - name: execute the start hadoop script 11 | shell: source /home/vagrant/format_hadoop_and_start_for_the_first_time.sh 12 | args: 13 | executable: /bin/bash 14 | become: true 15 | 16 | 17 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/templates/core-site.xml.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 18 | 19 | 20 | 21 | fs.default.name 22 | hdfs://localhost:9000 23 | 24 | 25 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/templates/create_id_rsa.sh.j2: -------------------------------------------------------------------------------- 1 | 2 | # https://stackoverflow.com/questions/3659602/automating-enter-keypresses-for-bash-script-generating-ssh-keys 3 | # https://www.unix.com/shell-programming-and-scripting/191559-bash-script-create-rsa-key-pair.html 4 | 5 | yes y | ssh-keygen -f /home/vagrant/.ssh/id_rsa -t rsa -N '' -q 6 | cat /home/vagrant/.ssh/id_rsa.pub >> /home/vagrant/.ssh/authorized_keys 7 | chown -R vagrant:vagrant /home/vagrant/.ssh -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/templates/format_hadoop_and_start_for_the_first_time.sh.j2: -------------------------------------------------------------------------------- 1 | /usr/local/hadoop/bin/hdfs namenode -format 2 | /usr/local/hadoop/sbin/start-dfs.sh && /usr/local/hadoop/sbin/start-yarn.sh 3 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/templates/hdfs-site.xml.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | dfs.replication 23 | 1 24 | 25 | 26 | dfs.name.dir 27 | file:///home/vagrant/hadoopinfra/hdfs/namenode 28 | 29 | 30 | dfs.data.dir 31 | file:///home/vagrant/hadoopinfra/hdfs/datanode 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/templates/mapred-site.xml.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | mapreduce.framework.name 23 | yarn 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hadoopserver/templates/yarn-site.xml.j2: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | 18 | 19 | 20 | yarn.nodemanager.aux-services 21 | mapreduce_shuffle 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hiveserver/tasks/basic_server_config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # basic system tasks 3 | 4 | - name: set locale to {{locale}} 5 | action: command /usr/sbin/update-locale LANG={{locale}} LC_ALL={{locale}} 6 | become: true 7 | 8 | - name: get ubuntu packages for hadoop 9 | apt: 10 | name: ['build-essential', 'unzip', 'git', 'default-jdk', 'ssh', 'pdsh'] 11 | state: latest 12 | install_recommends: yes 13 | update_cache: yes 14 | become: true 15 | 16 | - name: Make sure that we have a 'hive' group 17 | group: 18 | name=hive 19 | state=present 20 | 21 | - name: Make sure that we have a 'wheel' group 22 | group: 23 | name=wheel 24 | state=present 25 | 26 | - name: Make sure that vagrant user belongs to correct groups 27 | user: 28 | name: vagrant 29 | groups: wheel,hive 30 | append: yes 31 | 32 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hiveserver/tasks/configure_hive_files.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # add values to hadoop configuration files 3 | 4 | - name: add parameters to /etc/environment 5 | blockinfile: 6 | path: /home/vagrant/.bashrc 7 | insertafter: EOF 8 | block: |2 9 | export HIVE_HOME=/usr/local/hive 10 | export PATH=$PATH:$HIVE_HOME/bin 11 | export CLASSPATH=$CLASSPATH:/usr/local/hadoop/lib/*:. 12 | export CLASSPATH=$CLASSPATH:/usr/local/hive/lib/*:. 13 | become: true 14 | 15 | - name: add parameters to hive-env.sh via template 16 | template: 17 | src: hadoop-env.sh.j2 18 | dest: /usr/local/hadoop/etc/hadoop/hadoop-env.sh 19 | owner: vagrant 20 | group: hadoop 21 | become: true 22 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hiveserver/tasks/download_and_extract_hive.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # download the hive 3.1.1 directory 3 | 4 | - name: get the hive 3.1.1 code 5 | get_url: 6 | url: http://mirrors.advancedhosters.com/apache/hive/hive-{{hive_version}}/apache-hive-{{hive_version}}-bin.tar.gz 7 | dest: /vagrant/resources/hive.tar.gz 8 | force: no 9 | become: true 10 | ignore_errors: yes 11 | register: hivedownloadexists 12 | when: hivedownloadexists is not defined 13 | 14 | - name: unarchive the hive code 15 | unarchive: 16 | src: /vagrant/resources/hive.tar.gz 17 | dest: /vagrant/resources/src/hive 18 | owner: vagrant 19 | group: hive 20 | remote_src: yes 21 | become: true 22 | when: hivedownloadexists 23 | 24 | - name: create link to /usr/local/hive from /resources/src/hive 25 | file: 26 | src: /vagrant/resources/src/hive/apache-hive-{{hive_version}}-bin 27 | dest: /usr/local/hive 28 | state: link 29 | owner: vagrant 30 | group: hive 31 | ignore_errors: true 32 | become: true -------------------------------------------------------------------------------- /ansible/deployment/roles/hiveserver/tasks/install_java.yaml: -------------------------------------------------------------------------------- 1 | # Get Java ready for Hadoop 2 | 3 | - name: Install add-apt-repostory 4 | become: yes 5 | apt: name=software-properties-common state=latest 6 | 7 | - name: Add Oracle Java Repository 8 | become: yes 9 | apt_repository: 10 | repo: 'ppa:webupd8team/java' 11 | 12 | - name: Accept Java 8 License 13 | become: yes 14 | debconf: 15 | name: 'oracle-java8-installer' 16 | question: 'shared/accepted-oracle-license-v1-1' 17 | value: 'true' 18 | vtype: 'select' 19 | 20 | - name: Install Oracle Java 8 21 | become: yes 22 | apt: 23 | name: ['oracle-java8-installer', 'ca-certificates', 'oracle-java8-set-default'] 24 | state: latest 25 | 26 | - name: correct java version selected 27 | alternatives: 28 | name: java 29 | path: "{{java_version_for_alternatives}}" 30 | 31 | - name: set JAVA_HOME variable 32 | lineinfile: 33 | path: /etc/environment 34 | insertafter: EOF 35 | line: 'JAVA_HOME="{{java_home}}"' -------------------------------------------------------------------------------- /ansible/deployment/roles/hiveserver/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # sequential links to installation instructions 3 | 4 | - include: ./roles/hiveserver/tasks/basic_server_config.yaml 5 | 6 | - include: ./roles/hiveserver/tasks/install_java.yaml 7 | 8 | - include: ./roles/hiveserver/tasks/download_and_extract_hive.yaml 9 | 10 | - include: ./roles/hiveserver/tasks/configure_hive_files.yaml 11 | -------------------------------------------------------------------------------- /ansible/deployment/roles/hiveserver/templates/hive-env.sh.j2: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Set Hive and Hadoop environment variables here. These variables can be used 18 | # to control the execution of Hive. It should be used by admins to configure 19 | # the Hive installation (so that users do not have to set environment variables 20 | # or set command line parameters to get correct behavior). 21 | # 22 | # The hive service being invoked (CLI etc.) is available via the environment 23 | # variable SERVICE 24 | 25 | 26 | # Hive Client memory usage can be an issue if a large number of clients 27 | # are running at the same time. The flags below have been useful in 28 | # reducing memory usage: 29 | # 30 | # if [ "$SERVICE" = "cli" ]; then 31 | # if [ -z "$DEBUG" ]; then 32 | # export HADOOP_OPTS="$HADOOP_OPTS -XX:NewRatio=12 -Xms10m -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:+UseParNewGC -XX:-UseGCOverheadLimit" 33 | # else 34 | # export HADOOP_OPTS="$HADOOP_OPTS -XX:NewRatio=12 -Xms10m -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:-UseGCOverheadLimit" 35 | # fi 36 | # fi 37 | 38 | # The heap size of the jvm stared by hive shell script can be controlled via: 39 | # 40 | # export HADOOP_HEAPSIZE=1024 41 | # 42 | # Larger heap size may be required when running queries over large number of files or partitions. 43 | # By default hive shell scripts use a heap size of 256 (MB). Larger heap size would also be 44 | # appropriate for hive server. 45 | 46 | 47 | # Set HADOOP_HOME to point to a specific hadoop install directory 48 | export HADOOP_HOME=/usr/local/hadoop 49 | 50 | # Hive Configuration Directory can be controlled by: 51 | # export HIVE_CONF_DIR= 52 | 53 | # Folder containing extra libraries required for hive compilation/execution can be controlled by: 54 | # export HIVE_AUX_JARS_PATH= 55 | -------------------------------------------------------------------------------- /ansible/deployment/roles/rserver/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # basic system tasks 4 | 5 | - name: set locale to {{locale}} 6 | action: command /usr/sbin/update-locale LANG={{locale}} LC_ALL={{locale}} 7 | become: true 8 | 9 | # manual workaround to add CRAN repository this is ugly fix later 10 | 11 | - name: manually add CRAN repository to apt 12 | shell: echo "deb http://cran.rstudio.com/bin/linux/ubuntu xenial/" | sudo tee -a /etc/apt/sources.list 13 | become: true 14 | 15 | - name: add CRAN repository key 16 | apt_key: keyserver=keyserver.ubuntu.com id=E084DAB9 state=present 17 | become: true 18 | 19 | - name: get r-server packages 20 | apt: name={{item}} state=latest install_recommends=yes update_cache=yes 21 | sudo: yes 22 | ignore_errors: yes 23 | with_items: 24 | - build-essential 25 | - libgdal-dev 26 | - libgl1-mesa-dev 27 | - libglu1-mesa-dev 28 | - libproj-dev 29 | - netcdf-bin 30 | - openbox 31 | - r-base 32 | - r-base-dev 33 | - tk8.6-dev 34 | - tmux 35 | - unzip 36 | - xauth 37 | - grass 38 | 39 | # a different way to install R packages http://adamj.eu/tech/2014/07/19/installing-and-removing-r-packages-with-ansible/ 40 | 41 | - name: r - packages <-- core 42 | command: > 43 | Rscript --slave --no-save --no-restore-history -e "if (! ('{{ item }}' %in% installed.packages()[,'Package'])) { install.packages(pkgs='{{ item }}', dependencies=TRUE, repos=c('http://cran.rstudio.com/')); print('Added'); } else { print('Already installed'); }" 44 | register: r_result 45 | failed_when: "r_result.rc != 0 or 'had non-zero exit status' in r_result.stderr" 46 | changed_when: "'Added' in r_result.stdout" 47 | sudo: yes 48 | ignore_errors: yes 49 | with_items: 50 | - classInt 51 | - DCluster 52 | - deldir 53 | - geoR 54 | - gstat 55 | - maptools 56 | - ncdf 57 | - plyr 58 | - RandomFields 59 | - raster 60 | - RColorBrewer 61 | - rgdal 62 | - rgeos 63 | - RSAGA 64 | - sp 65 | - spatstat 66 | - spdep 67 | - spgrass6 68 | - splancs 69 | 70 | - name: r - packages <-- optional 71 | command: > 72 | Rscript --slave --no-save --no-restore-history -e "if (! ('{{ item }}' %in% installed.packages()[,'Package'])) { install.packages(pkgs='{{ item }}', dependencies=TRUE, repos=c('http://cran.rstudio.com/')); print('Added'); } else { print('Already installed'); }" 73 | register: r_result 74 | failed_when: "r_result.rc != 0 or 'had non-zero exit status' in r_result.stderr" 75 | changed_when: "'Added' in r_result.stdout" 76 | sudo: yes 77 | ignore_errors: yes 78 | with_items: 79 | - ade4 80 | - adehabitat 81 | - adehabitatHR 82 | - adehabitatHS 83 | - adehabitatLT 84 | - adehabitatMA 85 | - ads 86 | - akima 87 | - ash 88 | - aspace 89 | - automap 90 | - CircSpatial 91 | - clustTool 92 | - CompRandFld 93 | - constrainedKriging 94 | - cshapes 95 | - diseasemapping 96 | - DSpat 97 | - ecespa 98 | - fields 99 | - FieldSim 100 | - gdistance 101 | - Geneland 102 | - GEOmap 103 | - geomapdata 104 | - geonames 105 | - geoRglm 106 | - geosphere 107 | - GeoXp 108 | - glmmBUGS 109 | - gmaps 110 | - gmt 111 | - Guerry 112 | - hdeco 113 | - intamap 114 | - mapdata 115 | - mapproj 116 | - maps 117 | - MarkedPointProcess 118 | - MBA 119 | - ModelMap 120 | - ncf 121 | - nlme 122 | - pastecs 123 | - PBSmapping 124 | - PBSmodelling 125 | - psgp 126 | - ramps 127 | - RArcInfo 128 | - regress 129 | - RgoogleMaps 130 | - RPyGeo 131 | - RSurvey 132 | - rworldmap 133 | - sgeostat 134 | - shapefiles 135 | - sparr 136 | - spatcounts 137 | - spatgraphs 138 | - spatial 139 | - spatialCovariance 140 | - SpatialExtremes 141 | - spatialkernel 142 | - spatialsegregation 143 | - spBayes 144 | - spcosa 145 | - spgwr 146 | - sphet 147 | - spsurvey 148 | - SQLiteMap 149 | - Stem 150 | - tgp 151 | - trip 152 | - tripack 153 | - tripEstimation 154 | - UScensus2000 155 | - vardiag 156 | - vegan 157 | 158 | - name: r - packages <-- non-spatial 159 | command: > 160 | Rscript --slave --no-save --no-restore-history -e "if (! ('{{ item }}' %in% installed.packages()[,'Package'])) { install.packages(pkgs='{{ item }}', dependencies=TRUE, repos=c('http://cran.rstudio.com/')); print('Added'); } else { print('Already installed'); }" 161 | register: r_result 162 | failed_when: "r_result.rc != 0 or 'had non-zero exit status' in r_result.stderr" 163 | changed_when: "'Added' in r_result.stdout" 164 | sudo: yes 165 | with_items: 166 | - RPostgreSQL 167 | - RSQLite 168 | - RODBC 169 | 170 | #- name: second round of R packages installation check 171 | # command: Rscript --slave --no-save --no-restore-history /vagrant/r-requirements.R 172 | # sudo: yes 173 | 174 | -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/tasks/basic_server_config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: set locale to {{locale}} 3 | command: /usr/sbin/update-locale LANG={{locale}} LC_ALL={{locale}} 4 | become: true 5 | 6 | - name: install required system packages. 7 | apt: 8 | name: ['build-essential', 'cython', 'gdal-bin', 'gfortran', 'libgdal-dev', 'libgeos-dev', 'libpq-dev', 'nginx', 'nodejs', 'nodejs-dev', 'npm', 'virtualenv', 'postgresql', 'postgresql-contrib', 'python3-apt', 'python3-dev', 'python3-pip', 'python3-pycurl', 'python3-setuptools','python3-software-properties',] 9 | state: present 10 | update-cache: yes 11 | install_recommends: yes 12 | become: true 13 | 14 | - name: do upgrades to newly installed packages 15 | apt: 16 | upgrade: full 17 | become: true 18 | 19 | - name: enable ufw incoming and outgoing 20 | ufw: 21 | state: disabled 22 | become: true 23 | 24 | - name: add vagrant user to www-data group 25 | user: 26 | name: "{{ remote_web_user }}" 27 | groups: "sudo, {{ remote_web_group }}" 28 | append: yes 29 | 30 | - name: create ~/.bash_profile to make life easier 31 | template: 32 | src: bash_profile.j2 33 | dest: "/home/{{ remote_web_user }}/.bash_profile" 34 | owner: vagrant 35 | group: vagrant 36 | -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/tasks/collect_django_static_and_fix_permissions.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Run Django collectstatic 3 | shell: "cd {{django_dir}}; {{ venv_python }} manage.py collectstatic" 4 | when: create_new_project == True 5 | 6 | - name: fix Django directory permissions 7 | file: 8 | state: directory 9 | owner: "{{ remote_web_user }}" 10 | group: "{{ remote_web_group }}" 11 | recurse: yes 12 | path: "{{ django_dir }}" 13 | become: true -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/tasks/create_directory_and_config_files_for_webservers.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #- name: create a directory for the socket files 3 | # file: 4 | # state: directory 5 | # owner: "{{ remote_web_user }}" 6 | # group: "{{ remote_web_group }}" 7 | # path: "{{ socket_dir }}" 8 | # mode: 777 9 | # become: true 10 | # when: create_new_project == true 11 | 12 | - name: create a socket file from a template 13 | template: 14 | src: gunicorn.socket.j2 15 | dest: "{{ socket_path }}" 16 | owner: "{{ remote_web_user }}" 17 | group: "{{ remote_web_group }}" 18 | become: true 19 | when: create_new_project == true 20 | 21 | - name: create a gunicorn system file 22 | template: 23 | src: gunicorn.service.j2 24 | dest: /etc/systemd/system/gunicorn.service 25 | owner: root 26 | group: root 27 | become: true 28 | when: create_new_project == true 29 | 30 | - name: create an nginx service file 31 | template: 32 | src: nginx.j2 33 | dest: "/etc/nginx/sites-available/{{ project_name }}" 34 | become: true 35 | when: create_new_project == true -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/tasks/create_django_project.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: if there is a django project in /vagrant, delete it 3 | file: 4 | path: "{{ django_dir }}" 5 | state: absent 6 | become: true 7 | ignore_errors: yes 8 | when: create_new_project == True 9 | 10 | - name: create a new django project in the /home/vagrant directory using the new virtualenv 11 | shell: "cd /vagrant/; {{ venv_path }}/bin/django-admin.py startproject {{ project_name }}" 12 | when: create_new_project == True 13 | 14 | - name: remove the settings.py from the new django project 15 | file: 16 | dest: "/vagrant/{{ project_name }}/{{ project_name }}/settings.py" 17 | state: absent 18 | become: true 19 | when: create_new_project == True 20 | 21 | - name: create the new settings.py file using the template (fills in database settings and sets static_root) 22 | template: 23 | src: draft_django_settings.py.j2 24 | dest: "{{ django_dir }}/{{ project_name }}/settings.py" 25 | owner: vagrant 26 | group: vagrant 27 | mode: 0644 28 | when: create_new_project == True 29 | 30 | -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/tasks/create_venv.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: delete a virtualenv if it exists 4 | shell: "rm -rf {{ venv_path }}" 5 | ignore_errors: yes 6 | become: true 7 | 8 | - name: install python requirements 9 | pip: 10 | requirements: /vagrant/resources/python_requirements.txt 11 | virtualenv: "{{ venv_path }}" 12 | virtualenv_python: /usr/bin/python3 13 | state: latest 14 | become: true -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/tasks/link_nginx_file_and_start_webservers.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: link the sites-available to sites-enabled 3 | file: > 4 | src=/etc/nginx/sites-available/{{ project_name }} 5 | dest=/etc/nginx/sites-enabled/{{ project_name }} 6 | owner=root 7 | group=root 8 | state=link 9 | become: true 10 | when: create_new_project == True 11 | 12 | - name: reload systemctl files 13 | shell: "sudo systemctl daemon-reload" 14 | 15 | - name: start gunicorn in service 16 | shell: "sudo systemctl restart gunicorn" 17 | 18 | - name: start nginx in service 19 | shell: "sudo systemctl restart nginx" -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: ./roles/webserver/tasks/basic_server_config.yaml 4 | 5 | - include: ./roles/webserver/tasks/create_venv.yaml 6 | 7 | - include: ./roles/webserver/tasks/create_django_project.yaml 8 | 9 | - include: ./roles/webserver/tasks/migrate_new_django_project.yaml 10 | 11 | - include: ./roles/webserver/tasks/collect_django_static_and_fix_permissions.yaml 12 | 13 | - include: ./roles/webserver/tasks/create_directory_and_config_files_for_webservers.yaml 14 | 15 | - include: ./roles/webserver/tasks/link_nginx_file_and_start_webservers.yaml -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/tasks/migrate_new_django_project.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Run Django database makemigrations 4 | shell: "cd {{django_dir}}; {{ venv_python }} manage.py makemigrations" 5 | when: create_new_project == True 6 | 7 | - name: Run Django database migrate 8 | shell: "cd {{django_dir}}; {{ venv_python }} manage.py migrate" 9 | when: create_new_project == True 10 | 11 | -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/tasks/old.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: set locale to {{locale}} 4 | command: /usr/sbin/update-locale LANG={{locale}} LC_ALL={{locale}} 5 | become: true 6 | 7 | - name: install required system packages. 8 | action: apt pkg={{item}} state=installed update-cache=yes install_recommends=yes 9 | become: true 10 | with_items: 11 | - build-essential 12 | - cython 13 | - gdal-bin 14 | - gfortran 15 | - libgdal-dev 16 | - libgeos-dev 17 | - libpq-dev 18 | - nginx 19 | - nodejs-legacy 20 | - npm 21 | - postgresql 22 | - postgresql-contrib 23 | - python-apt 24 | - python-dev 25 | - python-pip 26 | - python-pycurl 27 | - python-setuptools 28 | - python-software-properties 29 | - python-virtualenv 30 | - supervisor 31 | - vim 32 | 33 | - name: do upgrades to newly installed packages 34 | apt: upgrade=full 35 | become: true 36 | 37 | - name: enable ufw incoming and outgoing 38 | ufw: > 39 | state=disabled 40 | become: true 41 | 42 | - name: delete a virtualenv if it exists 43 | shell: rm -rf {{ venv_path }} 44 | ignore_errors: yes 45 | become: true 46 | 47 | - name: create python virtualenv in /home/vagrant/project_directory with requirements 48 | pip: > 49 | virtualenv={{ venv_path }} 50 | virtualenv_command=/usr/bin/virtualenv 51 | virtualenv_site_packages=yes 52 | requirements=/vagrant/resources/python_requirements.txt 53 | state=latest 54 | become: true 55 | 56 | - name: if there is a django project in /vagrant, delete it 57 | file: > 58 | path=/vagrant/{{project_name}} 59 | state=absent 60 | become: true 61 | ignore_errors: yes 62 | when: create_new_project == True 63 | 64 | - name: create a new django project in the /home/vagrant directory using the new virtualenv 65 | shell: "cd /vagrant/; {{ venv_path }}/bin/django-admin.py startproject {{ project_name }}" 66 | when: create_new_project == True 67 | 68 | - name: remove the settings.py from the new django project 69 | file: > 70 | dest=/vagrant/{{ project_name }}/{{ project_name }}/settings.py 71 | state=absent 72 | become: true 73 | when: create_new_project == True 74 | 75 | - name: create the new settings.py file using the template (fills in database settings and sets static_root) 76 | template: > 77 | src=draft_django_settings.py.j2 78 | dest={{ django_dir }}/{{ project_name }}/settings.py 79 | owner=vagrant 80 | group=vagrant 81 | mode=0644 82 | when: create_new_project == True 83 | 84 | - name: Run Django database makemigrations 85 | django_manage: > 86 | command="makemigrations" 87 | app_path=/vagrant/{{ project_name }} 88 | virtualenv={{ venv_path }} 89 | when: create_new_project == True 90 | 91 | - name: Run Django database migrate 92 | django_manage: > 93 | command=migrate 94 | app_path=/vagrant/{{ project_name }} 95 | virtualenv={{ venv_path }} 96 | when: create_new_project == True 97 | 98 | - name: Run Django collectstatic 99 | django_manage: > 100 | command=collectstatic 101 | app_path=/vagrant/{{ project_name }} 102 | virtualenv={{ venv_path }} 103 | when: create_new_project == True 104 | 105 | - name: fix Django directory permissions 106 | file: > 107 | state=directory 108 | owner=vagrant 109 | group=www-data 110 | recurse=yes 111 | path={{ django_dir }} 112 | become: true 113 | 114 | - name: create a directory for the socket files 115 | file: > 116 | state=directory 117 | owner=vagrant 118 | group=www-data 119 | path={{ socket_dir }} 120 | mode=777 121 | become: true 122 | when: create_new_project == True 123 | 124 | - name: create a gunicorn system file 125 | template: > 126 | src=gunicorn.service.j2 127 | dest=/etc/systemd/system/gunicorn.service 128 | owner=root 129 | group=root 130 | become: true 131 | when: create_new_project == True 132 | 133 | - name: create an nginx service file 134 | template: > 135 | src=nginx.j2 136 | dest=/etc/nginx/sites-available/{{ project_name }} 137 | become: true 138 | when: create_new_project == True 139 | 140 | - name: link the sites-available to sites-enabled 141 | file: > 142 | src=/etc/nginx/sites-available/{{ project_name }} 143 | dest=/etc/nginx/sites-enabled/{{ project_name }} 144 | owner=root 145 | group=root 146 | state=link 147 | become: true 148 | when: create_new_project == True 149 | 150 | - name: start gunicorn in systemctl 151 | shell: "sudo systemctl start gunicorn" 152 | become: true 153 | 154 | - name: start nginx is systemctl 155 | shell: "sudo systemctl start nginx" 156 | become: true 157 | 158 | -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/templates/bash_profile.j2: -------------------------------------------------------------------------------- 1 | cd {{ django_dir }} 2 | source {{ venv_path }}/bin/activate 3 | -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/templates/draft_django_settings.py.j2: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for {{project_name}} project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.2.1. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.2/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.2/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'z6@=^c$d+w$nxzga7rwvxm(xlxoj(u)udeov9_+4(7dayh-7eq' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = ['localhost'] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'django.contrib.gis', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = '{{project_name}}.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = '{{project_name}}.wsgi.application' 72 | 73 | # Database 74 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 75 | 76 | DATABASES = { 77 | 'default': { 78 | 'ENGINE': 'django.contrib.gis.db.backends.postgis', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 79 | 'NAME': '{{dbname}}', # Or path to database file if using sqlite3. 80 | 'USER': '{{dbuser}}', # Not used with sqlite3. 81 | 'PASSWORD': '{{dbpassword}}', # Not used with sqlite3. 82 | 'HOST': 'localhost', # Set to empty string for localhost. Not used with sqlite3. 83 | 'PORT': '5432', # Set to empty string for default. Not used with sqlite3. 84 | } 85 | } 86 | 87 | 88 | # Password validation 89 | # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators 90 | 91 | AUTH_PASSWORD_VALIDATORS = [ 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 100 | }, 101 | { 102 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 103 | }, 104 | ] 105 | 106 | 107 | # Internationalization 108 | # https://docs.djangoproject.com/en/2.2/topics/i18n/ 109 | 110 | LANGUAGE_CODE = 'en-us' 111 | 112 | TIME_ZONE = 'UTC' 113 | 114 | USE_I18N = True 115 | 116 | USE_L10N = True 117 | 118 | USE_TZ = True 119 | 120 | 121 | # Static files (CSS, JavaScript, Images) 122 | # https://docs.djangoproject.com/en/2.2/howto/static-files/ 123 | 124 | STATIC_URL = '/static/' 125 | STATIC_ROOT = os.path.join(BASE_DIR, 'static/') 126 | -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/templates/gunicorn.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=gunicorn daemon 3 | Requires=gunicorn.socket 4 | After=network.target 5 | 6 | [Service] 7 | User={{ remote_web_user }} 8 | Group={{ remote_web_group }} 9 | WorkingDirectory={{ django_dir }} 10 | ExecStart={{ venv_path }}/bin/gunicorn \ 11 | --access-logfile - \ 12 | --workers 3 \ 13 | --bind unix:/run/gunicorn.sock \ 14 | {{ project_name }}.wsgi:application 15 | 16 | [Install] 17 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/templates/gunicorn.socket.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=gunicorn socket 3 | 4 | [Socket] 5 | ListenStream=/run/gunicorn.sock 6 | 7 | [Install] 8 | WantedBy=sockets.target -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/templates/nginx.j2: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | 5 | server_name localhost 127.0.0.1 0.0.0.0; 6 | 7 | location = /favicon.ico { 8 | access_log off; 9 | log_not_found off; 10 | } 11 | 12 | location /static/ { 13 | root {{ django_dir }}; 14 | } 15 | 16 | location / { 17 | include proxy_params; 18 | proxy_pass http://unix:/run/gunicorn.sock; 19 | } 20 | } -------------------------------------------------------------------------------- /ansible/deployment/roles/webserver/templates/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chicago_crimes", 3 | "version": "0.0.0", 4 | "description": "a viewer for crimes in chicago", 5 | "main": "index.js", 6 | "dependencies": { 7 | "openlayers": "~3.13.0", 8 | "d3": "~3.5.0", 9 | "jquery": "~2.2.0", 10 | "lodash": "~4.2.0", 11 | "bootstrap": "~3.3.6", 12 | "topojson": "~1.6" 13 | }, 14 | "devDependencies": {}, 15 | "scripts": { 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "author": "dheeraj chand ", 19 | "license": "BSD-2-Clause" 20 | } 21 | -------------------------------------------------------------------------------- /ansible/deployment/site.retry: -------------------------------------------------------------------------------- 1 | default 2 | -------------------------------------------------------------------------------- /ansible/deployment/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | sudo : yes 4 | vars_files: 5 | - vars.yml 6 | roles: 7 | - common 8 | - dbserver 9 | # - geoserver 10 | - webserver 11 | # #- hadoopserver 12 | # #- hiveserver 13 | # - rserver 14 | 15 | 16 | -------------------------------------------------------------------------------- /ansible/deployment/vars.yml: -------------------------------------------------------------------------------- 1 | project_name: ballista 2 | remote_web_user: vagrant 3 | remote_web_group: www-data 4 | venv_path: "/vagrant/projectenv" 5 | venv_python: "{{ venv_path }}/bin/python" 6 | gunicorn_path: "{{ venv_path }}/bin/gunicorn" 7 | socket_path: "/etc/systemd/system/gunicorn.socket" 8 | source_location: "/vagrant/" 9 | source_location_auto_remove : false 10 | django_dir: "/vagrant/{{ project_name }}" 11 | dbuser: "{{ project_name }}" 12 | dbname: "{{ project_name }}" 13 | dbpassword: "87a10d441346d53d55e788c755c3a598" 14 | locale: en_US.UTF-8 15 | tomcat_admin_user: mohanthecat 16 | tomcat_admin_password: tunasteak 17 | create_new_project: true 18 | create_new_static: true 19 | geoserver_version: "2.15.0" 20 | hadoop_version: "3.1.1" 21 | hive_version: "3.1.1" 22 | java_version_for_alternatives: "/usr/lib/jvm/java-11-oracle/bin/java" 23 | javac_version_for_alternatives: "/usr/lib/jvm/java-11-oracle/bin/javac" 24 | java_home: "/usr/lib/jvm/java-11-oracle/bin/java" 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /ballista/ballista/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dheerajchand/ubuntu-django-nginx-ansible/db03d7d053ed91a622d341858ab3cf7023adf7dd/ballista/ballista/__init__.py -------------------------------------------------------------------------------- /ballista/ballista/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for ballista project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.2.1. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.2/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.2/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'z6@=^c$d+w$nxzga7rwvxm(xlxoj(u)udeov9_+4(7dayh-7eq' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = ['localhost'] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'django.contrib.gis', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'ballista.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'ballista.wsgi.application' 72 | 73 | # Database 74 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 75 | 76 | DATABASES = { 77 | 'default': { 78 | 'ENGINE': 'django.contrib.gis.db.backends.postgis', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 79 | 'NAME': 'ballista', # Or path to database file if using sqlite3. 80 | 'USER': 'ballista', # Not used with sqlite3. 81 | 'PASSWORD': '87a10d441346d53d55e788c755c3a598', # Not used with sqlite3. 82 | 'HOST': 'localhost', # Set to empty string for localhost. Not used with sqlite3. 83 | 'PORT': '5432', # Set to empty string for default. Not used with sqlite3. 84 | } 85 | } 86 | 87 | 88 | # Password validation 89 | # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators 90 | 91 | AUTH_PASSWORD_VALIDATORS = [ 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 100 | }, 101 | { 102 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 103 | }, 104 | ] 105 | 106 | 107 | # Internationalization 108 | # https://docs.djangoproject.com/en/2.2/topics/i18n/ 109 | 110 | LANGUAGE_CODE = 'en-us' 111 | 112 | TIME_ZONE = 'UTC' 113 | 114 | USE_I18N = True 115 | 116 | USE_L10N = True 117 | 118 | USE_TZ = True 119 | 120 | 121 | # Static files (CSS, JavaScript, Images) 122 | # https://docs.djangoproject.com/en/2.2/howto/static-files/ 123 | 124 | STATIC_URL = '/static/' 125 | STATIC_ROOT = os.path.join(BASE_DIR, 'static/') 126 | -------------------------------------------------------------------------------- /ballista/ballista/urls.py: -------------------------------------------------------------------------------- 1 | """ballista URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.2/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path 18 | 19 | urlpatterns = [ 20 | path('admin/', admin.site.urls), 21 | ] 22 | -------------------------------------------------------------------------------- /ballista/ballista/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for ballista 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/2.2/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ballista.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /ballista/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ballista.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /ballista/static/admin/css/changelists.css: -------------------------------------------------------------------------------- 1 | /* CHANGELISTS */ 2 | 3 | #changelist { 4 | position: relative; 5 | width: 100%; 6 | } 7 | 8 | #changelist table { 9 | width: 100%; 10 | } 11 | 12 | .change-list .hiddenfields { display:none; } 13 | 14 | .change-list .filtered table { 15 | border-right: none; 16 | } 17 | 18 | .change-list .filtered { 19 | min-height: 400px; 20 | } 21 | 22 | .change-list .filtered .results, .change-list .filtered .paginator, 23 | .filtered #toolbar, .filtered div.xfull { 24 | margin-right: 280px; 25 | width: auto; 26 | } 27 | 28 | .change-list .filtered table tbody th { 29 | padding-right: 1em; 30 | } 31 | 32 | #changelist-form .results { 33 | overflow-x: auto; 34 | } 35 | 36 | #changelist .toplinks { 37 | border-bottom: 1px solid #ddd; 38 | } 39 | 40 | #changelist .paginator { 41 | color: #666; 42 | border-bottom: 1px solid #eee; 43 | background: #fff; 44 | overflow: hidden; 45 | } 46 | 47 | /* CHANGELIST TABLES */ 48 | 49 | #changelist table thead th { 50 | padding: 0; 51 | white-space: nowrap; 52 | vertical-align: middle; 53 | } 54 | 55 | #changelist table thead th.action-checkbox-column { 56 | width: 1.5em; 57 | text-align: center; 58 | } 59 | 60 | #changelist table tbody td.action-checkbox { 61 | text-align: center; 62 | } 63 | 64 | #changelist table tfoot { 65 | color: #666; 66 | } 67 | 68 | /* TOOLBAR */ 69 | 70 | #changelist #toolbar { 71 | padding: 8px 10px; 72 | margin-bottom: 15px; 73 | border-top: 1px solid #eee; 74 | border-bottom: 1px solid #eee; 75 | background: #f8f8f8; 76 | color: #666; 77 | } 78 | 79 | #changelist #toolbar form input { 80 | border-radius: 4px; 81 | font-size: 14px; 82 | padding: 5px; 83 | color: #333; 84 | } 85 | 86 | #changelist #toolbar form #searchbar { 87 | height: 19px; 88 | border: 1px solid #ccc; 89 | padding: 2px 5px; 90 | margin: 0; 91 | vertical-align: top; 92 | font-size: 13px; 93 | } 94 | 95 | #changelist #toolbar form #searchbar:focus { 96 | border-color: #999; 97 | } 98 | 99 | #changelist #toolbar form input[type="submit"] { 100 | border: 1px solid #ccc; 101 | padding: 2px 10px; 102 | margin: 0; 103 | vertical-align: middle; 104 | background: #fff; 105 | box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; 106 | cursor: pointer; 107 | color: #333; 108 | } 109 | 110 | #changelist #toolbar form input[type="submit"]:focus, 111 | #changelist #toolbar form input[type="submit"]:hover { 112 | border-color: #999; 113 | } 114 | 115 | #changelist #changelist-search img { 116 | vertical-align: middle; 117 | margin-right: 4px; 118 | } 119 | 120 | /* FILTER COLUMN */ 121 | 122 | #changelist-filter { 123 | position: absolute; 124 | top: 0; 125 | right: 0; 126 | z-index: 1000; 127 | width: 240px; 128 | background: #f8f8f8; 129 | border-left: none; 130 | margin: 0; 131 | } 132 | 133 | #changelist-filter h2 { 134 | font-size: 14px; 135 | text-transform: uppercase; 136 | letter-spacing: 0.5px; 137 | padding: 5px 15px; 138 | margin-bottom: 12px; 139 | border-bottom: none; 140 | } 141 | 142 | #changelist-filter h3 { 143 | font-weight: 400; 144 | font-size: 14px; 145 | padding: 0 15px; 146 | margin-bottom: 10px; 147 | } 148 | 149 | #changelist-filter ul { 150 | margin: 5px 0; 151 | padding: 0 15px 15px; 152 | border-bottom: 1px solid #eaeaea; 153 | } 154 | 155 | #changelist-filter ul:last-child { 156 | border-bottom: none; 157 | padding-bottom: none; 158 | } 159 | 160 | #changelist-filter li { 161 | list-style-type: none; 162 | margin-left: 0; 163 | padding-left: 0; 164 | } 165 | 166 | #changelist-filter a { 167 | display: block; 168 | color: #999; 169 | text-overflow: ellipsis; 170 | overflow-x: hidden; 171 | } 172 | 173 | #changelist-filter li.selected { 174 | border-left: 5px solid #eaeaea; 175 | padding-left: 10px; 176 | margin-left: -15px; 177 | } 178 | 179 | #changelist-filter li.selected a { 180 | color: #5b80b2; 181 | } 182 | 183 | #changelist-filter a:focus, #changelist-filter a:hover, 184 | #changelist-filter li.selected a:focus, 185 | #changelist-filter li.selected a:hover { 186 | color: #036; 187 | } 188 | 189 | /* DATE DRILLDOWN */ 190 | 191 | .change-list ul.toplinks { 192 | display: block; 193 | float: left; 194 | padding: 0; 195 | margin: 0; 196 | width: 100%; 197 | } 198 | 199 | .change-list ul.toplinks li { 200 | padding: 3px 6px; 201 | font-weight: bold; 202 | list-style-type: none; 203 | display: inline-block; 204 | } 205 | 206 | .change-list ul.toplinks .date-back a { 207 | color: #999; 208 | } 209 | 210 | .change-list ul.toplinks .date-back a:focus, 211 | .change-list ul.toplinks .date-back a:hover { 212 | color: #036; 213 | } 214 | 215 | /* PAGINATOR */ 216 | 217 | .paginator { 218 | font-size: 13px; 219 | padding-top: 10px; 220 | padding-bottom: 10px; 221 | line-height: 22px; 222 | margin: 0; 223 | border-top: 1px solid #ddd; 224 | } 225 | 226 | .paginator a:link, .paginator a:visited { 227 | padding: 2px 6px; 228 | background: #79aec8; 229 | text-decoration: none; 230 | color: #fff; 231 | } 232 | 233 | .paginator a.showall { 234 | padding: 0; 235 | border: none; 236 | background: none; 237 | color: #5b80b2; 238 | } 239 | 240 | .paginator a.showall:focus, .paginator a.showall:hover { 241 | background: none; 242 | color: #036; 243 | } 244 | 245 | .paginator .end { 246 | margin-right: 6px; 247 | } 248 | 249 | .paginator .this-page { 250 | padding: 2px 6px; 251 | font-weight: bold; 252 | font-size: 13px; 253 | vertical-align: top; 254 | } 255 | 256 | .paginator a:focus, .paginator a:hover { 257 | color: white; 258 | background: #036; 259 | } 260 | 261 | /* ACTIONS */ 262 | 263 | .filtered .actions { 264 | margin-right: 280px; 265 | border-right: none; 266 | } 267 | 268 | #changelist table input { 269 | margin: 0; 270 | vertical-align: baseline; 271 | } 272 | 273 | #changelist table tbody tr.selected { 274 | background-color: #FFFFCC; 275 | } 276 | 277 | #changelist .actions { 278 | padding: 10px; 279 | background: #fff; 280 | border-top: none; 281 | border-bottom: none; 282 | line-height: 24px; 283 | color: #999; 284 | } 285 | 286 | #changelist .actions.selected { 287 | background: #fffccf; 288 | border-top: 1px solid #fffee8; 289 | border-bottom: 1px solid #edecd6; 290 | } 291 | 292 | #changelist .actions span.all, 293 | #changelist .actions span.action-counter, 294 | #changelist .actions span.clear, 295 | #changelist .actions span.question { 296 | font-size: 13px; 297 | margin: 0 0.5em; 298 | display: none; 299 | } 300 | 301 | #changelist .actions:last-child { 302 | border-bottom: none; 303 | } 304 | 305 | #changelist .actions select { 306 | vertical-align: top; 307 | height: 24px; 308 | background: none; 309 | color: #000; 310 | border: 1px solid #ccc; 311 | border-radius: 4px; 312 | font-size: 14px; 313 | padding: 0 0 0 4px; 314 | margin: 0; 315 | margin-left: 10px; 316 | } 317 | 318 | #changelist .actions select:focus { 319 | border-color: #999; 320 | } 321 | 322 | #changelist .actions label { 323 | display: inline-block; 324 | vertical-align: middle; 325 | font-size: 13px; 326 | } 327 | 328 | #changelist .actions .button { 329 | font-size: 13px; 330 | border: 1px solid #ccc; 331 | border-radius: 4px; 332 | background: #fff; 333 | box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; 334 | cursor: pointer; 335 | height: 24px; 336 | line-height: 1; 337 | padding: 4px 8px; 338 | margin: 0; 339 | color: #333; 340 | } 341 | 342 | #changelist .actions .button:focus, #changelist .actions .button:hover { 343 | border-color: #999; 344 | } 345 | -------------------------------------------------------------------------------- /ballista/static/admin/css/dashboard.css: -------------------------------------------------------------------------------- 1 | /* DASHBOARD */ 2 | 3 | .dashboard .module table th { 4 | width: 100%; 5 | } 6 | 7 | .dashboard .module table td { 8 | white-space: nowrap; 9 | } 10 | 11 | .dashboard .module table td a { 12 | display: block; 13 | padding-right: .6em; 14 | } 15 | 16 | /* RECENT ACTIONS MODULE */ 17 | 18 | .module ul.actionlist { 19 | margin-left: 0; 20 | } 21 | 22 | ul.actionlist li { 23 | list-style-type: none; 24 | overflow: hidden; 25 | text-overflow: ellipsis; 26 | -o-text-overflow: ellipsis; 27 | } 28 | -------------------------------------------------------------------------------- /ballista/static/admin/css/fonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Roboto'; 3 | src: url('../fonts/Roboto-Bold-webfont.woff'); 4 | font-weight: 700; 5 | font-style: normal; 6 | } 7 | 8 | @font-face { 9 | font-family: 'Roboto'; 10 | src: url('../fonts/Roboto-Regular-webfont.woff'); 11 | font-weight: 400; 12 | font-style: normal; 13 | } 14 | 15 | @font-face { 16 | font-family: 'Roboto'; 17 | src: url('../fonts/Roboto-Light-webfont.woff'); 18 | font-weight: 300; 19 | font-style: normal; 20 | } 21 | -------------------------------------------------------------------------------- /ballista/static/admin/css/login.css: -------------------------------------------------------------------------------- 1 | /* LOGIN FORM */ 2 | 3 | body.login { 4 | background: #f8f8f8; 5 | } 6 | 7 | .login #header { 8 | height: auto; 9 | padding: 15px 16px; 10 | justify-content: center; 11 | } 12 | 13 | .login #header h1 { 14 | font-size: 18px; 15 | } 16 | 17 | .login #header h1 a { 18 | color: #fff; 19 | } 20 | 21 | .login #content { 22 | padding: 20px 20px 0; 23 | } 24 | 25 | .login #container { 26 | background: #fff; 27 | border: 1px solid #eaeaea; 28 | border-radius: 4px; 29 | overflow: hidden; 30 | width: 28em; 31 | min-width: 300px; 32 | margin: 100px auto; 33 | } 34 | 35 | .login #content-main { 36 | width: 100%; 37 | } 38 | 39 | .login .form-row { 40 | padding: 4px 0; 41 | float: left; 42 | width: 100%; 43 | border-bottom: none; 44 | } 45 | 46 | .login .form-row label { 47 | padding-right: 0.5em; 48 | line-height: 2em; 49 | font-size: 1em; 50 | clear: both; 51 | color: #333; 52 | } 53 | 54 | .login .form-row #id_username, .login .form-row #id_password { 55 | clear: both; 56 | padding: 8px; 57 | width: 100%; 58 | -webkit-box-sizing: border-box; 59 | -moz-box-sizing: border-box; 60 | box-sizing: border-box; 61 | } 62 | 63 | .login span.help { 64 | font-size: 10px; 65 | display: block; 66 | } 67 | 68 | .login .submit-row { 69 | clear: both; 70 | padding: 1em 0 0 9.4em; 71 | margin: 0; 72 | border: none; 73 | background: none; 74 | text-align: left; 75 | } 76 | 77 | .login .password-reset-link { 78 | text-align: center; 79 | } 80 | -------------------------------------------------------------------------------- /ballista/static/admin/css/responsive_rtl.css: -------------------------------------------------------------------------------- 1 | /* TABLETS */ 2 | 3 | @media (max-width: 1024px) { 4 | [dir="rtl"] .colMS { 5 | margin-right: 0; 6 | } 7 | 8 | [dir="rtl"] #user-tools { 9 | text-align: right; 10 | } 11 | 12 | [dir="rtl"] #changelist .actions label { 13 | padding-left: 10px; 14 | padding-right: 0; 15 | } 16 | 17 | [dir="rtl"] #changelist .actions select { 18 | margin-left: 0; 19 | margin-right: 15px; 20 | } 21 | 22 | [dir="rtl"] .change-list .filtered .results, 23 | [dir="rtl"] .change-list .filtered .paginator, 24 | [dir="rtl"] .filtered #toolbar, 25 | [dir="rtl"] .filtered div.xfull, 26 | [dir="rtl"] .filtered .actions { 27 | margin-right: 0; 28 | margin-left: 230px; 29 | } 30 | 31 | [dir="rtl"] .inline-group ul.tools a.add, 32 | [dir="rtl"] .inline-group div.add-row a, 33 | [dir="rtl"] .inline-group .tabular tr.add-row td a { 34 | padding: 8px 26px 8px 10px; 35 | background-position: calc(100% - 8px) 9px; 36 | } 37 | 38 | [dir="rtl"] .related-widget-wrapper-link + .selector { 39 | margin-right: 0; 40 | margin-left: 15px; 41 | } 42 | 43 | [dir="rtl"] .selector .selector-filter label { 44 | margin-right: 0; 45 | margin-left: 8px; 46 | } 47 | 48 | [dir="rtl"] .object-tools li { 49 | float: right; 50 | } 51 | 52 | [dir="rtl"] .object-tools li + li { 53 | margin-left: 0; 54 | margin-right: 15px; 55 | } 56 | 57 | [dir="rtl"] .dashboard .module table td a { 58 | padding-left: 0; 59 | padding-right: 16px; 60 | } 61 | } 62 | 63 | /* MOBILE */ 64 | 65 | @media (max-width: 767px) { 66 | [dir="rtl"] .change-list .filtered .results, 67 | [dir="rtl"] .change-list .filtered .paginator, 68 | [dir="rtl"] .filtered #toolbar, 69 | [dir="rtl"] .filtered div.xfull, 70 | [dir="rtl"] .filtered .actions { 71 | margin-left: 0; 72 | } 73 | 74 | [dir="rtl"] .aligned .add-another, 75 | [dir="rtl"] .aligned .related-lookup, 76 | [dir="rtl"] .aligned .datetimeshortcuts { 77 | margin-left: 0; 78 | margin-right: 15px; 79 | } 80 | 81 | [dir="rtl"] .aligned ul { 82 | margin-right: 0; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /ballista/static/admin/css/rtl.css: -------------------------------------------------------------------------------- 1 | body { 2 | direction: rtl; 3 | } 4 | 5 | /* LOGIN */ 6 | 7 | .login .form-row { 8 | float: right; 9 | } 10 | 11 | .login .form-row label { 12 | float: right; 13 | padding-left: 0.5em; 14 | padding-right: 0; 15 | text-align: left; 16 | } 17 | 18 | .login .submit-row { 19 | clear: both; 20 | padding: 1em 9.4em 0 0; 21 | } 22 | 23 | /* GLOBAL */ 24 | 25 | th { 26 | text-align: right; 27 | } 28 | 29 | .module h2, .module caption { 30 | text-align: right; 31 | } 32 | 33 | .module ul, .module ol { 34 | margin-left: 0; 35 | margin-right: 1.5em; 36 | } 37 | 38 | .viewlink, .addlink, .changelink { 39 | padding-left: 0; 40 | padding-right: 16px; 41 | background-position: 100% 1px; 42 | } 43 | 44 | .deletelink { 45 | padding-left: 0; 46 | padding-right: 16px; 47 | background-position: 100% 1px; 48 | } 49 | 50 | .object-tools { 51 | float: left; 52 | } 53 | 54 | thead th:first-child, 55 | tfoot td:first-child { 56 | border-left: none; 57 | } 58 | 59 | /* LAYOUT */ 60 | 61 | #user-tools { 62 | right: auto; 63 | left: 0; 64 | text-align: left; 65 | } 66 | 67 | div.breadcrumbs { 68 | text-align: right; 69 | } 70 | 71 | #content-main { 72 | float: right; 73 | } 74 | 75 | #content-related { 76 | float: left; 77 | margin-left: -300px; 78 | margin-right: auto; 79 | } 80 | 81 | .colMS { 82 | margin-left: 300px; 83 | margin-right: 0; 84 | } 85 | 86 | /* SORTABLE TABLES */ 87 | 88 | table thead th.sorted .sortoptions { 89 | float: left; 90 | } 91 | 92 | thead th.sorted .text { 93 | padding-right: 0; 94 | padding-left: 42px; 95 | } 96 | 97 | /* dashboard styles */ 98 | 99 | .dashboard .module table td a { 100 | padding-left: .6em; 101 | padding-right: 16px; 102 | } 103 | 104 | /* changelists styles */ 105 | 106 | .change-list .filtered table { 107 | border-left: none; 108 | border-right: 0px none; 109 | } 110 | 111 | #changelist-filter { 112 | right: auto; 113 | left: 0; 114 | border-left: none; 115 | border-right: none; 116 | } 117 | 118 | .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { 119 | margin-right: 0; 120 | margin-left: 280px; 121 | } 122 | 123 | #changelist-filter li.selected { 124 | border-left: none; 125 | padding-left: 10px; 126 | margin-left: 0; 127 | border-right: 5px solid #eaeaea; 128 | padding-right: 10px; 129 | margin-right: -15px; 130 | } 131 | 132 | .filtered .actions { 133 | margin-left: 280px; 134 | margin-right: 0; 135 | } 136 | 137 | #changelist table tbody td:first-child, #changelist table tbody th:first-child { 138 | border-right: none; 139 | border-left: none; 140 | } 141 | 142 | /* FORMS */ 143 | 144 | .aligned label { 145 | padding: 0 0 3px 1em; 146 | float: right; 147 | } 148 | 149 | .submit-row { 150 | text-align: left 151 | } 152 | 153 | .submit-row p.deletelink-box { 154 | float: right; 155 | } 156 | 157 | .submit-row input.default { 158 | margin-left: 0; 159 | } 160 | 161 | .vDateField, .vTimeField { 162 | margin-left: 2px; 163 | } 164 | 165 | .aligned .form-row input { 166 | margin-left: 5px; 167 | } 168 | 169 | form .aligned p.help, form .aligned div.help { 170 | clear: right; 171 | } 172 | 173 | form .aligned ul { 174 | margin-right: 163px; 175 | margin-left: 0; 176 | } 177 | 178 | form ul.inline li { 179 | float: right; 180 | padding-right: 0; 181 | padding-left: 7px; 182 | } 183 | 184 | input[type=submit].default, .submit-row input.default { 185 | float: left; 186 | } 187 | 188 | fieldset .fieldBox { 189 | float: right; 190 | margin-left: 20px; 191 | margin-right: 0; 192 | } 193 | 194 | .errorlist li { 195 | background-position: 100% 12px; 196 | padding: 0; 197 | } 198 | 199 | .errornote { 200 | background-position: 100% 12px; 201 | padding: 10px 12px; 202 | } 203 | 204 | /* WIDGETS */ 205 | 206 | .calendarnav-previous { 207 | top: 0; 208 | left: auto; 209 | right: 10px; 210 | } 211 | 212 | .calendarnav-next { 213 | top: 0; 214 | right: auto; 215 | left: 10px; 216 | } 217 | 218 | .calendar caption, .calendarbox h2 { 219 | text-align: center; 220 | } 221 | 222 | .selector { 223 | float: right; 224 | } 225 | 226 | .selector .selector-filter { 227 | text-align: right; 228 | } 229 | 230 | .inline-deletelink { 231 | float: left; 232 | } 233 | 234 | form .form-row p.datetime { 235 | overflow: hidden; 236 | } 237 | 238 | .related-widget-wrapper { 239 | float: right; 240 | } 241 | 242 | /* MISC */ 243 | 244 | .inline-related h2, .inline-group h2 { 245 | text-align: right 246 | } 247 | 248 | .inline-related h3 span.delete { 249 | padding-right: 20px; 250 | padding-left: inherit; 251 | left: 10px; 252 | right: inherit; 253 | float:left; 254 | } 255 | 256 | .inline-related h3 span.delete label { 257 | margin-left: inherit; 258 | margin-right: 2px; 259 | } 260 | 261 | /* IE7 specific bug fixes */ 262 | 263 | div.colM { 264 | position: relative; 265 | } 266 | 267 | .submit-row input { 268 | float: left; 269 | } 270 | -------------------------------------------------------------------------------- /ballista/static/admin/css/vendor/select2/LICENSE-SELECT2.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2012-2015 Kevin Brown, Igor Vaynberg, and Select2 contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /ballista/static/admin/fonts/README.txt: -------------------------------------------------------------------------------- 1 | Roboto webfont source: https://www.google.com/fonts/specimen/Roboto 2 | WOFF files extracted using https://github.com/majodev/google-webfonts-helper 3 | Weights used in this project: Light (300), Regular (400), Bold (700) 4 | -------------------------------------------------------------------------------- /ballista/static/admin/fonts/Roboto-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dheerajchand/ubuntu-django-nginx-ansible/db03d7d053ed91a622d341858ab3cf7023adf7dd/ballista/static/admin/fonts/Roboto-Bold-webfont.woff -------------------------------------------------------------------------------- /ballista/static/admin/fonts/Roboto-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dheerajchand/ubuntu-django-nginx-ansible/db03d7d053ed91a622d341858ab3cf7023adf7dd/ballista/static/admin/fonts/Roboto-Light-webfont.woff -------------------------------------------------------------------------------- /ballista/static/admin/fonts/Roboto-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dheerajchand/ubuntu-django-nginx-ansible/db03d7d053ed91a622d341858ab3cf7023adf7dd/ballista/static/admin/fonts/Roboto-Regular-webfont.woff -------------------------------------------------------------------------------- /ballista/static/admin/img/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Code Charm Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /ballista/static/admin/img/README.txt: -------------------------------------------------------------------------------- 1 | All icons are taken from Font Awesome (http://fontawesome.io/) project. 2 | The Font Awesome font is licensed under the SIL OFL 1.1: 3 | - https://scripts.sil.org/OFL 4 | 5 | SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG 6 | Font-Awesome-SVG-PNG is licensed under the MIT license (see file license 7 | in current folder). 8 | -------------------------------------------------------------------------------- /ballista/static/admin/img/calendar-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ballista/static/admin/img/gis/move_vertex_off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ballista/static/admin/img/gis/move_vertex_on.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-addlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-calendar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-changelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-clock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-deletelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-no.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-unknown-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-unknown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-viewlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/icon-yes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/inline-delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/selector-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /ballista/static/admin/img/sorting-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ballista/static/admin/img/tooltag-add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/img/tooltag-arrowright.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ballista/static/admin/js/SelectBox.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 'use strict'; 3 | var SelectBox = { 4 | cache: {}, 5 | init: function(id) { 6 | var box = document.getElementById(id); 7 | var node; 8 | SelectBox.cache[id] = []; 9 | var cache = SelectBox.cache[id]; 10 | var boxOptions = box.options; 11 | var boxOptionsLength = boxOptions.length; 12 | for (var i = 0, j = boxOptionsLength; i < j; i++) { 13 | node = boxOptions[i]; 14 | cache.push({value: node.value, text: node.text, displayed: 1}); 15 | } 16 | }, 17 | redisplay: function(id) { 18 | // Repopulate HTML select box from cache 19 | var box = document.getElementById(id); 20 | var node; 21 | $(box).empty(); // clear all options 22 | var new_options = box.outerHTML.slice(0, -9); // grab just the opening tag 23 | var cache = SelectBox.cache[id]; 24 | for (var i = 0, j = cache.length; i < j; i++) { 25 | node = cache[i]; 26 | if (node.displayed) { 27 | var new_option = new Option(node.text, node.value, false, false); 28 | // Shows a tooltip when hovering over the option 29 | new_option.setAttribute("title", node.text); 30 | new_options += new_option.outerHTML; 31 | } 32 | } 33 | new_options += ''; 34 | box.outerHTML = new_options; 35 | }, 36 | filter: function(id, text) { 37 | // Redisplay the HTML select box, displaying only the choices containing ALL 38 | // the words in text. (It's an AND search.) 39 | var tokens = text.toLowerCase().split(/\s+/); 40 | var node, token; 41 | var cache = SelectBox.cache[id]; 42 | for (var i = 0, j = cache.length; i < j; i++) { 43 | node = cache[i]; 44 | node.displayed = 1; 45 | var node_text = node.text.toLowerCase(); 46 | var numTokens = tokens.length; 47 | for (var k = 0; k < numTokens; k++) { 48 | token = tokens[k]; 49 | if (node_text.indexOf(token) === -1) { 50 | node.displayed = 0; 51 | break; // Once the first token isn't found we're done 52 | } 53 | } 54 | } 55 | SelectBox.redisplay(id); 56 | }, 57 | delete_from_cache: function(id, value) { 58 | var node, delete_index = null; 59 | var cache = SelectBox.cache[id]; 60 | for (var i = 0, j = cache.length; i < j; i++) { 61 | node = cache[i]; 62 | if (node.value === value) { 63 | delete_index = i; 64 | break; 65 | } 66 | } 67 | cache.splice(delete_index, 1); 68 | }, 69 | add_to_cache: function(id, option) { 70 | SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); 71 | }, 72 | cache_contains: function(id, value) { 73 | // Check if an item is contained in the cache 74 | var node; 75 | var cache = SelectBox.cache[id]; 76 | for (var i = 0, j = cache.length; i < j; i++) { 77 | node = cache[i]; 78 | if (node.value === value) { 79 | return true; 80 | } 81 | } 82 | return false; 83 | }, 84 | move: function(from, to) { 85 | var from_box = document.getElementById(from); 86 | var option; 87 | var boxOptions = from_box.options; 88 | var boxOptionsLength = boxOptions.length; 89 | for (var i = 0, j = boxOptionsLength; i < j; i++) { 90 | option = boxOptions[i]; 91 | var option_value = option.value; 92 | if (option.selected && SelectBox.cache_contains(from, option_value)) { 93 | SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1}); 94 | SelectBox.delete_from_cache(from, option_value); 95 | } 96 | } 97 | SelectBox.redisplay(from); 98 | SelectBox.redisplay(to); 99 | }, 100 | move_all: function(from, to) { 101 | var from_box = document.getElementById(from); 102 | var option; 103 | var boxOptions = from_box.options; 104 | var boxOptionsLength = boxOptions.length; 105 | for (var i = 0, j = boxOptionsLength; i < j; i++) { 106 | option = boxOptions[i]; 107 | var option_value = option.value; 108 | if (SelectBox.cache_contains(from, option_value)) { 109 | SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1}); 110 | SelectBox.delete_from_cache(from, option_value); 111 | } 112 | } 113 | SelectBox.redisplay(from); 114 | SelectBox.redisplay(to); 115 | }, 116 | sort: function(id) { 117 | SelectBox.cache[id].sort(function(a, b) { 118 | a = a.text.toLowerCase(); 119 | b = b.text.toLowerCase(); 120 | try { 121 | if (a > b) { 122 | return 1; 123 | } 124 | if (a < b) { 125 | return -1; 126 | } 127 | } 128 | catch (e) { 129 | // silently fail on IE 'unknown' exception 130 | } 131 | return 0; 132 | } ); 133 | }, 134 | select_all: function(id) { 135 | var box = document.getElementById(id); 136 | var boxOptions = box.options; 137 | var boxOptionsLength = boxOptions.length; 138 | for (var i = 0; i < boxOptionsLength; i++) { 139 | boxOptions[i].selected = 'selected'; 140 | } 141 | } 142 | }; 143 | window.SelectBox = SelectBox; 144 | })(django.jQuery); 145 | -------------------------------------------------------------------------------- /ballista/static/admin/js/actions.js: -------------------------------------------------------------------------------- 1 | /*global gettext, interpolate, ngettext*/ 2 | (function($) { 3 | 'use strict'; 4 | var lastChecked; 5 | 6 | $.fn.actions = function(opts) { 7 | var options = $.extend({}, $.fn.actions.defaults, opts); 8 | var actionCheckboxes = $(this); 9 | var list_editable_changed = false; 10 | var showQuestion = function() { 11 | $(options.acrossClears).hide(); 12 | $(options.acrossQuestions).show(); 13 | $(options.allContainer).hide(); 14 | }, 15 | showClear = function() { 16 | $(options.acrossClears).show(); 17 | $(options.acrossQuestions).hide(); 18 | $(options.actionContainer).toggleClass(options.selectedClass); 19 | $(options.allContainer).show(); 20 | $(options.counterContainer).hide(); 21 | }, 22 | reset = function() { 23 | $(options.acrossClears).hide(); 24 | $(options.acrossQuestions).hide(); 25 | $(options.allContainer).hide(); 26 | $(options.counterContainer).show(); 27 | }, 28 | clearAcross = function() { 29 | reset(); 30 | $(options.acrossInput).val(0); 31 | $(options.actionContainer).removeClass(options.selectedClass); 32 | }, 33 | checker = function(checked) { 34 | if (checked) { 35 | showQuestion(); 36 | } else { 37 | reset(); 38 | } 39 | $(actionCheckboxes).prop("checked", checked) 40 | .parent().parent().toggleClass(options.selectedClass, checked); 41 | }, 42 | updateCounter = function() { 43 | var sel = $(actionCheckboxes).filter(":checked").length; 44 | // data-actions-icnt is defined in the generated HTML 45 | // and contains the total amount of objects in the queryset 46 | var actions_icnt = $('.action-counter').data('actionsIcnt'); 47 | $(options.counterContainer).html(interpolate( 48 | ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { 49 | sel: sel, 50 | cnt: actions_icnt 51 | }, true)); 52 | $(options.allToggle).prop("checked", function() { 53 | var value; 54 | if (sel === actionCheckboxes.length) { 55 | value = true; 56 | showQuestion(); 57 | } else { 58 | value = false; 59 | clearAcross(); 60 | } 61 | return value; 62 | }); 63 | }; 64 | // Show counter by default 65 | $(options.counterContainer).show(); 66 | // Check state of checkboxes and reinit state if needed 67 | $(this).filter(":checked").each(function(i) { 68 | $(this).parent().parent().toggleClass(options.selectedClass); 69 | updateCounter(); 70 | if ($(options.acrossInput).val() === 1) { 71 | showClear(); 72 | } 73 | }); 74 | $(options.allToggle).show().on('click', function() { 75 | checker($(this).prop("checked")); 76 | updateCounter(); 77 | }); 78 | $("a", options.acrossQuestions).on('click', function(event) { 79 | event.preventDefault(); 80 | $(options.acrossInput).val(1); 81 | showClear(); 82 | }); 83 | $("a", options.acrossClears).on('click', function(event) { 84 | event.preventDefault(); 85 | $(options.allToggle).prop("checked", false); 86 | clearAcross(); 87 | checker(0); 88 | updateCounter(); 89 | }); 90 | lastChecked = null; 91 | $(actionCheckboxes).on('click', function(event) { 92 | if (!event) { event = window.event; } 93 | var target = event.target ? event.target : event.srcElement; 94 | if (lastChecked && $.data(lastChecked) !== $.data(target) && event.shiftKey === true) { 95 | var inrange = false; 96 | $(lastChecked).prop("checked", target.checked) 97 | .parent().parent().toggleClass(options.selectedClass, target.checked); 98 | $(actionCheckboxes).each(function() { 99 | if ($.data(this) === $.data(lastChecked) || $.data(this) === $.data(target)) { 100 | inrange = (inrange) ? false : true; 101 | } 102 | if (inrange) { 103 | $(this).prop("checked", target.checked) 104 | .parent().parent().toggleClass(options.selectedClass, target.checked); 105 | } 106 | }); 107 | } 108 | $(target).parent().parent().toggleClass(options.selectedClass, target.checked); 109 | lastChecked = target; 110 | updateCounter(); 111 | }); 112 | $('form#changelist-form table#result_list tr').on('change', 'td:gt(0) :input', function() { 113 | list_editable_changed = true; 114 | }); 115 | $('form#changelist-form button[name="index"]').on('click', function(event) { 116 | if (list_editable_changed) { 117 | return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.")); 118 | } 119 | }); 120 | $('form#changelist-form input[name="_save"]').on('click', function(event) { 121 | var action_changed = false; 122 | $('select option:selected', options.actionContainer).each(function() { 123 | if ($(this).val()) { 124 | action_changed = true; 125 | } 126 | }); 127 | if (action_changed) { 128 | if (list_editable_changed) { 129 | return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")); 130 | } else { 131 | return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button.")); 132 | } 133 | } 134 | }); 135 | }; 136 | /* Setup plugin defaults */ 137 | $.fn.actions.defaults = { 138 | actionContainer: "div.actions", 139 | counterContainer: "span.action-counter", 140 | allContainer: "div.actions span.all", 141 | acrossInput: "div.actions input.select-across", 142 | acrossQuestions: "div.actions span.question", 143 | acrossClears: "div.actions span.clear", 144 | allToggle: "#action-toggle", 145 | selectedClass: "selected" 146 | }; 147 | $(document).ready(function() { 148 | var $actionsEls = $('tr input.action-select'); 149 | if ($actionsEls.length > 0) { 150 | $actionsEls.actions(); 151 | } 152 | }); 153 | })(django.jQuery); 154 | -------------------------------------------------------------------------------- /ballista/static/admin/js/actions.min.js: -------------------------------------------------------------------------------- 1 | (function(a){var f;a.fn.actions=function(e){var b=a.extend({},a.fn.actions.defaults,e),g=a(this),k=!1,l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()},m=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},n=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},p=function(){n(); 2 | a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)},q=function(c){c?l():n();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length,d=a(".action-counter").data("actionsIcnt");a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:d},!0));a(b.allToggle).prop("checked",function(){if(c===g.length){var a=!0;l()}else a=!1,p();return a})};a(b.counterContainer).show(); 3 | a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass);h();1===a(b.acrossInput).val()&&m()});a(b.allToggle).show().on("click",function(){q(a(this).prop("checked"));h()});a("a",b.acrossQuestions).on("click",function(c){c.preventDefault();a(b.acrossInput).val(1);m()});a("a",b.acrossClears).on("click",function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);p();q(0);h()});f=null;a(g).on("click",function(c){c||(c=window.event);var d=c.target?c.target: 4 | c.srcElement;if(f&&a.data(f)!==a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(g).each(function(){if(a.data(this)===a.data(f)||a.data(this)===a.data(d))e=e?!1:!0;e&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);f=d;h()});a("form#changelist-form table#result_list tr").on("change","td:gt(0) :input",function(){k=!0}); 5 | a('form#changelist-form button[name="index"]').on("click",function(a){if(k)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').on("click",function(c){var d=!1;a("select option:selected",b.actionContainer).each(function(){a(this).val()&&(d=!0)});if(d)return k?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")): 6 | confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"};a(document).ready(function(){var e= 7 | a("tr input.action-select");0= 0) && parseFloat(navigator.appVersion); 5 | var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]); 6 | 7 | // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]); 8 | function quickElement() { 9 | 'use strict'; 10 | var obj = document.createElement(arguments[0]); 11 | if (arguments[2]) { 12 | var textNode = document.createTextNode(arguments[2]); 13 | obj.appendChild(textNode); 14 | } 15 | var len = arguments.length; 16 | for (var i = 3; i < len; i += 2) { 17 | obj.setAttribute(arguments[i], arguments[i + 1]); 18 | } 19 | arguments[1].appendChild(obj); 20 | return obj; 21 | } 22 | 23 | // "a" is reference to an object 24 | function removeChildren(a) { 25 | 'use strict'; 26 | while (a.hasChildNodes()) { 27 | a.removeChild(a.lastChild); 28 | } 29 | } 30 | 31 | // ---------------------------------------------------------------------------- 32 | // Find-position functions by PPK 33 | // See https://www.quirksmode.org/js/findpos.html 34 | // ---------------------------------------------------------------------------- 35 | function findPosX(obj) { 36 | 'use strict'; 37 | var curleft = 0; 38 | if (obj.offsetParent) { 39 | while (obj.offsetParent) { 40 | curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft); 41 | obj = obj.offsetParent; 42 | } 43 | // IE offsetParent does not include the top-level 44 | if (isIE && obj.parentElement) { 45 | curleft += obj.offsetLeft - obj.scrollLeft; 46 | } 47 | } else if (obj.x) { 48 | curleft += obj.x; 49 | } 50 | return curleft; 51 | } 52 | 53 | function findPosY(obj) { 54 | 'use strict'; 55 | var curtop = 0; 56 | if (obj.offsetParent) { 57 | while (obj.offsetParent) { 58 | curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop); 59 | obj = obj.offsetParent; 60 | } 61 | // IE offsetParent does not include the top-level 62 | if (isIE && obj.parentElement) { 63 | curtop += obj.offsetTop - obj.scrollTop; 64 | } 65 | } else if (obj.y) { 66 | curtop += obj.y; 67 | } 68 | return curtop; 69 | } 70 | 71 | //----------------------------------------------------------------------------- 72 | // Date object extensions 73 | // ---------------------------------------------------------------------------- 74 | (function() { 75 | 'use strict'; 76 | Date.prototype.getTwelveHours = function() { 77 | var hours = this.getHours(); 78 | if (hours === 0) { 79 | return 12; 80 | } 81 | else { 82 | return hours <= 12 ? hours : hours - 12; 83 | } 84 | }; 85 | 86 | Date.prototype.getTwoDigitMonth = function() { 87 | return (this.getMonth() < 9) ? '0' + (this.getMonth() + 1) : (this.getMonth() + 1); 88 | }; 89 | 90 | Date.prototype.getTwoDigitDate = function() { 91 | return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate(); 92 | }; 93 | 94 | Date.prototype.getTwoDigitTwelveHour = function() { 95 | return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours(); 96 | }; 97 | 98 | Date.prototype.getTwoDigitHour = function() { 99 | return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours(); 100 | }; 101 | 102 | Date.prototype.getTwoDigitMinute = function() { 103 | return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes(); 104 | }; 105 | 106 | Date.prototype.getTwoDigitSecond = function() { 107 | return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); 108 | }; 109 | 110 | Date.prototype.getHourMinute = function() { 111 | return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); 112 | }; 113 | 114 | Date.prototype.getHourMinuteSecond = function() { 115 | return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond(); 116 | }; 117 | 118 | Date.prototype.getFullMonthName = function() { 119 | return typeof window.CalendarNamespace === "undefined" 120 | ? this.getTwoDigitMonth() 121 | : window.CalendarNamespace.monthsOfYear[this.getMonth()]; 122 | }; 123 | 124 | Date.prototype.strftime = function(format) { 125 | var fields = { 126 | B: this.getFullMonthName(), 127 | c: this.toString(), 128 | d: this.getTwoDigitDate(), 129 | H: this.getTwoDigitHour(), 130 | I: this.getTwoDigitTwelveHour(), 131 | m: this.getTwoDigitMonth(), 132 | M: this.getTwoDigitMinute(), 133 | p: (this.getHours() >= 12) ? 'PM' : 'AM', 134 | S: this.getTwoDigitSecond(), 135 | w: '0' + this.getDay(), 136 | x: this.toLocaleDateString(), 137 | X: this.toLocaleTimeString(), 138 | y: ('' + this.getFullYear()).substr(2, 4), 139 | Y: '' + this.getFullYear(), 140 | '%': '%' 141 | }; 142 | var result = '', i = 0; 143 | while (i < format.length) { 144 | if (format.charAt(i) === '%') { 145 | result = result + fields[format.charAt(i + 1)]; 146 | ++i; 147 | } 148 | else { 149 | result = result + format.charAt(i); 150 | } 151 | ++i; 152 | } 153 | return result; 154 | }; 155 | 156 | // ---------------------------------------------------------------------------- 157 | // String object extensions 158 | // ---------------------------------------------------------------------------- 159 | String.prototype.pad_left = function(pad_length, pad_string) { 160 | var new_string = this; 161 | for (var i = 0; new_string.length < pad_length; i++) { 162 | new_string = pad_string + new_string; 163 | } 164 | return new_string; 165 | }; 166 | 167 | String.prototype.strptime = function(format) { 168 | var split_format = format.split(/[.\-/]/); 169 | var date = this.split(/[.\-/]/); 170 | var i = 0; 171 | var day, month, year; 172 | while (i < split_format.length) { 173 | switch (split_format[i]) { 174 | case "%d": 175 | day = date[i]; 176 | break; 177 | case "%m": 178 | month = date[i] - 1; 179 | break; 180 | case "%Y": 181 | year = date[i]; 182 | break; 183 | case "%y": 184 | year = date[i]; 185 | break; 186 | } 187 | ++i; 188 | } 189 | // Create Date object from UTC since the parsed value is supposed to be 190 | // in UTC, not local time. Also, the calendar uses UTC functions for 191 | // date extraction. 192 | return new Date(Date.UTC(year, month, day)); 193 | }; 194 | 195 | })(); 196 | // ---------------------------------------------------------------------------- 197 | // Get the computed style for and element 198 | // ---------------------------------------------------------------------------- 199 | function getStyle(oElm, strCssRule) { 200 | 'use strict'; 201 | var strValue = ""; 202 | if(document.defaultView && document.defaultView.getComputedStyle) { 203 | strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); 204 | } 205 | else if(oElm.currentStyle) { 206 | strCssRule = strCssRule.replace(/\-(\w)/g, function(strMatch, p1) { 207 | return p1.toUpperCase(); 208 | }); 209 | strValue = oElm.currentStyle[strCssRule]; 210 | } 211 | return strValue; 212 | } 213 | -------------------------------------------------------------------------------- /ballista/static/admin/js/inlines.min.js: -------------------------------------------------------------------------------- 1 | var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(b,d,a){b instanceof String&&(b=String(b));for(var c=b.length,f=0;f'+a.addText+""),l=d.find("tr:last a")):(c.filter(":last").after('"),l=c.filter(":last").next().find("a")));l.on("click",function(d){d.preventDefault();d=b("#"+a.prefix+"-empty"); 6 | var c=d.clone(!0);c.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+h);c.is("tr")?c.children(":last").append('
'+a.deleteText+"
"):c.is("ul")||c.is("ol")?c.append('
  • '+a.deleteText+"
  • "):c.children(":first").append(''+a.deleteText+"");c.find("*").each(function(){f(this,a.prefix,g.val())});c.insertBefore(b(d)); 7 | b(g).val(parseInt(g.val(),10)+1);h+=1;""!==e.val()&&0>=e.val()-g.val()&&l.parent().hide();c.find("a."+a.deleteCssClass).on("click",function(d){d.preventDefault();c.remove();--h;a.removed&&a.removed(c);b(document).trigger("formset:removed",[c,a.prefix]);d=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(d.length);(""===e.val()||0 tr",b(d).tabularFormset(d,a.options)}})})})(django.jQuery); 14 | -------------------------------------------------------------------------------- /ballista/static/admin/js/jquery.init.js: -------------------------------------------------------------------------------- 1 | /*global django:true, jQuery:false*/ 2 | /* Puts the included jQuery into our own namespace using noConflict and passing 3 | * it 'true'. This ensures that the included jQuery doesn't pollute the global 4 | * namespace (i.e. this preserves pre-existing values for both window.$ and 5 | * window.jQuery). 6 | */ 7 | var django = django || {}; 8 | django.jQuery = jQuery.noConflict(true); 9 | -------------------------------------------------------------------------------- /ballista/static/admin/js/popup_response.js: -------------------------------------------------------------------------------- 1 | /*global opener */ 2 | (function() { 3 | 'use strict'; 4 | var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse); 5 | switch(initData.action) { 6 | case 'change': 7 | opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value); 8 | break; 9 | case 'delete': 10 | opener.dismissDeleteRelatedObjectPopup(window, initData.value); 11 | break; 12 | default: 13 | opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj); 14 | break; 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /ballista/static/admin/js/prepopulate.js: -------------------------------------------------------------------------------- 1 | /*global URLify*/ 2 | (function($) { 3 | 'use strict'; 4 | $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) { 5 | /* 6 | Depends on urlify.js 7 | Populates a selected field with the values of the dependent fields, 8 | URLifies and shortens the string. 9 | dependencies - array of dependent fields ids 10 | maxLength - maximum length of the URLify'd string 11 | allowUnicode - Unicode support of the URLify'd string 12 | */ 13 | return this.each(function() { 14 | var prepopulatedField = $(this); 15 | 16 | var populate = function() { 17 | // Bail if the field's value has been changed by the user 18 | if (prepopulatedField.data('_changed')) { 19 | return; 20 | } 21 | 22 | var values = []; 23 | $.each(dependencies, function(i, field) { 24 | field = $(field); 25 | if (field.val().length > 0) { 26 | values.push(field.val()); 27 | } 28 | }); 29 | prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode)); 30 | }; 31 | 32 | prepopulatedField.data('_changed', false); 33 | prepopulatedField.on('change', function() { 34 | prepopulatedField.data('_changed', true); 35 | }); 36 | 37 | if (!prepopulatedField.val()) { 38 | $(dependencies.join(',')).on('keyup change focus', populate); 39 | } 40 | }); 41 | }; 42 | })(django.jQuery); 43 | -------------------------------------------------------------------------------- /ballista/static/admin/js/prepopulate.min.js: -------------------------------------------------------------------------------- 1 | (function(b){b.fn.prepopulate=function(d,f,g){return this.each(function(){var a=b(this),h=function(){if(!a.data("_changed")){var e=[];b.each(d,function(a,c){c=b(c);01&&(n+="a"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Моля въведете още "+t+" символ";return t>1&&(n+="a"),n},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(e){var t="Можете да направите до "+e.maximum+" ";return e.maximum>1?t+="избора":t+="избор",t},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/ca.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Si us plau, elimina "+t+" car";return t==1?n+="àcter":n+="àcters",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Si us plau, introdueix "+t+" car";return t==1?n+="àcter":n+="àcters",n},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var t="Només es pot seleccionar "+e.maximum+" element";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/cs.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/cs",[],function(){function e(e,t){switch(e){case 2:return t?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?"Prosím zadejte o jeden znak méně":n<=4?"Prosím zadejte o "+e(n,!0)+" znaky méně":"Prosím zadejte o "+n+" znaků méně"},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?"Prosím zadejte ještě jeden znak":n<=4?"Prosím zadejte ještě další "+e(n,!0)+" znaky":"Prosím zadejte ještě dalších "+n+" znaků"},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(t){var n=t.maximum;return n==1?"Můžete zvolit jen jednu položku":n<=4?"Můžete zvolit maximálně "+e(n,!1)+" položky":"Můžete zvolit maximálně "+n+" položek"},noResults:function(){return"Nenalezeny žádné položky"},searching:function(){return"Vyhledávání…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/da.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Angiv venligst "+t+" tegn mindre";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Angiv venligst "+t+" tegn mere";return n},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var t="Du kan kun vælge "+e.maximum+" emne";return e.maximum!=1&&(t+="r"),t},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/de.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/de",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return"Bitte "+t+" Zeichen weniger eingeben"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Bitte "+t+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var t="Sie können nur "+e.maximum+" Eintr";return e.maximum===1?t+="ag":t+="äge",t+=" auswählen",t},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/el.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Παρακαλώ διαγράψτε "+t+" χαρακτήρ";return t==1&&(n+="α"),t!=1&&(n+="ες"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Παρακαλώ συμπληρώστε "+t+" ή περισσότερους χαρακτήρες";return n},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(e){var t="Μπορείτε να επιλέξετε μόνο "+e.maximum+" επιλογ";return e.maximum==1&&(t+="ή"),e.maximum!=1&&(t+="ές"),t},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/en.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Please delete "+t+" character";return t!=1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Please enter "+t+" or more characters";return n},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var t="You can only select "+e.maximum+" item";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No results found"},searching:function(){return"Searching…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/es.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"La carga falló"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Por favor, elimine "+t+" car";return t==1?n+="ácter":n+="acteres",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Por favor, introduzca "+t+" car";return t==1?n+="ácter":n+="acteres",n},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var t="Sólo puede seleccionar "+e.maximum+" elemento";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/et.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Sisesta "+t+" täht";return t!=1&&(n+="e"),n+=" vähem",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Sisesta "+t+" täht";return t!=1&&(n+="e"),n+=" rohkem",n},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var t="Saad vaid "+e.maximum+" tulemus";return e.maximum==1?t+="e":t+="t",t+=" valida",t},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/eu.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return t==1?n+="karaktere bat":n+=t+" karaktere",n+=" gutxiago",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return t==1?n+="karaktere bat":n+=t+" karaktere",n+=" gehiago",n},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return e.maximum===1?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/fa.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="لطفاً "+t+" کاراکتر را حذف نمایید";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="لطفاً تعداد "+t+" کاراکتر یا بیشتر وارد نمایید";return n},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(e){var t="شما تنها می‌توانید "+e.maximum+" آیتم را انتخاب نمایید";return t},noResults:function(){return"هیچ نتیجه‌ای یافت نشد"},searching:function(){return"در حال جستجو..."}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/fi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fi",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return"Ole hyvä ja anna "+t+" merkkiä vähemmän"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Ole hyvä ja anna "+t+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(e){return"Voit valita ainoastaan "+e.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/fr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Supprimez "+t+" caractère";return t!==1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Saisissez "+t+" caractère";return t!==1&&(n+="s"),n},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){var t="Vous pouvez seulement sélectionner "+e.maximum+" élément";return e.maximum!==1&&(t+="s"),t},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/gl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/gl",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Elimine ";return t===1?n+="un carácter":n+=t+" caracteres",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Engada ";return t===1?n+="un carácter":n+=t+" caracteres",n},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){var t="Só pode ";return e.maximum===1?t+="un elemento":t+=e.maximum+" elementos",t},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/he.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="נא למחוק ";return t===1?n+="תו אחד":n+=t+" תווים",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="נא להכניס ";return t===1?n+="תו אחד":n+=t+" תווים",n+=" או יותר",n},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(e){var t="באפשרותך לבחור עד ";return e.maximum===1?t+="פריט אחד":t+=e.maximum+" פריטים",t},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/hi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" अक्षर को हटा दें";return t>1&&(n=t+" अक्षरों को हटा दें "),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="कृपया "+t+" या अधिक अक्षर दर्ज करें";return n},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(e){var t="आप केवल "+e.maximum+" आइटम का चयन कर सकते हैं";return t},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/hr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hr",[],function(){function e(e){var t=" "+e+" znak";return e%10<5&&e%10>0&&(e%100<5||e%100>19)?e%10>1&&(t+="a"):t+="ova",t}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(t){var n=t.input.length-t.maximum;return"Unesite "+e(n)},inputTooShort:function(t){var n=t.minimum-t.input.length;return"Unesite još "+e(n)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(e){return"Maksimalan broj odabranih stavki je "+e.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/hu.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return"Túl hosszú. "+t+" karakterrel több, mint kellene."},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Túl rövid. Még "+t+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/id.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Hapuskan "+t+" huruf"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Masukkan "+t+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(e){return"Anda hanya dapat memilih "+e.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/is.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/is",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vinsamlegast styttið texta um "+t+" staf";return t<=1?n:n+"i"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vinsamlegast skrifið "+t+" staf";return t>1&&(n+="i"),n+=" í viðbót",n},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(e){return"Þú getur aðeins valið "+e.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/it.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Per favore cancella "+t+" caratter";return t!==1?n+="i":n+="e",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Per favore inserisci "+t+" o più caratteri";return n},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var t="Puoi selezionare solo "+e.maximum+" element";return e.maximum!==1?t+="i":t+="o",t},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/ja.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" 文字を削除してください";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="少なくとも "+t+" 文字を入力してください";return n},loadingMore:function(){return"読み込み中…"},maximumSelected:function(e){var t=e.maximum+" 件しか選択できません";return t},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/km.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="សូមលុបចេញ "+t+" អក្សរ";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="សូមបញ្ចូល"+t+" អក្សរ រឺ ច្រើនជាងនេះ";return n},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(e){var t="អ្នកអាចជ្រើសរើសបានតែ "+e.maximum+" ជម្រើសប៉ុណ្ណោះ";return t},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/ko.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="너무 깁니다. "+t+" 글자 지워주세요.";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="너무 짧습니다. "+t+" 글자 더 입력해주세요.";return n},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(e){var t="최대 "+e.maximum+"개까지만 선택 가능합니다.";return t},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/lt.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/lt",[],function(){function e(e,t,n,r){return e%10===1&&(e%100<11||e%100>19)?t:e%10>=2&&e%10<=9&&(e%100<11||e%100>19)?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r="Pašalinkite "+n+" simbol";return r+=e(n,"į","ius","ių"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Įrašykite dar "+n+" simbol";return r+=e(n,"į","ius","ių"),r},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(t){var n="Jūs galite pasirinkti tik "+t.maximum+" element";return n+=e(t.maximum,"ą","us","ų"),n},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/lv.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/lv",[],function(){function e(e,t,n,r){return e===11?t:e%10===1?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r="Lūdzu ievadiet par "+n;return r+=" simbol"+e(n,"iem","u","iem"),r+" mazāk"},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Lūdzu ievadiet vēl "+n;return r+=" simbol"+e(n,"us","u","us"),r},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(t){var n="Jūs varat izvēlēties ne vairāk kā "+t.maximum;return n+=" element"+e(t.maximum,"us","u","us"),n},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/mk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/mk",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Ве молиме внесете "+e.maximum+" помалку карактер";return e.maximum!==1&&(n+="и"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Ве молиме внесете уште "+e.maximum+" карактер";return e.maximum!==1&&(n+="и"),n},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(e){var t="Можете да изберете само "+e.maximum+" ставк";return e.maximum===1?t+="а":t+="и",t},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/ms.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Sila hapuskan "+t+" aksara"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Sila masukkan "+t+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(e){return"Anda hanya boleh memilih "+e.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/nb.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Vennligst fjern "+t+" tegn"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vennligst skriv inn ";return t>1?n+=" flere tegn":n+=" tegn til",n},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/nl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Gelieve "+t+" karakters te verwijderen";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Gelieve "+t+" of meer karakters in te voeren";return n},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var t=e.maximum==1?"kan":"kunnen",n="Er "+t+" maar "+e.maximum+" item";return e.maximum!=1&&(n+="s"),n+=" worden geselecteerd",n},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/pl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pl",[],function(){var e=["znak","znaki","znaków"],t=["element","elementy","elementów"],n=function(t,n){if(t===1)return n[0];if(t>1&&t<=4)return n[1];if(t>=5)return n[2]};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(t){var r=t.input.length-t.maximum;return"Usuń "+r+" "+n(r,e)},inputTooShort:function(t){var r=t.minimum-t.input.length;return"Podaj przynajmniej "+r+" "+n(r,e)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(e){return"Możesz zaznaczyć tylko "+e.maximum+" "+n(e.maximum,t)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/pt-BR.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Apague "+t+" caracter";return t!=1&&(n+="es"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Digite "+t+" ou mais caracteres";return n},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var t="Você só pode selecionar "+e.maximum+" ite";return e.maximum==1?t+="m":t+="ns",t},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/pt.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Por favor apague "+t+" ";return n+=t!=1?"caracteres":"carácter",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Introduza "+t+" ou mais caracteres";return n},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var t="Apenas pode seleccionar "+e.maximum+" ";return t+=e.maximum!=1?"itens":"item",t},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/ro.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return t!==1&&(n+="e"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vă rugăm să introduceți "+t+"sau mai multe caractere";return n},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",e.maximum!==1&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/ru.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ru",[],function(){function e(e,t,n,r){return e%10<5&&e%10>0&&e%100<5||e%100>20?e%10>1?n:t:r}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Пожалуйста, введите на "+n+" символ";return r+=e(n,"","a","ов"),r+=" меньше",r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Пожалуйста, введите еще хотя бы "+n+" символ";return r+=e(n,"","a","ов"),r},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(t){var n="Вы можете выбрать не более "+t.maximum+" элемент";return n+=e(t.maximum,"","a","ов"),n},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/sk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?"Prosím, zadajte o jeden znak menej":n>=2&&n<=4?"Prosím, zadajte o "+e[n](!0)+" znaky menej":"Prosím, zadajte o "+n+" znakov menej"},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?"Prosím, zadajte ešte jeden znak":n<=4?"Prosím, zadajte ešte ďalšie "+e[n](!0)+" znaky":"Prosím, zadajte ešte ďalších "+n+" znakov"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(t){return t.maximum==1?"Môžete zvoliť len jednu položku":t.maximum>=2&&t.maximum<=4?"Môžete zvoliť najviac "+e[t.maximum](!1)+" položky":"Môžete zvoliť najviac "+t.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/sr-Cyrl.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sr-Cyrl",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Обришите "+n+" симбол";return r+=e(n,"","а","а"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Укуцајте бар још "+n+" симбол";return r+=e(n,"","а","а"),r},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(t){var n="Можете изабрати само "+t.maximum+" ставк";return n+=e(t.maximum,"у","е","и"),n},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/sr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sr",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return"Preuzimanje nije uspelo."},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Obrišite "+n+" simbol";return r+=e(n,"","a","a"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Ukucajte bar još "+n+" simbol";return r+=e(n,"","a","a"),r},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(t){var n="Možete izabrati samo "+t.maximum+" stavk";return n+=e(t.maximum,"u","e","i"),n},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/sv.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sv",[],function(){return{errorLoading:function(){return"Resultat kunde inte laddas."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vänligen sudda ut "+t+" tecken";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vänligen skriv in "+t+" eller fler tecken";return n},loadingMore:function(){return"Laddar fler resultat…"},maximumSelected:function(e){var t="Du kan max välja "+e.maximum+" element";return t},noResults:function(){return"Inga träffar"},searching:function(){return"Söker…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/th.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/th",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="โปรดลบออก "+t+" ตัวอักษร";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="โปรดพิมพ์เพิ่มอีก "+t+" ตัวอักษร";return n},loadingMore:function(){return"กำลังค้นข้อมูลเพิ่ม…"},maximumSelected:function(e){var t="คุณสามารถเลือกได้ไม่เกิน "+e.maximum+" รายการ";return t},noResults:function(){return"ไม่พบข้อมูล"},searching:function(){return"กำลังค้นข้อมูล…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/tr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/tr",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" karakter daha girmelisiniz";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="En az "+t+" karakter daha girmelisiniz";return n},loadingMore:function(){return"Daha fazla…"},maximumSelected:function(e){var t="Sadece "+e.maximum+" seçim yapabilirsiniz";return t},noResults:function(){return"Sonuç bulunamadı"},searching:function(){return"Aranıyor…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/uk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/uk",[],function(){function e(e,t,n,r){return e%100>10&&e%100<15?r:e%10===1?t:e%10>1&&e%10<5?n:r}return{errorLoading:function(){return"Неможливо завантажити результати"},inputTooLong:function(t){var n=t.input.length-t.maximum;return"Будь ласка, видаліть "+n+" "+e(t.maximum,"літеру","літери","літер")},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Будь ласка, введіть "+t+" або більше літер"},loadingMore:function(){return"Завантаження інших результатів…"},maximumSelected:function(t){return"Ви можете вибрати лише "+t.maximum+" "+e(t.maximum,"пункт","пункти","пунктів")},noResults:function(){return"Нічого не знайдено"},searching:function(){return"Пошук…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/vi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/vi",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vui lòng nhập ít hơn "+t+" ký tự";return t!=1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vui lòng nhập nhiều hơn "+t+' ký tự"';return n},loadingMore:function(){return"Đang lấy thêm kết quả…"},maximumSelected:function(e){var t="Chỉ có thể chọn được "+e.maximum+" lựa chọn";return t},noResults:function(){return"Không tìm thấy kết quả"},searching:function(){return"Đang tìm…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/zh-CN.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="请删除"+t+"个字符";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="请再输入至少"+t+"个字符";return n},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(e){var t="最多只能选择"+e.maximum+"个项目";return t},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/select2/i18n/zh-TW.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-TW",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="請刪掉"+t+"個字元";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="請再輸入"+t+"個字元";return n},loadingMore:function(){return"載入中…"},maximumSelected:function(e){var t="你只能選擇最多"+e.maximum+"項";return t},noResults:function(){return"沒有找到相符的項目"},searching:function(){return"搜尋中…"}}}),{define:e.define,require:e.require}})(); -------------------------------------------------------------------------------- /ballista/static/admin/js/vendor/xregexp/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2007-2012 Steven Levithan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /ballista/static/gis/css/ol3.css: -------------------------------------------------------------------------------- 1 | .switch-type { 2 | background-repeat: no-repeat; 3 | cursor: pointer; 4 | top: 0.5em; 5 | width: 22px; 6 | height: 20px; 7 | } 8 | 9 | .type-Point { 10 | background-image: url("../img/draw_point_off.svg"); 11 | right: 5px; 12 | } 13 | .type-Point.type-active { 14 | background-image: url("../img/draw_point_on.svg"); 15 | } 16 | 17 | .type-LineString { 18 | background-image: url("../img/draw_line_off.svg"); 19 | right: 30px; 20 | } 21 | .type-LineString.type-active { 22 | background-image: url("../img/draw_line_on.svg"); 23 | } 24 | 25 | .type-Polygon { 26 | background-image: url("../img/draw_polygon_off.svg"); 27 | right: 55px; 28 | } 29 | .type-Polygon.type-active { 30 | background-image: url("../img/draw_polygon_on.svg"); 31 | } 32 | -------------------------------------------------------------------------------- /ballista/static/gis/img/draw_line_off.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ballista/static/gis/img/draw_line_on.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ballista/static/gis/img/draw_point_off.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ballista/static/gis/img/draw_point_on.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ballista/static/gis/img/draw_polygon_off.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ballista/static/gis/img/draw_polygon_on.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/python_requirements.txt: -------------------------------------------------------------------------------- 1 | Django 2 | psycopg2 3 | gunicorn 4 | django-extensions 5 | ipython 6 | django-model-utils 7 | geopandas 8 | virtualenv 9 | virtualenvwrapper 10 | -------------------------------------------------------------------------------- /resources/r-requirements.R: -------------------------------------------------------------------------------- 1 | core <- c("classInt", "DCluster", "deldir", "geoR", "gstat", "maptools", 2 | "RandomFields", "raster", "RColorBrewer", "rgdal", "sp", "spatstat", 3 | "spdep", "splancs","spgrass6", "rgeos","ncdf", "RSAGA") 4 | 5 | optional <- c("ade4", "adehabitat", "adehabitatHR", "adehabitatHS", "adehabitatLT", "adehabitatMA", "ads", "akima", "ash", "aspace", "automap", "CircSpatial", "clustTool", "CompRandFld", "constrainedKriging", "cshapes", "diseasemapping", "DSpat", "ecespa", "fields", "FieldSim", "gdistance", "Geneland", "GEOmap", "geomapdata", "geonames", "geoRglm", "geosphere", "GeoXp", "glmmBUGS", "gmaps", "gmt", "Guerry", "hdeco", "intamap", "mapdata", "mapproj", "maps", "MarkedPointProcess", "MBA", "ModelMap", "ncf", "nlme", "pastecs", "PBSmapping", "PBSmodelling", "psgp", "ramps", "RArcInfo", "regress", "RgoogleMaps", "RPyGeo", "RSurvey", "rworldmap", "sgeostat", "shapefiles", "sparr", "spatcounts", "spatgraphs", "spatial", "spatialCovariance", "SpatialExtremes", "spatialkernel", "spatialsegregation", "spBayes", "spcosa", "spgwr", "sphet", "spsurvey", "SQLiteMap", "Stem", "tgp", "trip", "tripack", "tripEstimation", "UScensus2000", "vardiag", "vegan") 6 | 7 | non_spatial <- c("RPostgresql","RSQLite","RODBC") 8 | 9 | packagelist <- core 10 | 11 | print("Beginning installation of required spatial packages.") 12 | 13 | for (i in packagelist) { 14 | #Generic Version followed by Australian Repos 15 | #install.packages(i, repos= "http://cran.r-project.org", lib = "/usr/local/lib/R/site-library/" , dependencies = TRUE) 16 | #For AU builds 17 | #install.packages(i, repos= "http://cran.ms.unimelb.edu.au/", lib = "/usr/local/lib/R/site-library/") 18 | #For EU builds 19 | #install.packages(i, repos= "http://stat.ethz.ch/CRAN/", lib = "/usr/local/lib/R/site-library/") 20 | #For US builds 21 | install.packages(i, repos= "http://cran.rstudio.com/", lib = "/usr/local/lib/R/site-library/") 22 | output <- paste("Finished installing",i,sep=" ") 23 | print(output) 24 | } 25 | 26 | print("Beginning installation of optional spatial packages.") 27 | 28 | for (o in optional) { 29 | 30 | #Generic Version followed by Australian Repos 31 | #install.packages(i, repos= "http://cran.r-project.org", lib = "/usr/local/lib/R/site-library/" , dependencies = TRUE) 32 | #For AU builds 33 | #install.packages(i, repos= "http://cran.ms.unimelb.edu.au/", lib = "/usr/local/lib/R/site-library/") 34 | #For EU builds 35 | #install.packages(i, repos= "http://stat.ethz.ch/CRAN/", lib = "/usr/local/lib/R/site-library/") 36 | #For US builds 37 | install.packages(i, repos= "http://cran.rstudio.com/", lib = "/usr/local/lib/R/site-library/") 38 | output <- paste("Finished installing",o,sep=" ") 39 | print(output) 40 | 41 | } 42 | 43 | print("Beginning installation of required optional non-spatial packages.") 44 | 45 | for (n in non_spatial) { 46 | 47 | #Generic Version followed by Australian Repos 48 | #install.packages(i, repos= "http://cran.r-project.org", lib = "/usr/local/lib/R/site-library/" , dependencies = TRUE) 49 | #For AU builds 50 | #install.packages(i, repos= "http://cran.ms.unimelb.edu.au/", lib = "/usr/local/lib/R/site-library/") 51 | #For EU builds 52 | #install.packages(i, repos= "http://stat.ethz.ch/CRAN/", lib = "/usr/local/lib/R/site-library/") 53 | #For US builds 54 | install.packages(i, repos= "http://cran.rstudio.com/", lib = "/usr/local/lib/R/site-library/") 55 | output <- paste("Finished installing",o,sep=" ") 56 | print(output) 57 | 58 | } 59 | 60 | 61 | q() -------------------------------------------------------------------------------- /resources/spf13-script.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2014 Steve Francia 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ############################ SETUP PARAMETERS 18 | app_name='spf13-vim' 19 | [ -z "$APP_PATH" ] && APP_PATH="$HOME/.spf13-vim-3" 20 | [ -z "$REPO_URI" ] && REPO_URI='https://github.com/spf13/spf13-vim.git' 21 | [ -z "$REPO_BRANCH" ] && REPO_BRANCH='3.0' 22 | debug_mode='0' 23 | fork_maintainer='0' 24 | [ -z "$VUNDLE_URI" ] && VUNDLE_URI="https://github.com/gmarik/vundle.git" 25 | 26 | ############################ BASIC SETUP TOOLS 27 | msg() { 28 | printf '%b\n' "$1" >&2 29 | } 30 | 31 | success() { 32 | if [ "$ret" -eq '0' ]; then 33 | msg "\33[32m[✔]\33[0m ${1}${2}" 34 | fi 35 | } 36 | 37 | error() { 38 | msg "\33[31m[✘]\33[0m ${1}${2}" 39 | exit 1 40 | } 41 | 42 | debug() { 43 | if [ "$debug_mode" -eq '1' ] && [ "$ret" -gt '1' ]; then 44 | msg "An error occurred in function \"${FUNCNAME[$i+1]}\" on line ${BASH_LINENO[$i+1]}, we're sorry for that." 45 | fi 46 | } 47 | 48 | program_exists() { 49 | local ret='0' 50 | type $1 >/dev/null 2>&1 || { local ret='1'; } 51 | 52 | # throw error on non-zero return value 53 | if [ ! "$ret" -eq '0' ]; then 54 | error "You must have '$1' installed to continue." 55 | fi 56 | } 57 | 58 | variable_set() { 59 | if [ -z "$1" ]; then 60 | error "You must have your HOME environmental variable set to continue." 61 | fi 62 | } 63 | 64 | lnif() { 65 | if [ -e "$1" ]; then 66 | ln -sf "$1" "$2" 67 | fi 68 | ret="$?" 69 | debug 70 | } 71 | 72 | ############################ SETUP FUNCTIONS 73 | 74 | do_backup() { 75 | if [ -e "$1" ] || [ -e "$2" ] || [ -e "$3" ]; then 76 | msg "Attempting to back up your original vim configuration." 77 | today=`date +%Y%m%d_%s` 78 | for i in "$1" "$2" "$3"; do 79 | [ -e "$i" ] && [ ! -L "$i" ] && mv -v "$i" "$i.$today"; 80 | done 81 | ret="$?" 82 | success "Your original vim configuration has been backed up." 83 | debug 84 | fi 85 | } 86 | 87 | sync_repo() { 88 | local repo_path="$1" 89 | local repo_uri="$2" 90 | local repo_branch="$3" 91 | local repo_name="$4" 92 | 93 | msg "Trying to update $repo_name" 94 | 95 | if [ ! -e "$repo_path" ]; then 96 | mkdir -p "$repo_path" 97 | git clone -b "$repo_branch" "$repo_uri" "$repo_path" 98 | ret="$?" 99 | success "Successfully cloned $repo_name." 100 | else 101 | cd "$repo_path" && git pull origin "$repo_branch" 102 | ret="$?" 103 | success "Successfully updated $repo_name" 104 | fi 105 | 106 | debug 107 | } 108 | 109 | create_symlinks() { 110 | local source_path="$1" 111 | local target_path="$2" 112 | 113 | lnif "$source_path/.vimrc" "$target_path/.vimrc" 114 | lnif "$source_path/.vimrc.bundles" "$target_path/.vimrc.bundles" 115 | lnif "$source_path/.vimrc.before" "$target_path/.vimrc.before" 116 | lnif "$source_path/.vim" "$target_path/.vim" 117 | 118 | touch "$target_path/.vimrc.local" 119 | 120 | ret="$?" 121 | success "Setting up vim symlinks." 122 | debug 123 | } 124 | 125 | setup_fork_mode() { 126 | local source_path="$2" 127 | local target_path="$3" 128 | 129 | if [ "$1" -eq '1' ]; then 130 | touch "$target_path/.vimrc.fork" 131 | touch "$target_path/.vimrc.bundles.fork" 132 | touch "$target_path/.vimrc.before.fork" 133 | 134 | lnif "$source_path/.vimrc.fork" "$target_path/.vimrc.fork" 135 | lnif "$source_path/.vimrc.bundles.fork" "$target_path/.vimrc.bundles.fork" 136 | lnif "$source_path/.vimrc.before.fork" "$target_path/.vimrc.before.fork" 137 | 138 | ret="$?" 139 | success "Created fork maintainer files." 140 | debug 141 | fi 142 | } 143 | 144 | setup_vundle() { 145 | local system_shell="$SHELL" 146 | export SHELL='/bin/sh' 147 | 148 | vim \ 149 | -u "$1" \ 150 | "+set nomore" \ 151 | "+BundleInstall!" \ 152 | "+BundleClean" \ 153 | "+qall" 154 | 155 | export SHELL="$system_shell" 156 | 157 | success "Now updating/installing plugins using Vundle" 158 | debug 159 | } 160 | 161 | ############################ MAIN() 162 | variable_set "$HOME" 163 | program_exists "vim" 164 | program_exists "git" 165 | 166 | do_backup "$HOME/.vim" \ 167 | "$HOME/.vimrc" \ 168 | "$HOME/.gvimrc" 169 | 170 | sync_repo "$APP_PATH" \ 171 | "$REPO_URI" \ 172 | "$REPO_BRANCH" \ 173 | "$app_name" 174 | 175 | create_symlinks "$APP_PATH" \ 176 | "$HOME" 177 | 178 | setup_fork_mode "$fork_maintainer" \ 179 | "$APP_PATH" \ 180 | "$HOME" 181 | 182 | sync_repo "$HOME/.vim/bundle/vundle" \ 183 | "$VUNDLE_URI" \ 184 | "master" \ 185 | "vundle" 186 | 187 | setup_vundle "$APP_PATH/.vimrc.bundles.default" 188 | 189 | msg "\nThanks for installing $app_name." 190 | msg "© `date +%Y` http://vim.spf13.com/" 191 | --------------------------------------------------------------------------------