├── ckanext
├── openafrica
│ ├── lib
│ │ ├── __init__.py
│ │ └── helpers.py
│ ├── public
│ │ ├── bg.jpg
│ │ ├── cmx-home.jpg
│ │ ├── blue_img_bg.png
│ │ ├── green_img_bg.png
│ │ ├── orange_img_bg.png
│ │ ├── yellow_img_bg.png
│ │ ├── images
│ │ │ ├── logos
│ │ │ │ ├── c4a.png
│ │ │ │ ├── ok.png
│ │ │ │ ├── wbg.png
│ │ │ │ ├── google.png
│ │ │ │ ├── icfj.png
│ │ │ │ ├── CfAlogoBW.png
│ │ │ │ ├── open-africa.jpg
│ │ │ │ ├── open-africa.png
│ │ │ │ ├── openafrica.jpg
│ │ │ │ └── openafrica.png
│ │ │ └── icons
│ │ │ │ └── ckan.ico
│ │ └── icons
│ │ │ ├── search.svg
│ │ │ ├── facebook.svg
│ │ │ ├── twitter.svg
│ │ │ ├── github.svg
│ │ │ ├── linkedin.svg
│ │ │ ├── instagram.svg
│ │ │ └── slack.svg
│ ├── templates
│ │ ├── user
│ │ │ ├── read_base.html
│ │ │ └── list.html
│ │ ├── organization
│ │ │ ├── snippets
│ │ │ │ ├── tag_list.html
│ │ │ │ └── organization.html
│ │ │ ├── about.html
│ │ │ ├── read_base.html
│ │ │ ├── old_read_base.html
│ │ │ └── read.html
│ │ ├── home
│ │ │ ├── snippets
│ │ │ │ ├── home_partner_logos.html
│ │ │ │ ├── subscription.html
│ │ │ │ ├── search.html
│ │ │ │ ├── about_text.html
│ │ │ │ ├── privacy_text.html
│ │ │ │ ├── toc_text.html
│ │ │ │ ├── accessibility_text.html
│ │ │ │ ├── moderation_text.html
│ │ │ │ ├── coc_text.html
│ │ │ │ └── faq_text.html
│ │ │ ├── about
│ │ │ │ ├── faq.html
│ │ │ │ ├── privacy.html
│ │ │ │ ├── coc.html
│ │ │ │ ├── toc.html
│ │ │ │ ├── moderation.html
│ │ │ │ ├── accessibility.html
│ │ │ │ └── contact.html
│ │ │ ├── robots.txt
│ │ │ └── index.html
│ │ ├── atlas.html
│ │ ├── base.html
│ │ ├── snippets
│ │ │ ├── language_selector.html
│ │ │ ├── package_list.html
│ │ │ ├── search_result_text.html
│ │ │ └── package_item.html
│ │ ├── package
│ │ │ └── search.html
│ │ ├── header.html
│ │ ├── dataset-page.html
│ │ ├── page.html
│ │ └── footer.html
│ ├── __init__.py
│ ├── assets
│ │ ├── webassets.yml
│ │ ├── js
│ │ │ └── datamx_load_apps.js
│ │ └── css
│ │ │ └── bootstrap-responsive.min.css
│ ├── blueprint.py
│ └── plugin.py
└── __init__.py
├── deploy
├── ansible.cfg
├── roles
│ ├── deploy
│ │ ├── tasks
│ │ │ ├── main.yml
│ │ │ └── deploy.yml
│ │ └── defaults
│ │ │ └── main.yml
│ ├── base
│ │ ├── vars
│ │ │ └── main.yml
│ │ └── tasks
│ │ │ ├── main.yml
│ │ │ └── create_swap_file.yml
│ ├── db
│ │ ├── templates
│ │ │ ├── pgdg.list.j2
│ │ │ ├── pg_hba-9.3.conf.j2
│ │ │ └── postgresql-9.3.conf.j2
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── defaults
│ │ │ └── main.yml
│ ├── nginx
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── templates
│ │ │ └── nginx_org_packages_ubuntu.list.j2
│ │ ├── files
│ │ │ ├── proxy_params
│ │ │ ├── extra-security.conf
│ │ │ └── nginx.conf
│ │ └── tasks
│ │ │ └── main.yml
│ ├── solr
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── main.yml
│ │ │ ├── solr-cores.yml
│ │ │ └── solr.yml
│ │ ├── files
│ │ │ └── log4j.properties
│ │ ├── defaults
│ │ │ └── main.yml
│ │ └── templates
│ │ │ ├── init.d-solr.j2
│ │ │ └── solr.in.sh.j2
│ ├── apache
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── templates
│ │ │ └── ports.conf.j2
│ │ └── tasks
│ │ │ └── main.yml
│ └── ckan
│ │ ├── handlers
│ │ └── main.yml
│ │ ├── templates
│ │ ├── apache
│ │ │ ├── ckan-apache.wsgi.j2
│ │ │ └── 000-ckan-default.conf.j2
│ │ ├── nginx
│ │ │ └── default-vhost.conf.j2
│ │ ├── supervisor.conf.j2
│ │ └── production-2.3.ini.j2
│ │ ├── defaults
│ │ └── main.yml
│ │ └── tasks
│ │ └── main.yml
├── env_vars
│ ├── ubuntu.yml
│ ├── base.yml
│ └── vagrant.yml
├── deploy.yml
├── vagrant.yml
└── Vagrantfile
├── .gitignore
├── setup.py
└── README.md
/ckanext/openafrica/lib/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/deploy/ansible.cfg:
--------------------------------------------------------------------------------
1 | [defaults]
2 | host_key_checking=False
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | ckanext_openafrica.egg-info/
3 | *.swp
4 | env/*
5 | build/
6 |
--------------------------------------------------------------------------------
/deploy/roles/deploy/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - include: deploy.yml
4 | tags: deploy
5 |
--------------------------------------------------------------------------------
/deploy/env_vars/ubuntu.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # Git settings.
4 | setup_git_repo: yes
5 | git_branch: master
6 |
--------------------------------------------------------------------------------
/deploy/roles/base/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | create_swap_file: no
4 | swap_file_path: /swapfile
5 | swap_file_size_kb: 512
--------------------------------------------------------------------------------
/ckanext/openafrica/public/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/bg.jpg
--------------------------------------------------------------------------------
/ckanext/openafrica/public/cmx-home.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/cmx-home.jpg
--------------------------------------------------------------------------------
/ckanext/openafrica/public/blue_img_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/blue_img_bg.png
--------------------------------------------------------------------------------
/ckanext/openafrica/public/green_img_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/green_img_bg.png
--------------------------------------------------------------------------------
/ckanext/openafrica/public/orange_img_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/orange_img_bg.png
--------------------------------------------------------------------------------
/ckanext/openafrica/public/yellow_img_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/yellow_img_bg.png
--------------------------------------------------------------------------------
/deploy/roles/db/templates/pgdg.list.j2:
--------------------------------------------------------------------------------
1 | # PGDG apt repo lists
2 | deb http://apt.postgresql.org/pub/repos/apt/ {{ ansible_distribution_release }}-pgdg main
3 |
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/logos/c4a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/logos/c4a.png
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/logos/ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/logos/ok.png
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/logos/wbg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/logos/wbg.png
--------------------------------------------------------------------------------
/deploy/roles/nginx/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: defaults/main.yml
3 |
4 | # nginx branch to use
5 | nginx_branch: stable
6 |
7 | # vim: set sw=2 ts=2:
8 |
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/icons/ckan.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/icons/ckan.ico
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/logos/google.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/logos/google.png
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/logos/icfj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/logos/icfj.png
--------------------------------------------------------------------------------
/deploy/env_vars/base.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | git_repo: https://github.com/CodeForAfrica/ckanext-openafrica
4 |
5 | project_name: openafrica
6 | application_name: openafrica
7 |
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/logos/CfAlogoBW.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/logos/CfAlogoBW.png
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/logos/open-africa.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/logos/open-africa.jpg
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/logos/open-africa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/logos/open-africa.png
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/logos/openafrica.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/logos/openafrica.jpg
--------------------------------------------------------------------------------
/ckanext/openafrica/public/images/logos/openafrica.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeForAfrica/ckanext-openafrica/master/ckanext/openafrica/public/images/logos/openafrica.png
--------------------------------------------------------------------------------
/deploy/roles/nginx/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: handlers/main.yml
3 |
4 | - name: reload nginx
5 | service: name=nginx state=reloaded
6 |
7 | # vim: set sw=2 ts=2:
8 |
--------------------------------------------------------------------------------
/deploy/roles/solr/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: handlers/main.yml
3 |
4 | - name: restart solr
5 | service: name=solr state=restarted
6 |
7 | # vim: set sw=2 ts=2:
8 |
--------------------------------------------------------------------------------
/deploy/roles/db/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: handlers/main.yml
3 |
4 | - name: restart postgres
5 | service: name=postgresql state=reloaded
6 |
7 | # vim: set sw=2 ts=2:
8 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/user/read_base.html:
--------------------------------------------------------------------------------
1 | {% ckan_extends %}
2 |
3 | {% block meta %}
4 | {{ super() }}
5 |
6 | {% endblock %}
7 |
--------------------------------------------------------------------------------
/ckanext/__init__.py:
--------------------------------------------------------------------------------
1 | # this is a namespace package
2 | try:
3 | import pkg_resources
4 | pkg_resources.declare_namespace(__name__)
5 | except ImportError:
6 | import pkgutil
7 | __path__ = pkgutil.extend_path(__path__, __name__)
8 |
--------------------------------------------------------------------------------
/ckanext/openafrica/__init__.py:
--------------------------------------------------------------------------------
1 | # this is a namespace package
2 | try:
3 | import pkg_resources
4 | pkg_resources.declare_namespace(__name__)
5 | except ImportError:
6 | import pkgutil
7 | __path__ = pkgutil.extend_path(__path__, __name__)
8 |
--------------------------------------------------------------------------------
/deploy/roles/apache/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: handlers/main.yml
3 |
4 | - name: reload apache2
5 | service: name=apache2 state=reloaded
6 |
7 | - name: stop apache2
8 | service: name=apache2 state=stopped
9 |
10 | # vim: set sw=2 ts=2:
11 |
--------------------------------------------------------------------------------
/deploy/env_vars/vagrant.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # Git settings.
4 | setup_git_repo: yes
5 | git_branch: develop
6 |
7 |
8 | # Database settings.
9 | db_user: "{{ application_name }}"
10 | db_name: "{{ application_name }}"
11 | db_password: "{{ application_name }}"
12 |
13 |
--------------------------------------------------------------------------------
/deploy/roles/apache/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: defaults/main.yml
3 |
4 | # since we'll have nginx on the front(80),
5 | # we need to set apache2 to listen to another port(8080)
6 | apache2_http_port: 8080
7 | apache2_https_port: 8443
8 |
9 | # vim: set sw=2 ts=2:
10 |
--------------------------------------------------------------------------------
/deploy/roles/nginx/templates/nginx_org_packages_ubuntu.list.j2:
--------------------------------------------------------------------------------
1 | {% if nginx_branch == "stable" %}
2 | deb http://nginx.org/packages/ubuntu/ {{ ansible_distribution_release }} nginx
3 | {% else %}
4 | deb http://nginx.org/packages/mainline/ubuntu/ {{ ansible_distribution_release }} nginx
5 | {% endif %}
6 |
--------------------------------------------------------------------------------
/deploy/roles/nginx/files/proxy_params:
--------------------------------------------------------------------------------
1 | proxy_set_header Host $http_host;
2 | proxy_set_header X-Real-IP $remote_addr;
3 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
4 | proxy_set_header X-Forwarded-Proto $scheme;
5 | proxy_connect_timeout 3600;
6 | proxy_send_timeout 3600;
7 | proxy_read_timeout 3600;
8 |
--------------------------------------------------------------------------------
/deploy/roles/ckan/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: handlers/main.yml
3 |
4 | - name: reload apache2
5 | service: name=apache2 state=reloaded
6 |
7 | - name: reload solr
8 | service: name=solr state=restarted
9 |
10 | - name: reload nginx
11 | service: name=nginx state=reloaded
12 |
13 | # vim: set sw=2 ts=2:
14 |
--------------------------------------------------------------------------------
/deploy/deploy.yml:
--------------------------------------------------------------------------------
1 | - name: Deploy the application
2 | hosts: tag_Name_openAFRICA_main_4
3 | #hosts: tag_openafricastaging_openafricastaging
4 | remote_user: ubuntu
5 | vars:
6 | - setup_git_repo: yes
7 | - update_apt_cache: yes
8 | vars_files:
9 | - env_vars/base.yml
10 | - env_vars/ubuntu.yml
11 |
12 | roles:
13 | - deploy
14 |
--------------------------------------------------------------------------------
/deploy/roles/deploy/tasks/deploy.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: get openafrica
3 | action: git repo=https://github.com/CodeForAfrica/ckanext-openafrica dest={{ ckan_virtualenv }}/src/ckanext-openafrica version=master
4 |
5 | - name: run setup.py develop for openafrica
6 | action: command chdir={{ ckan_virtualenv }}/src/ckanext-openafrica/ ../../bin/python setup.py develop
7 |
8 |
--------------------------------------------------------------------------------
/deploy/roles/deploy/defaults/main.yml:
--------------------------------------------------------------------------------
1 |
2 | # ckan user details
3 | ckan_user: {
4 | name: "ckan",
5 | system: "yes",
6 | home_path: "/usr/lib/ckan",
7 | shell: "/sbin/nologin",
8 | description: "CKAN User"
9 | }
10 |
11 | # CKAN default site name
12 | ckan_site_name: "default"
13 |
14 | #default ckan virtualenv path
15 | ckan_virtualenv: "{{ ckan_user.home_path }}/{{ ckan_site_name }}"
16 |
--------------------------------------------------------------------------------
/deploy/vagrant.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Create a {{ application_name }} virtual machine via vagrant
4 | hosts: all
5 | sudo: yes
6 | sudo_user: root
7 | remote_user: vagrant
8 | vars:
9 | - setup_git_repo: yes
10 | - update_apt_cache: yes
11 | vars_files:
12 | - env_vars/base.yml
13 | - env_vars/vagrant.yml
14 |
15 | roles:
16 | - base
17 | - apache
18 | - db
19 | - solr
20 | - nginx
21 | - ckan
22 |
--------------------------------------------------------------------------------
/deploy/roles/ckan/templates/apache/ckan-apache.wsgi.j2:
--------------------------------------------------------------------------------
1 | import os
2 | activate_this = os.path.join('{{ ckan_virtualenv }}/bin/activate_this.py')
3 | execfile(activate_this, dict(__file__=activate_this))
4 |
5 | from paste.deploy import loadapp
6 | config_filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'production.ini')
7 | from paste.script.util.logging_config import fileConfig
8 | fileConfig(config_filepath)
9 | application = loadapp('config:%s' % config_filepath)
10 |
--------------------------------------------------------------------------------
/deploy/roles/apache/templates/ports.conf.j2:
--------------------------------------------------------------------------------
1 | # If you just change the port or add more ports here, you will likely also
2 | # have to change the VirtualHost statement in
3 | # /etc/apache2/sites-enabled/000-default.conf
4 |
5 | Listen {{ apache2_http_port }}
6 |
7 |
8 | Listen {{ apache2_https_port }}
9 |
10 |
11 |
12 | Listen {{ apache2_https_port }}
13 |
14 |
15 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
16 |
--------------------------------------------------------------------------------
/ckanext/openafrica/public/icons/search.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ckanext/openafrica/public/icons/facebook.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/organization/snippets/tag_list.html:
--------------------------------------------------------------------------------
1 | {#
2 | render a list of tags linking to the dataset search page
3 | tags: list of tags
4 | #}
5 | {% set _class = _class or 'tag-list' %}
6 | {% set _tag_class=_tag_class or 'tag' %}
7 | {% set _organization_url=_organization_url or 'packages' %}
8 |
15 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/snippets/home_partner_logos.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/organization/about.html:
--------------------------------------------------------------------------------
1 | {% extends "organization/old_read_base.html" %}
2 |
3 | {% block subtitle %}{{ _('About') }} - {{ super() }}{% endblock %}
4 |
5 | {% block primary_content_inner %}
6 | {% block page_heading %}{{ c.group_dict.display_name }}{% endblock %}
7 | {% block organization_description %}
8 | {% if c.group_dict.description %}
9 | {{ h.render_markdown(c.group_dict.description) }}
10 | {% endif %}
11 | {% endblock %}
12 | {% block organization_extras %}
13 | {% snippet 'snippets/additional_info.html', extras = h.sorted_extras(c.group_dict.extras) %}
14 | {% endblock %}
15 | {% endblock %}
16 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/about/faq.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 |
3 | {% block subtitle %}{{ _('FAQs') }}{% endblock %}
4 |
5 | {% block breadcrumb_content %}
6 | {% link_for _('About'), controller='home', action='about' %}
7 | {% link_for _('FAQs'), named_route='openafrica.faq' %}
8 | {% endblock %}
9 |
10 | {% block primary %}
11 |
12 |
13 | {% block faq %}
14 |
{{ _('FAQs') }}
15 | {% snippet 'home/snippets/faq_text.html' %}
16 | {% endblock %}
17 |
18 |
19 | {% endblock %}
20 |
21 | {% block secondary %}{% endblock %}
22 |
--------------------------------------------------------------------------------
/ckanext/openafrica/assets/webassets.yml:
--------------------------------------------------------------------------------
1 | openafrica-js:
2 | output: ckanext-openafrica/openafrica.js
3 | contents:
4 | - js/datamx_load_apps.js
5 | - js/bootstrap.min.js
6 |
7 | openafrica-bootstrap-js:
8 | output: ckanext-openafrica/openafrica_bootstrap.js
9 | contents:
10 | - js/bootstrap.min.js
11 |
12 | openafrica-css:
13 | output: ckanext-openafrica/openafrica.css
14 | contents:
15 | - css/bootstrap-responsive.min.css
16 |
17 | openafrica-css-theme:
18 | output: ckanext-openafrica/openafrica-theme.css
19 | contents:
20 | - css/openafrica_theme.css
21 |
22 | openafrica-main-css:
23 | output: ckanext-openafrica/openafrica-main.css
24 | contents:
25 | - css/main.css
26 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/about/privacy.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 |
3 | {% block subtitle %}{{ _('Privacy') }}{% endblock %}
4 |
5 | {% block breadcrumb_content %}
6 | {% link_for _('About'), controller='home', action='about' %}
7 | {% link_for _('Privacy'), named_route='openafrica.privacy' %}
8 | {% endblock %}
9 |
10 | {% block primary %}
11 |
12 |
13 | {% block privacy %}
14 |
{{ _('Privacy') }}
15 | {% snippet 'home/snippets/privacy_text.html' %}
16 | {% endblock %}
17 |
18 |
19 | {% endblock %}
20 |
21 | {% block secondary %}{% endblock %}
22 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/about/coc.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 |
3 | {% block subtitle %}{{ _('Code of Conduct') }}{% endblock %}
4 |
5 | {% block breadcrumb_content %}
6 | {% link_for _('About'), controller='home', action='about' %}
7 | {% link_for _('Code of Conduct'), named_route='openafrica.coc' %}
8 | {% endblock %}
9 |
10 | {% block primary %}
11 |
12 |
13 | {% block coc %}
14 |
{{ _('Code of Conduct') }}
15 | {% snippet 'home/snippets/coc_text.html' %}
16 | {% endblock %}
17 |
18 |
19 | {% endblock %}
20 |
21 | {% block secondary %}{% endblock %}
22 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/about/toc.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 |
3 | {% block subtitle %}{{ _('Terms & Conditions') }}{% endblock %}
4 |
5 | {% block breadcrumb_content %}
6 | {% link_for _('About'), controller='home', action='about' %}
7 | {% link_for _('Terms & Conditions'), named_route='openafrica.toc' %}
8 | {% endblock %}
9 |
10 | {% block primary %}
11 |
12 |
13 | {% block toc %}
14 |
{{ _('Terms & Conditions') }}
15 | {% snippet 'home/snippets/toc_text.html' %}
16 | {% endblock %}
17 |
18 |
19 | {% endblock %}
20 |
21 | {% block secondary %}{% endblock %}
22 |
--------------------------------------------------------------------------------
/deploy/roles/solr/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: tasks/main.yml
3 |
4 | - name: Install Solr deps
5 | apt: name={{ item }} state=present install_recommends=no update_cache=yes cache_valid_time=3600
6 | with_items:
7 | - unzip
8 | - tar
9 |
10 | - name: Add Oracle Java PPA
11 | apt_repository: repo='ppa:webupd8team/java' state=present
12 | tags: java
13 |
14 | - name: Accept Oracle license
15 | shell: echo debconf shared/accepted-oracle-license-v1-1 select true | debconf-set-selections
16 | tags: java
17 |
18 | - name: Install Oracle Java 8
19 | apt: name=oracle-java8-installer state=present update_cache=yes
20 | tags: java
21 |
22 | - include: solr.yml
23 | tags: solr
24 |
25 | # vim: set sw=2 ts=2:
26 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/about/moderation.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 |
3 | {% block subtitle %}{{ _('Moderation Policy') }}{% endblock %}
4 |
5 | {% block breadcrumb_content %}
6 | {% link_for _('About'), controller='home', action='about' %}
7 | {% link_for _('Moderation Policy'), named_route='openafrica.moderation' %}
8 | {% endblock %}
9 |
10 | {% block primary %}
11 |
12 |
13 | {% block moderation %}
14 |
{{ _('Moderation Policy') }}
15 | {% snippet 'home/snippets/moderation_text.html' %}
16 | {% endblock %}
17 |
18 |
19 | {% endblock %}
20 |
21 | {% block secondary %}{% endblock %}
22 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/organization/read_base.html:
--------------------------------------------------------------------------------
1 | {% extends 'page.html' %}
2 |
3 | {% block content %}
4 |
5 |
6 |
7 | {% block primary_content %}
8 | {% endblock %}
9 |
10 |
11 |
12 | {% block package_list %}
13 | {% endblock %}
14 | {% block page_pagination %}
15 | {% endblock %}
16 |
17 |
18 |
19 | {% block apps_list %}
20 | {% endblock %}
21 |
22 |
23 |
24 | {% endblock %}
25 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/about/accessibility.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 |
3 | {% block subtitle %}{{ _('Accessibility') }}{% endblock %}
4 |
5 | {% block breadcrumb_content %}
6 | {% link_for _('About'), controller='home', action='about' %}
7 | {% link_for _('Accessibility'), named_route='openafrica.accessibility' %}
8 | {% endblock %}
9 |
10 | {% block primary %}
11 |
12 |
13 | {% block accessibility %}
14 |
{{ _('Accessibility') }}
15 | {% snippet 'home/snippets/accessibility_text.html' %}
16 | {% endblock %}
17 |
18 |
19 | {% endblock %}
20 |
21 | {% block secondary %}{% endblock %}
22 |
--------------------------------------------------------------------------------
/ckanext/openafrica/public/icons/twitter.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/deploy/roles/ckan/templates/nginx/default-vhost.conf.j2:
--------------------------------------------------------------------------------
1 | proxy_cache_path /var/cache/nginx_cache levels=1:2 keys_zone=cache:30m max_size=250m;
2 | proxy_temp_path /var/cache/nginx_proxy 1 2;
3 |
4 | server {
5 | client_max_body_size 100M;
6 | location / {
7 | proxy_pass http://127.0.0.1:{{ apache2_http_port }}/;
8 | proxy_set_header X-Forwarded-For $remote_addr;
9 | proxy_set_header Host $host;
10 | proxy_cache cache;
11 | proxy_cache_bypass $cookie_auth_tkt;
12 | proxy_no_cache $cookie_auth_tkt;
13 | proxy_cache_valid 30m;
14 | proxy_cache_key $host$scheme$proxy_host$request_uri;
15 | # In emergency comment out line to force caching
16 | # proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
17 | }
18 | }
19 |
20 | # vim: sw=4 ts=4:
21 |
--------------------------------------------------------------------------------
/deploy/roles/nginx/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: tasks/main.yml
3 |
4 | - name: Add nginx.org apt signing key
5 | apt_key: url=http://nginx.org/keys/nginx_signing.key state=present
6 |
7 | - name: Add nginx.org repo
8 | template: src=nginx_org_packages_ubuntu.list.j2 dest=/etc/apt/sources.list.d/nginx_org_packages_ubuntu.list mode=0644 owner=root group=root
9 |
10 | - name: Install nginx
11 | apt: name=nginx update_cache=yes state=latest
12 |
13 | - name: Copy nginx configs
14 | copy: src={{ item }} dest=/etc/nginx/{{ item }} mode=0644 owner=root group=root
15 | with_items:
16 | - extra-security.conf
17 | - nginx.conf
18 | - proxy_params
19 | notify:
20 | - reload nginx
21 |
22 | - name: Start & enable nginx service
23 | service: name=nginx state=started enabled=yes
24 |
25 | # vim: set sw=2 ts=2:
26 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/about/contact.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 |
3 | {% block subtitle %}{{ _('Contact Us') }}{% endblock %}
4 |
5 | {% block breadcrumb_content %}
6 | {% link_for _('About'), controller='home', action='about' %}
7 | {% link_for _('Contact Us'), named_route='openafrica.contact' %}
8 | {% endblock %}
9 |
10 | {% block primary %}
11 |
12 |
13 | {% block contact %}
14 |
{{ _('Contact Us') }}
15 |
16 | {% endblock %}
17 |
18 |
19 | {% endblock %}
20 |
21 | {% block secondary %}{% endblock %}
22 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/atlas.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {%- block page -%}
4 |
5 | {% block skip %}
6 |
7 | {% endblock %}
8 |
9 | {%- block header %}
10 | {% include "header.html" %}
11 | {% endblock -%}
12 |
13 | {%- block content %}
14 |
18 | {% endblock -%}
19 |
20 |
21 | {%- block footer %}
22 | {% include "footer.html" %}
23 | {% endblock -%}
24 | {%- endblock -%}
25 |
26 | {%- block scripts %}
27 | {% asset 'base/main' %}
28 | {% asset 'base/ckan' %}
29 | {% if g.tracking_enabled %}
30 | {% asset 'base/tracking.js' %}
31 | {% endif %}
32 | {{ super() }}
33 | {% endblock -%}
34 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/base.html:
--------------------------------------------------------------------------------
1 | {% ckan_extends %}
2 |
3 | {% block meta %}
4 | {{ super() }}
5 |
6 |
7 |
8 |
10 |
11 |
12 | {% endblock %}
13 |
14 | {% block styles %}
15 | {{ super() }}
16 | {% asset 'openafrica/openafrica-main-css' %}
17 | {% asset 'openafrica/openafrica-css' %}
18 | {% asset 'openafrica/openafrica-css-theme' %}
19 | {% endblock %}
20 |
--------------------------------------------------------------------------------
/deploy/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5 | VAGRANTFILE_API_VERSION = "2"
6 |
7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8 | config.vm.box = "ubuntu/trusty64"
9 | config.vm.box_url = "ubuntu/trusty64"
10 |
11 | config.vm.network :private_network, ip: "192.168.33.16"
12 |
13 | config.vm.provider :virtualbox do |vb|
14 | vb.customize ["modifyvm", :id, "--name", "openafrica", "--memory", "4096"]
15 | end
16 |
17 | config.vm.synced_folder "../", "/usr/lib/ckan/default"
18 |
19 | # Ansible provisioner.
20 | config.vm.provision "ansible" do |ansible|
21 | ansible.playbook = "vagrant.yml"
22 | ansible.host_key_checking = false
23 | ansible.verbose = "v"
24 | #ansible.tags = "a tag here in case you want to run only part of provision"
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/deploy/roles/base/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - include: create_swap_file.yml
4 | when: create_swap_file
5 | tags: swap
6 |
7 | - name: Ensure bash, OpenSSL, and libssl are the latest versions
8 | apt: name={{ item }} update_cache={{ update_apt_cache }} state=latest
9 | with_items:
10 | - bash
11 | - openssl
12 | - libssl-dev
13 | - libssl-doc
14 | tags: packages
15 |
16 | - name: Install base packages
17 | apt: name={{ item }} update_cache={{ update_apt_cache }} force=yes state=installed
18 | with_items:
19 | - build-essential
20 | - ntp
21 | - htop
22 | - git
23 | - libpq-dev
24 | - python-dev
25 | - libxml2-dev
26 | - libxslt1-dev
27 | - zlib1g-dev
28 | - python-pip
29 | - python-pycurl
30 | - supervisor
31 | - rabbitmq-server
32 | tags: packages
33 |
34 | - name: Install virtualenv
35 | pip: name=virtualenv
36 | tags: packages
37 |
--------------------------------------------------------------------------------
/ckanext/openafrica/assets/js/datamx_load_apps.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | ckan.module("datamx_load_apps", function($, _) {
4 | return {
5 | initialize: function() {
6 | var organization = this.options.organization;
7 | var api_url = "http://cmx-apps.herokuapp.com/v1/apps.json";
8 | var that = this;
9 |
10 | $.proxyAll(this, /_on/);
11 |
12 | // Get the apps from the APPs API
13 | $.ajax({
14 | url: api_url,
15 | data: {"organization": organization},
16 | success: function (data) {
17 | var index = 0;
18 | for(index in data) {
19 | that.sandbox.client.getTemplate("datamx_application_frame.html", data[index], that._onReceiveSnippet);
20 | }
21 | }
22 | });
23 | },
24 |
25 | _onReceiveSnippet: function(html) {
26 | console.log(html);
27 | this.el.append(html);
28 | }
29 | };
30 | });
31 |
--------------------------------------------------------------------------------
/ckanext/openafrica/public/icons/github.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/snippets/language_selector.html:
--------------------------------------------------------------------------------
1 | {% set current_url = request.environ.CKAN_CURRENT_URL %}
2 | {% set current_lang = request.environ.CKAN_LANG %}
3 |
14 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import find_packages, setup
2 |
3 | version = '0.9.1'
4 |
5 | setup(
6 | name='ckanext-openafrica',
7 | version=version,
8 | description="CKAN extension for openAFRICA.",
9 | long_description="""\
10 | """,
11 | classifiers=[],
12 | keywords='ckan ckanext openafrica extension data theme',
13 | author='Code for Africa',
14 | author_email='support@codeforafrica.org',
15 | url='http://openafrica.net',
16 | license='GPL v2.',
17 | packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
18 | namespace_packages=['ckanext', 'ckanext.openafrica'],
19 | include_package_data=True,
20 | zip_safe=False,
21 | install_requires=[
22 | # -*- Extra requirements: -*-
23 | ],
24 | entry_points=\
25 | """
26 | [ckan.plugins]
27 | # Add plugins here, eg
28 | # myplugin=ckanext.openafrica:PluginClass
29 | openafrica=ckanext.openafrica.plugin:OpenAfricaPlugin
30 | """,
31 | )
32 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/snippets/subscription.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Join the openAFRICA Community
4 |
We will not spam or share your email with third parties
5 |
6 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/snippets/search.html:
--------------------------------------------------------------------------------
1 | {% set tags = h.get_facet_items_dict('tags', limit=3) %}
2 | {% set placeholder = _('Search for datasets...') %}
3 |
4 |
18 |
--------------------------------------------------------------------------------
/deploy/roles/apache/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: tasks/main.yml
3 |
4 | - name: Install apache2 & mod-wsgi
5 | apt: name={{ item }} state=latest
6 | with_items:
7 | - apache2
8 | - libapache2-mod-wsgi
9 | - libapache2-mod-rpaf
10 | register: stop_apache
11 |
12 | - name: Temporarily stop apache2
13 | service: name=apache2 state=stopped
14 | when: stop_apache is defined and stop_apache|changed
15 |
16 | - name: Configure apache2 ports
17 | template: src="ports.conf.j2" dest="/etc/apache2/ports.conf" owner=root group=root mode=0644
18 | notify: reload apache2
19 |
20 | - name: Enable mod-wsgi & mod-rpaf apache2 modules
21 | command: /usr/sbin/a2enmod {{ item.mod }} creates={{ item.link }}
22 | with_items:
23 | - { mod: "wsgi", link: "/etc/apache2/mods-enabled/wsgi.load" }
24 | - { mod: "rpaf", link: "/etc/apache2/mods-enabled/rpaf.load" }
25 | notify: reload apache2
26 |
27 | - name: Start & enable apache2 service
28 | service: name=apache2 state=started enabled=yes
29 |
30 | # vim: set sw=2 ts=2:
31 |
--------------------------------------------------------------------------------
/deploy/roles/solr/files/log4j.properties:
--------------------------------------------------------------------------------
1 | # Logging level
2 | solr.log=${solr.solr.home}/../logs
3 | log4j.rootLogger=INFO, file, CONSOLE
4 |
5 | log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
6 |
7 | log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
8 | log4j.appender.CONSOLE.layout.ConversionPattern=%-4r [%t] %-5p %c %x [%X{collection} %X{shard} %X{replica} %X{core}] \u2013 %m%n
9 |
10 | #- size rotation with log cleanup.
11 | log4j.appender.file=org.apache.log4j.RollingFileAppender
12 | log4j.appender.file.MaxFileSize=4MB
13 | log4j.appender.file.MaxBackupIndex=9
14 |
15 | #- File to log to and log format
16 | log4j.appender.file.File=${solr.log}/solr.log
17 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
18 | log4j.appender.file.layout.ConversionPattern=%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS}; [%X{collection} %X{shard} %X{replica} %X{core}] %C; %m\n
19 |
20 | log4j.logger.org.apache.zookeeper=WARN
21 | log4j.logger.org.apache.hadoop=WARN
22 |
23 | # set to INFO to enable infostream log messages
24 | log4j.logger.org.apache.solr.update.LoggingInfoStream=OFF
25 |
--------------------------------------------------------------------------------
/ckanext/openafrica/public/icons/linkedin.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/deploy/roles/base/tasks/create_swap_file.yml:
--------------------------------------------------------------------------------
1 | - name: Create swap file
2 | command: dd if=/dev/zero of={{ swap_file_path }} bs=1024 count={{ swap_file_size_kb }}k
3 | creates="{{ swap_file_path }}"
4 | tags: swap.file.create
5 |
6 | - name: Change swap file permissions
7 | file: path="{{ swap_file_path }}"
8 | owner=root
9 | group=root
10 | mode=0600
11 | tags: swap.file.permissions
12 |
13 | - name: Check swap file type
14 | command: file {{ swap_file_path }}
15 | register: swapfile
16 | tags: swap.file.mkswap
17 |
18 | - name: Make swap file
19 | command: "sudo mkswap {{ swap_file_path }}"
20 | when: swapfile.stdout.find('swap file') == -1
21 | tags: swap.file.mkswap
22 |
23 | - name: Write swap entry in fstab
24 | mount: name=none
25 | src={{ swap_file_path }}
26 | fstype=swap
27 | opts=sw
28 | passno=0
29 | dump=0
30 | state=present
31 | tags: swap.fstab
32 |
33 | - name: Mount swap
34 | command: "swapon {{ swap_file_path }}"
35 | when: ansible_swaptotal_mb < 1
36 | tags: swap.file.swapon
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/snippets/about_text.html:
--------------------------------------------------------------------------------
1 | {% trans %}
2 |
3 | The openAFRICA platform initiative aims to be largest repository of Data on the Africa Continent. We are creating a Library of Congress of Data for African for use by Citizens, Media, Activists, Governments and Civil Society. The Platform will also provide structured linked data with a robust API (Application Programming Interface) that will allow Developers to build applications. The Platform will have a rating system that will rate uploaded Datasets according to 5 star deployment scheme for Open Data.
4 |
5 | openAFRICA is part of the Ujuzi Initiative which is created and funded by the African Media Initiative (AMI) , the World Bank Institute (WBI) and Google . The program is implemented by Code for Africa .
6 |
7 | {% endtrans %}
8 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/snippets/package_list.html:
--------------------------------------------------------------------------------
1 | {#
2 | Displays a list of datasets.
3 |
4 | packages - A list of packages to display.
5 | list_class - The class name for the list item.
6 | item_class - The class name to use on each item.
7 | hide_resources - If true hides the resources (default: false).
8 | banner - If true displays a popular banner (default: false).
9 | truncate - The length to trucate the description to (default: 180)
10 | truncate_title - The length to truncate the title to (default: 80).
11 |
12 | Example:
13 |
14 | {% snippet 'snippets/package_list.html', packages=c.datasets %}
15 |
16 | #}
17 | {% block package_list %}
18 | {% if packages %}
19 |
20 | {% block package_list_inner %}
21 | {% for package in packages %}
22 | {% snippet 'snippets/package_item.html', package=package, item_class=item_class, hide_resources=hide_resources, banner=banner, truncate=truncate, truncate_title=truncate_title %}
23 | {% endfor %}
24 | {% endblock %}
25 |
26 | {% endif %}
27 | {% endblock %}
28 |
--------------------------------------------------------------------------------
/deploy/roles/nginx/files/extra-security.conf:
--------------------------------------------------------------------------------
1 | # The X-Frame-Options header indicates whether a browser should be allowed
2 | # to render a page within a frame or iframe.
3 | add_header X-Frame-Options SAMEORIGIN;
4 |
5 | # MIME type sniffing security protection
6 | # There are very few edge cases where you wouldn't want this enabled.
7 | add_header X-Content-Type-Options nosniff;
8 |
9 | # The X-XSS-Protection header is used by Internet Explorer version 8+
10 | # The header instructs IE to enable its inbuilt anti-cross-site scripting filter.
11 | add_header X-XSS-Protection "1; mode=block";
12 |
13 | # with Content Security Policy (CSP) enabled (and a browser that supports it (http://caniuse.com/#feat=contentsecuritypolicy),
14 | # you can tell the browser that it can only download content from the domains you explicitly allow
15 | # CSP can be quite difficult to configure, and cause real issues if you get it wrong
16 | # There is website that helps you generate a policy here http://cspisawesome.com/
17 | # add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' https://www.google-analytics.com;";
18 |
--------------------------------------------------------------------------------
/ckanext/openafrica/public/icons/instagram.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/deploy/roles/nginx/files/nginx.conf:
--------------------------------------------------------------------------------
1 | user www-data;
2 | worker_processes auto;
3 |
4 | error_log /var/log/nginx/error.log error;
5 | pid /var/run/nginx.pid;
6 |
7 |
8 | events {
9 | worker_connections 1024;
10 | }
11 |
12 |
13 | http {
14 | include /etc/nginx/mime.types;
15 | default_type application/octet-stream;
16 |
17 | log_format main '$remote_addr - $remote_user [$time_local] "$request" '
18 | '$status $body_bytes_sent "$http_referer" '
19 | '"$http_user_agent" "$http_x_forwarded_for"';
20 |
21 | server_tokens off;
22 |
23 | access_log off;
24 |
25 | sendfile on;
26 | #tcp_nopush on;
27 |
28 | keepalive_timeout 65;
29 |
30 | gzip on;
31 | gzip_vary on;
32 | gzip_comp_level 6;
33 | gzip_min_length 860;
34 | gzip_disable "msie6";
35 | gzip_http_version 1.1;
36 | gzip_types text/plain text/css text/xml application/rss+xml application/javascript;
37 |
38 | # Max file upload size (keep in mind CSV uploads for DSpace)
39 | client_max_body_size 70m;
40 |
41 | include proxy_params;
42 | include /etc/nginx/conf.d/*.conf;
43 | }
44 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/organization/snippets/organization.html:
--------------------------------------------------------------------------------
1 | {% with truncate=truncate or 0, url=h.url_for(controller='organization', action='read', id=organization.name) %}
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
{{ organization.title or organization.name }}
10 | {% if organization.description %}
11 |
12 | {{ h.markdown_extract(organization.description, 180) }}
13 |
14 | {% else %}
15 |
{{ _('There is no description for this organization') }}
16 | {% endif %}
17 |
18 |
19 |
{{organization.package_count}}
20 | Datasets
21 |
22 |
23 |
24 |
25 | {% endwith %}
26 |
--------------------------------------------------------------------------------
/ckanext/openafrica/blueprint.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint, make_response
2 | from ckan.plugins.toolkit import render
3 |
4 | openafrica = Blueprint("openafrica", __name__)
5 |
6 | def static_path(path):
7 | def render_path():
8 | return render(path)
9 |
10 | return render_path
11 |
12 | def robots_txt():
13 | """display robots.txt"""
14 | resp = make_response(render("home/robots.txt"))
15 | resp.headers["Content-Type"] = "text/plain; charset=utf-8"
16 | return resp
17 |
18 | rules = [
19 | ("/about/terms-and-conditions", "toc", static_path("home/about/toc.html")),
20 | ("/about/accessibility", "accessibility", static_path("home/about/accessibility.html")),
21 | ("/about/code-of-conduct", "coc", static_path("home/about/coc.html")),
22 | ("/about/moderation-policy", "moderation", static_path("home/about/moderation.html")),
23 | ("/about/faq", "faq", static_path("home/about/faq.html")),
24 | ("/about/privacy", "privacy", static_path("home/about/privacy.html")),
25 | ("/about/contact-us", "contact", static_path("home/about/contact.html")),
26 | ("/robots.txt", "robots_txt", robots_txt)
27 | ]
28 |
29 | for rule in rules:
30 | openafrica.add_url_rule(*rule)
31 |
32 |
--------------------------------------------------------------------------------
/deploy/roles/solr/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: defaults/main.yml
3 |
4 | # solr version to install
5 | solr_version: 5.2.1
6 |
7 | # solr tarball name. Infered from solr version
8 | solr_tarball: solr-{{ solr_version }}.tgz
9 |
10 | # solr mirror url
11 | solr_mirror_url: https://archive.apache.org/dist/lucene/solr/{{ solr_version }}/{{ solr_tarball }}
12 |
13 | # sha256 checksum for solr tarball
14 | solr_sha256sum: 3f54cec862da1376857f96f4a6f2044a5addcebc4df159b8797fd71f7ba8df86
15 |
16 | # directory in which solr-tarball will be extracted in
17 | solr_prefix_dir: /opt
18 |
19 | # directory in which solr will be installed
20 | solr_install_dir: /opt/solr
21 |
22 | # will contain solr log files, core(s)
23 | solr_var_dir: /var/solr
24 |
25 | # default port which solr will listen & serve requests from
26 | solr_port: 8983
27 |
28 | # solr system user, also owner of solr files/dirs
29 | solr_user: {
30 | name: "solr",
31 | system: "yes",
32 | home_path: "/home/solr",
33 | description: "SOLR User"
34 | }
35 |
36 | # solr java min/max memory heap allocation sizes
37 | solr_java_mem: "-Xms1024m -Xmx1024m"
38 |
39 | # default solr core used by CKAN
40 | solr_cores:
41 | - ckan_default
42 |
43 | # vim: set sw=2 ts=2:
44 |
--------------------------------------------------------------------------------
/deploy/roles/solr/tasks/solr-cores.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: We first delete the core if it exists
3 | become_user: solr
4 | command: "{{ solr_install_dir }}/bin/solr delete -c ckan_default"
5 |
6 | - name: Experiment in creating a core
7 | become_user: solr
8 | command: "{{ solr_install_dir }}/bin/solr create -c ckan_default"
9 |
10 | - name: Create Solr core data dir
11 | file: dest={{ solr_var_dir }}/data/{{ item }}/data/index state=directory mode=0755
12 | with_items: "{{ solr_cores }}"
13 |
14 | - name: Create Solr core conf dir
15 | file: dest={{ solr_var_dir }}/data/{{ item }}/conf state=directory owner={{ solr_user.name }} group={{ solr_user.name }} mode=0755
16 | with_items: "{{ solr_cores }}"
17 |
18 | - name: Populate Solr core conf dir
19 | command: /usr/bin/rsync -a {{ solr_install_dir }}/server/solr/configsets/basic_configs/conf/ {{ solr_var_dir }}/data/{{ item }}/conf/ creates={{ solr_var_dir }}/data/{{ item }}/conf/solrconfig.xml
20 | with_items: "{{ solr_cores }}"
21 |
22 | - name: Create core.properties placeholder
23 | file: dest={{ solr_var_dir }}/data/{{ item }}/core.properties state=touch owner={{ solr_user.name }} group={{ solr_user.name }} mode=0644
24 | with_items: "{{ solr_cores }}"
25 |
26 | # vim: set ts=2 sw=2:
27 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/snippets/privacy_text.html:
--------------------------------------------------------------------------------
1 | {% trans %}
2 | Your personal data: From time to time, you may be asked to submit personal information about yourself (e.g. name and e-mail address) in order to receive or use services on our website. Such services include e-mail updates, website feedback, or suggesting an idea / application.
3 |
4 | By entering your details in the fields requested, you enable openAFRICA and its service providers to provide you with the services you select. Any personal information you provide to us will only be used by us, our agents and service providers, and will not be disclosed unless we are obliged or permitted to by law to do so.
5 |
6 | If you post or send offensive, inappropriate or objectionable content anywhere on this site, we may use whatever information about you is available to us to stop such behaviour.
7 |
8 | We will hold your personal information on our systems for as long as you use the service you have requested, and remove it in the event that the purpose has been met or when you no longer wish to continue your subscription.
9 |
10 |
11 |
12 | ** Attribution of content - data.gov.uk
13 | {% endtrans %}
14 |
--------------------------------------------------------------------------------
/deploy/roles/db/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: tasks/main.yml
3 |
4 | - name: Add PGDG apt list file
5 | template: src=pgdg.list.j2 dest=/etc/apt/sources.list.d/pgdg.list owner=root group=root mode=0644
6 |
7 | - name: Import PGDG repo keys
8 | apt_key: url="https://www.postgresql.org/media/keys/ACCC4CF8.asc" state=present
9 |
10 | - name: Install postgresql
11 | apt: name={{ item }} update_cache=yes state=present
12 | with_items:
13 | - python-psycopg2
14 | - postgresql-{{ pg_version }}
15 | - postgresql-client-{{ pg_version }}
16 | - postgresql-contrib-{{ pg_version }}
17 | notify:
18 | - restart postgres
19 |
20 | - name: Copy postgres configs
21 | template: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }} owner={{ item.owner }} group={{ item.group }}
22 | with_items:
23 | - { src: 'postgresql-{{ pg_version }}.conf.j2', dest: '{{ pg_conf_dir }}/postgresql.conf', mode: '0644', owner: 'postgres', group: 'postgres' }
24 | - { src: 'pg_hba-{{ pg_version }}.conf.j2', dest: '{{ pg_conf_dir }}/pg_hba.conf', mode: '0640', owner: 'postgres', group: 'postgres' }
25 | notify: restart postgres
26 |
27 | - name: start & enable postgres
28 | service: name=postgresql state=started enabled=true
29 |
30 | # vim: set sw=2 ts=2:
31 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/robots.txt:
--------------------------------------------------------------------------------
1 | {% ckan_extends %}
2 |
3 | {% block additional_user_agents -%}
4 | # Amazonbot
5 | User-agent: Amazonbot
6 | Disallow: /
7 |
8 | # anthropic-ai
9 | User-agent: anthropic-ai
10 | Disallow: /
11 |
12 | # Applebot
13 | User-agent: Applebot
14 | Disallow: /
15 |
16 | # Applebot-Extended
17 | User-agent: Applebot-Extended
18 | Disallow: /
19 |
20 | # Bytespider
21 | User-agent: Bytespider
22 | Disallow: /
23 |
24 | # CCBot
25 | User-agent: CCBot
26 | Disallow: /
27 |
28 | # ChatGPT-User
29 | User-agent: ChatGPT-User
30 | Disallow: /
31 |
32 | # Claude-Web
33 | User-agent: Claude-Web
34 | Disallow: /
35 |
36 | # ClaudeBot
37 | User-agent: ClaudeBot
38 | Disallow: /
39 |
40 | # cohere-ai
41 | User-agent: cohere-ai
42 | Disallow: /
43 |
44 | # Diffbot
45 | User-agent: Diffbot
46 | Disallow: /
47 |
48 | # FacebookBot
49 | User-agent: FacebookBot
50 | Disallow: /
51 |
52 | # Google-Extended
53 | User-agent: Google-Extended
54 | Disallow: /
55 |
56 | # GPTBot
57 | User-agent: GPTBot
58 | Disallow: /
59 |
60 | # omgili
61 | User-agent: omgili
62 | Disallow: /
63 |
64 | # PerplexityBot
65 | User-agent: PerplexityBot
66 | Disallow: /
67 |
68 | # Generatedy by RoboShield (https://roboshield.trustlab.africa)
69 |
70 | {%- endblock %}
71 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/snippets/toc_text.html:
--------------------------------------------------------------------------------
1 | {% trans %}
2 | The data and information available through openAFRICA are available under terms described in the “licence” or "constraints" field of individual dataset records (meta-data). Except where otherwise noted this is Open Government License.
3 |
4 | We want the information on this site to be open and as easy to re-use as possible. When you submit information to this site we will work on the basis, unless you clearly state otherwise alongside your work, that you are granting the us a non-exclusive, irrevocable right to use and pass on all public information that you submit (for example descriptions of your ideas and screenshots of your apps) as well as the right to allow the re-use of that information.
5 |
6 | This is so that we can place the contents of this site under the same permissive licence terms as above. Your ideas and applications remain your own. Please check the terms and conditions of the third party websites linked from the openAFRICA platform.
7 |
8 | The accuracy of information from any third party sites published on openAFRICA is the responsibility of those sites.
9 |
10 |
11 |
12 | ** Attribution of content - data.gov.uk
13 | {% endtrans %}
14 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/user/list.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 |
3 | {% block meta %}
4 | {{ super() }}
5 |
6 | {% endblock %}
7 |
8 | {% block subtitle %}{{ _('All Users') }}{% endblock %}
9 |
10 | {% block breadcrumb_content %}
11 | {{ h.nav_link(_('Users'), named_route='user.index') }}
12 | {% endblock %}
13 |
14 | {% block primary_content %}
15 |
16 |
17 |
18 | {% block page_heading %}{{ _('Users') }}{% endblock %}
19 |
20 | {% if c.userobj.sysadmin %}
21 | {% block users_list %}
22 |
23 | {% block users_list_inner %}
24 | {% for user in page.items %}
25 | {{ h.linked_user(user.name, maxlength=20) }} - {{ user.email }}
26 | {% endfor %}
27 | {% endblock %}
28 |
29 | {% endblock %}
30 | {% else %}
31 |
{{ _('You do not have permission to view the list of users.') }}
32 | {% endif %}
33 |
34 | {% block page_pagination %}
35 | {{ page.pager(q=q, order_by=order_by) }}
36 | {% endblock %}
37 |
38 | {% endblock %}
39 |
40 | {% block secondary_content %}
41 | {% snippet 'user/snippets/user_search.html', q=q %}
42 | {% endblock %}
43 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/organization/old_read_base.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 |
3 | {% block subtitle %}{{ c.group_dict.display_name }} - {{ _('Organizations') }}{% endblock %}
4 |
5 | {% block breadcrumb_content %}
6 | {% link_for _('Organizations'), controller='organization', action='index' %}
7 | {% link_for c.group_dict.display_name|truncate(35), controller='organization', action='read', id=c.group_dict.name %}
8 | {% endblock %}
9 |
10 | {% block content_action %}
11 | {% if h.check_access('organization_update', {'id': c.group_dict.id}) %}
12 | {% link_for _('Manage'), controller='organization', action='edit', id=c.group_dict.name, class_='btn', icon='wrench' %}
13 | {% endif %}
14 | {% endblock %}
15 |
16 | {% block content_primary_nav %}
17 | {{ h.build_nav_icon('organization_read', _('Datasets'), id=c.group_dict.name) }}
18 | {{ h.build_nav_icon('organization_activity', _('Activity Stream'), id=c.group_dict.name, offset=0) }}
19 | {{ h.build_nav_icon('organization_about', _('About'), id=c.group_dict.name) }}
20 | {% endblock %}
21 |
22 | {% block secondary_content %}
23 | {% snippet 'snippets/organization.html', organization=c.group_dict, show_nums=true %}
24 | {% block organization_facets %}{% endblock %}
25 | {% endblock %}
26 |
27 | {% block links %}
28 | {{ super() }}
29 | {% include "organization/snippets/feeds.html" %}
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/deploy/roles/db/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: defaults/main.yml
3 |
4 | # Default values used to deploy postgresql
5 |
6 | # TLS cipher suite used by postgresql client-server connection
7 | pg_tls_cipher_suite: "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:CAMELLIA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"
8 |
9 | # Postgresql version
10 | pg_version: 9.3
11 |
12 | # Postgresql configuration directory on Ubuntu hosts
13 | pg_conf_dir: "/etc/postgresql/{{ pg_version }}/main"
14 |
15 | # IP address/hostname on which postgresql will listen
16 | # for connections on
17 | pg_listen_addresses: "localhost"
18 |
19 | pg_db_server: "localhost"
20 | # host connection details allowed to connect to postgresql server
21 | # See http://www.postgresql.org/docs/9.1/static/auth-pg-hba-conf.html
22 | pg_db_connections:
23 | - { type: "host", db: "all", user: "all", src_addr: "127.0.0.1/32", method: "md5" }
24 |
25 | # vim: set sw=2 ts=2:
26 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/snippets/accessibility_text.html:
--------------------------------------------------------------------------------
1 | {% trans %}
2 |
3 | This website is run by Code for Africa as part of its data liberation programme, which is co-funded by the the World Bank Global Media Development Programme and Google NewsLab . It is our intention that the website is usable and accessible to all users.
4 |
5 | Feedback
6 |
7 | We very much welcome and actively encourage your feedback on this site. The site is being developed in a phased approach so we encourage you to provide feedback to ensure that future iterations meet your needs.
8 |
9 | We will not pass on any of your personal information when dealing with your enquiry, unless you have given us permission to do so. Once we have replied to you, we keep a record of your message for audit purposes.
10 |
11 | Contact Us
12 |
13 | Changes to this privacy policy
14 |
15 | If this privacy policy changes in any way, we will place an updated version on this page. Regularly reviewing this page ensures you are always aware of what information we collect, how we use it and under what circumstances, if any, we will share it with other parties.
16 |
17 |
18 |
19 | ** Attribution of content - data.gov.uk
20 | {% endtrans %}
21 |
--------------------------------------------------------------------------------
/ckanext/openafrica/lib/helpers.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | """
4 | Copyright (c) 2015-2017 Code for Africa
5 |
6 | This file is part of CKAN openAFRICA Extension.
7 |
8 | CKAN openAFRICA Extension is free software: you can redistribute it and/or
9 | modify it under the terms of the GNU Affero General Public License as published
10 | by the Free Software Foundation, either version 2 of the License, or
11 | (at your option) any later version.
12 |
13 | CKAN openAFRICA Extension is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU Affero General Public License for more details.
17 |
18 | You should have received a copy of the GNU Affero General Public License
19 | along with CKAN openAfrica Extension. If not, see
20 | .
21 |
22 | """
23 |
24 | u"""
25 | Helper functions
26 |
27 | Consists of functions to typically be used within templates, but also
28 | available to Controllers. This module is available to templates as 'h'.
29 | It is an extension of ckan helpers.py
30 | """
31 |
32 | import datetime
33 |
34 | from ckan import plugins
35 |
36 |
37 | def current_year():
38 | u""" Return the current year """
39 | year = datetime.datetime.now().year
40 | return year
41 |
42 |
43 | def is_plugin_enabled(plugin_name):
44 | u"""
45 | Returns a boolean True or False, indicating if the supplied plugin_name
46 | is enabled in the config file
47 |
48 | :param plugin_name: the name of the plugin to check for in the config file
49 | :type plugin_name: string
50 | """
51 | return plugins.plugin_loaded(plugin_name)
52 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/package/search.html:
--------------------------------------------------------------------------------
1 | {% extends 'dataset-page.html' %}
2 | {% import 'macros/form.html' as form %}
3 |
4 | {% block primary_content %}
5 |
6 | {% block page_primary_action %}
7 | {% if h.check_access('package_create') %}
8 |
9 | {% link_for _('Add Dataset'), controller='dataset', action='new', class_='btn btn-primary', icon='plus-sign-alt' %}
10 |
11 | {% endif %}
12 | {% endblock %}
13 | {% block form %}
14 | {% set facets = {
15 | 'fields': c.fields_grouped,
16 | 'search': c.search_facets,
17 | 'titles': c.facet_titles,
18 | 'translated_fields': c.translated_fields,
19 | 'remove_field': c.remove_field }
20 | %}
21 | {% set sorting = [
22 | (_('Relevance'), 'score desc, metadata_modified desc'),
23 | (_('Name Ascending'), 'title_string asc'),
24 | (_('Name Descending'), 'title_string desc'),
25 | (_('Last Modified'), 'metadata_modified desc'),
26 | (_('Popular'), 'views_recent desc')]
27 | %}
28 | {% snippet 'snippets/search_form.html', type='dataset', query=c.q, sorting=sorting, sorting_selected=c.sort_by_selected, count=c.page.item_count, facets=facets, show_empty=request.params, error=c.query_error %}
29 | {% if c.userobj %}
30 |
{{_('Can\'t find what you are looking for?')}} {{_('Suggest a dataset')}}.
31 | {% endif %}
32 | {% endblock %}
33 | {% block package_search_result_list %}
34 | {{ h.snippet('snippets/package_list.html', packages=c.page.items) }}
35 | {% endblock %}
36 | {% block page_pagination %}
37 | {{ c.page.pager(q=c.q) }}
38 | {% endblock %}
39 |
40 | {% endblock %}
41 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/snippets/search_result_text.html:
--------------------------------------------------------------------------------
1 | {#
2 |
3 | Displays a test for results of a search.
4 |
5 | query - The text that was searched for
6 | count - The number of results for the search
7 | type - Search result type (dataset, group, organization)
8 |
9 | Example:
10 |
11 | {% snippet 'snippets/search_result_text.html', query=query, count=count, type='dataset' %}
12 |
13 | #}
14 | {% if type == 'dataset' %}
15 | {% set text_query = ungettext('{number} dataset found for "{query}"', '{number} datasets found for "{query}"', count) %}
16 | {% set text_query_none = _('No datasets found for "{query}"') %}
17 | {% set text_no_query = ungettext('{number} dataset found', '{number} datasets found', count) %}
18 | {% set text_no_query_none = _('No datasets found') %}
19 |
20 | {% elif type == 'group' %}
21 | {% set text_query = ungettext('{number} group found for "{query}"', '{number} groups found for "{query}"', count) %}
22 | {% set text_query_none = _('No groups found for "{query}"') %}
23 | {% set text_no_query = ungettext('{number} group found', '{number} groups found', count) %}
24 | {% set text_no_query_none = _('No groups found') %}
25 |
26 | {% elif type == 'organization' %}
27 | {% set text_query = ungettext('{number} organisation found for "{query}"', '{number} organisations found for "{query}"', count) %}
28 | {% set text_query_none = _('No organisations found for "{query}"') %}
29 | {% set text_no_query = ungettext('{number} organisation found', '{number} organisations found', count) %}
30 | {% set text_no_query_none = _('No organisations found') %}
31 | {%- endif -%}
32 |
33 | {% if query %}
34 | {%- if count -%}
35 | {{ text_query.format(number=h.localised_number(count), query=query) }}
36 | {%- else -%}
37 | {{ text_query_none.format(query=query) }}
38 | {%- endif -%}
39 | {%- else -%}
40 | {%- if count -%}
41 | {{ text_no_query.format(number=h.localised_number(count)) }}
42 | {%- else -%}
43 | {{ text_no_query_none }}
44 | {%- endif -%}
45 | {%- endif -%}
46 |
--------------------------------------------------------------------------------
/deploy/roles/solr/tasks/solr.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Create system user account to run solr daemon
4 | user: name={{ solr_user.name }} createhome=yes home={{ solr_user.home_path }} shell=/bin/bash system=yes state=present
5 |
6 | - name: Get Solr tarball
7 | get_url: url={{ solr_mirror_url }} dest={{ solr_prefix_dir }}/{{ solr_tarball }} sha256sum={{ solr_sha256sum }}
8 | register: get_url_result
9 |
10 | - name: Unpack Solr tarball
11 | unarchive: src={{ solr_prefix_dir }}/{{ solr_tarball }} dest={{ solr_prefix_dir }} creates={{ solr_prefix_dir }}/solr-{{ solr_version }} owner={{ solr_user.name }} group={{ solr_user.name }} copy=no
12 | when: get_url_result|changed
13 |
14 | # /opt/solr -> /opt/solr-$SOLR_VERSION
15 | - name: Create a symlink to solr installation dir
16 | file: src="{{solr_prefix_dir}}/solr-{{solr_version}}" dest="{{solr_prefix_dir}}/solr" owner={{ solr_user.name }} group={{ solr_user.name }} state=link
17 |
18 | - name: Create solr data & log dirs
19 | file: path={{ item }} owner={{ solr_user.name }} group={{ solr_user.name }} state=directory
20 | with_items:
21 | - "{{solr_var_dir}}/data"
22 | - "{{solr_var_dir}}/logs"
23 |
24 | - name: Copy solr init.d service file
25 | template: src=init.d-solr.j2 dest=/etc/init.d/solr owner=root group=root mode=0755
26 |
27 | - name: Copy solr.xml config. files
28 | command: /usr/bin/rsync -a "{{solr_install_dir}}/server/solr/solr.xml" "{{solr_var_dir}}/data/" creates="{{solr_var_dir}}/data/solr.xml"
29 |
30 | - name: Copy solr env files
31 | template: src=solr.in.sh.j2 dest={{ solr_var_dir }}/solr.in.sh owner={{ solr_user.name }} group={{ solr_user.name }} mode=0755
32 | notify: restart solr
33 |
34 | - name: Reconfigure solr logging
35 | copy: src=log4j.properties dest="{{ solr_var_dir }}/log4j.properties" owner={{ solr_user.name }} group={{ solr_user.name }} mode=0644
36 | notify: restart solr
37 |
38 | - name: Start & enable service
39 | service: name=solr state=started enabled=yes
40 |
41 | - include: solr-cores.yml
42 | become_user: "{{ solr_user.name }}"
43 | when: solr_cores is defined
44 | tags: solr-cores
45 |
46 | # vim: set ts=2 sw=2:
47 |
--------------------------------------------------------------------------------
/deploy/roles/ckan/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: defaults/main.yml
3 |
4 | # ckan user details
5 | ckan_user: {
6 | name: "ckan",
7 | system: "yes",
8 | home_path: "/usr/lib/ckan",
9 | shell: "/sbin/nologin",
10 | description: "CKAN User"
11 | }
12 |
13 | celery_user: ubuntu
14 | log_path: "/var/log/ckan/africaopendata"
15 | # latest stable ckan version
16 | ckan_version: "2.3"
17 |
18 | # Link/URL to download ckan sources
19 | ckan_src_url: "git+https://github.com/okfn/ckan.git@ckan-{{ ckan_version }}#egg=ckan"
20 |
21 | # CKAN default site name
22 | ckan_site_name: "africaopendata"
23 |
24 | # CKAN site_id
25 | ckan.site_id: africaopendata
26 |
27 | # CKAN site URL
28 | ckan_site_url: "http://{{ ckan_site_name }}"
29 |
30 | # CKAN site title
31 | ckan_site_title: "CKAN"
32 |
33 | # CKAN site description
34 | ckan_site_description: "The easy way to get, use and share data"
35 |
36 | # CKAN email settings
37 | ckan_email_to: "ckan@yourdomain.com"
38 | ckan_error_email_from: "no-reply@yourdomain.com"
39 | ckan_smtp_server: "smtp.yourdomain.com"
40 | ckan_smtp_starttls: False
41 | ckan_smtp_user: "ckan-mailer"
42 | ckan_smtp_password: 'T$UZqA\XeN$}CX8)'
43 | ckan_smtp_mail_from: "no-reply@yourdomain.com"
44 |
45 | # disable ckan debugging on production servers unless when
46 | # in dev. mode
47 | ckan_debug_mode: "false"
48 |
49 | #default ckan virtualenv path
50 | ckan_virtualenv: "{{ ckan_user.home_path }}/{{ ckan_site_name }}"
51 |
52 | # postgresql database & user used by ckan
53 | ckan_db: {
54 | username: "ckan_default",
55 | password: "h8ds*hzYRE",
56 | dbname: "ckan_default",
57 | dbhost: "{{ pg_db_server }}"
58 | }
59 |
60 | # CKAN default site's configs directory
61 | ckan_conf_dir: "/etc/ckan/{{ ckan_site_name }}"
62 |
63 | # directory in which CKAN will store all uploaded data
64 | ckan_storage_path: "/var/lib/ckan/{{ckan_site_name}}"
65 |
66 | # CKAN Maximum resource upload size in MB
67 | ckan_max_resource_size: 10
68 |
69 | # maximum image upload size in MB
70 | ckan_max_image_size: 2
71 |
72 | # CKAN solr URL
73 | ckan_solr_url: "http://127.0.0.1:8983/solr/ckan_default"
74 |
75 | supervisor_services:
76 | - ckan_gather_consumer
77 | - ckan_fetch_consumer
78 | # vim: set sw=2 ts=2:
79 |
--------------------------------------------------------------------------------
/ckanext/openafrica/public/icons/slack.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/organization/read.html:
--------------------------------------------------------------------------------
1 | {% extends 'organization/read_base.html' %}
2 |
3 | {% set organization=c.group_dict %}
4 |
5 | {% block primary_action %}
6 | {% endblock %}
7 |
8 | {% block primary_content %}
9 | {% snippet 'organization/snippets/organization.html', organization=organization, show_nums=true %}
10 | {% endblock %}
11 |
12 | {% block package_list %}
13 |
14 |
15 | {% if c.page.items %}
16 |
Order by:
17 | {% if c.sort_by_selected != "score desc" %}
18 |
Last Modified
19 |
/
20 |
Popular
21 | {% else %}
22 |
Last Modified
23 |
/
24 |
Popular
25 | {% endif %}
26 | {% endif %}
27 |
28 |
29 | {% if h.check_access("organization_update", {"id": organization.id}) %}
30 | {% link_for _("Manage"), controller="organization", action="edit", id=organization.name, class_="btn", icon="wrench" %}
31 | {% endif %}
32 | {% if h.check_access("package_create", { "owner_org": organization.id }) %}
33 | {% link_for _("Add Dataset"), controller="dataset", action="new", group=organization.id, class_="btn btn-primary", icon="plus-sign-alt" %}
34 | {% endif %}
35 |
36 |
37 | {% set tags=h.get_facet_items_dict('tags') %}
38 | {% snippet 'organization/snippets/tag_list.html', tags=tags, _tag_class='label', _organization_url=organization.name %}
39 |
40 |
41 |
42 | {% if c.page.items %}
43 | {{ h.snippet('snippets/package_list.html', packages=c.page.items) }}
44 | {% endif %}
45 | {% endblock %}
46 |
47 | {% block page_pagination %}
48 |
51 |
52 | {% endblock %}
53 |
54 | {% block apps_list %}
55 | Related Applications
56 | Related applications made using these datasets
57 |
60 |
61 | {% endblock %}
62 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/snippets/moderation_text.html:
--------------------------------------------------------------------------------
1 | {% trans %}
2 | This moderation policy sets out the timescales, methods and terms within which openAFRICA operates. This ensures that all user generated online content is suitable and in the context of the openAFRICA service.
3 |
4 | Making postings: Comments added to the site by registered, logged-in members will appear on the site without moderation. We use 'Captcha' software on all our web forms except the login page in order to prevent and reduce the amount of unsolicited postings that some users attempt to upload.
5 |
6 | We sometimes use moderation management software to aid in the prevention of 'Spam' appearing on this website and to flag-up unsuitable content. Comments added to the site by unregistered or non logged-in users will not appear until they have been moderated. Ideas and applications submitted are always moderated before appearing on the site within 3- 5 days of being submitted.
7 |
8 | Moderation frequency: The openAFRICA team will strive to moderate content added within a 72 hour period during the working week. Comments added over the weekend or on Public Holidays will be moderated on the next available working day.
9 |
10 | Ad-hoc online events: If there are any 'featured' online feedback events that require more frequent moderation e.g. an online consultation that occurs within a specific time period; we will make moderation frequency for that specific activity.
11 |
12 | Content editing after approval: The openAFRICA team will occasionally edit submitted content before it appears on the site. This editing is limited to improving clarity of any idea and removing typos, finally optimising any images that accompany an app. We will not change the substance or meaning of any contribution.
13 |
14 | Content not published?: If your submission to the site does not appear on the site, or is removed, it means that the openAFRICA team feel that the contribution does not comply with the code of conduct of the site.
15 | Where possible and in response to any requests, we will explain why your contribution did not fit with the guidelines, with suggestions of how the content could be re-phrased so that it can appear on the site.
16 | Send moderation queries by email to: support [at] codeforafrica [dot] org
17 |
18 |
19 |
20 | ** Attribution of content - data.gov.uk
21 | {% endtrans %}
22 |
--------------------------------------------------------------------------------
/ckanext/openafrica/plugin.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | # Copyright (c) 2015-2017 Code for Africa
4 |
5 | # This file is part of CKAN openAFRICA Extension.
6 |
7 | # CKAN openAFRICA Extension is free software: you can redistribute it and/or
8 | # modify it under the terms of the GNU Affero General Public License as published by
9 | # the Free Software Foundation, either version 2 of the License, or
10 | # (at your option) any later version.
11 |
12 | # CKAN openAFRICA Extension is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU Affero General Public License for more details.
16 |
17 | # You should have received a copy of the GNU Affero General Public License
18 | # along with CKAN openAFRICA Extension. If not, see .
19 |
20 | u'''Defines openAFRICA plugin
21 | Extends CKAN plugins core which provides plugin services to the CKAN
22 | '''
23 |
24 | import ckan.plugins as plugins
25 | import ckan.plugins.toolkit as toolkit
26 | from . import blueprint
27 |
28 |
29 | class OpenAfricaPlugin(plugins.SingletonPlugin):
30 | u"""
31 | openAFRICA templating plugin.
32 | """
33 | plugins.implements(plugins.IConfigurer, inherit=True)
34 | plugins.implements(plugins.ITemplateHelpers, inherit=True)
35 | plugins.implements(plugins.IBlueprint)
36 |
37 | def update_config(self, config):
38 | u"""
39 | Called by load_environment at earliest point when config is
40 | available to plugins. The config should be updated in place.
41 |
42 | :param config: ``config`` object
43 | """
44 | toolkit.add_template_directory(config, 'templates')
45 | toolkit.add_public_directory(config, 'public')
46 | toolkit.add_resource('assets', 'openafrica')
47 |
48 | # IBlueprint
49 | def get_blueprint(self):
50 | """
51 | CKAN uses Flask Blueprints to extend urls
52 | :return:
53 | """
54 | return blueprint.openafrica
55 |
56 |
57 | def get_helpers(self):
58 | u"""
59 | All functions, not starting with __ in the ckanext.openafrica.lib
60 | module will be loaded and made available as helpers to the
61 | templates.
62 | """
63 | from ckanext.openafrica.lib import helpers
64 | from inspect import getmembers, isfunction
65 |
66 | helper_dict = {}
67 |
68 | funcs = [o for o in getmembers(helpers, isfunction)]
69 | return dict([(f[0], f[1],) for f in funcs if not f[0].startswith('__')])
70 |
--------------------------------------------------------------------------------
/deploy/roles/ckan/templates/apache/000-ckan-default.conf.j2:
--------------------------------------------------------------------------------
1 |
2 | # The ServerName directive sets the request scheme, hostname and port that
3 | # the server uses to identify itself. This is used when creating
4 | # redirection URLs. In the context of virtual hosts, the ServerName
5 | # specifies what hostname must appear in the request's Host: header to
6 | # match this virtual host. For the default virtual host (this file) this
7 | # value is not decisive as it is used as a last resort host regardless.
8 | # However, you must set it for any further virtual host explicitly.
9 | #ServerName www.example.com
10 |
11 | ServerAdmin {{ ckan_email_to }}
12 | #DocumentRoot /var/www/html
13 |
14 | # apache 2.4: https://httpd.apache.org/docs/2.4/upgrading.html#access
15 | # "AH01630: client denied by server configuration: /etc/ckan/default/apache.wsgi"
16 |
17 | Options All
18 | AllowOverride All
19 | Require all granted
20 |
21 |
22 | # WSGI script path
23 | WSGIScriptAlias / {{ ckan_conf_dir }}/apache.wsgi
24 |
25 | # Pass authorization info on (needed for rest api).
26 | WSGIPassAuthorization On
27 |
28 | # Deploy as a daemon (avoids conflicts between CKAN instances).
29 | WSGIDaemonProcess {{ ckan_site_name }} display-name={{ ckan_site_name }} processes=2 threads=15
30 |
31 | WSGIProcessGroup {{ ckan_site_name }}
32 |
33 |
34 | RPAFenable On
35 | RPAFsethostname On
36 | RPAFproxy_ips 127.0.0.1
37 |
38 |
39 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
40 | # error, crit, alert, emerg.
41 | # It is also possible to configure the loglevel for particular
42 | # modules, e.g.
43 | #LogLevel info ssl:warn
44 | ErrorLog ${APACHE_LOG_DIR}/{{ ckan_site_name }}.error.log
45 | CustomLog ${APACHE_LOG_DIR}/{{ ckan_site_name }}.custom.log combined
46 |
47 | # For most configuration files from conf-available/, which are
48 | # enabled or disabled at a global level, it is possible to
49 | # include a line for only one particular virtual host. For example the
50 | # following line enables the CGI configuration for this host only
51 | # after it has been globally disabled with "a2disconf".
52 | #Include conf-available/serve-cgi-bin.conf
53 |
54 |
55 |
56 | # vim: syntax=apache sw=2 ts=4:
57 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/index.html:
--------------------------------------------------------------------------------
1 | {% ckan_extends %}
2 |
3 | {% block primary_content %}
4 | {% snippet 'home/snippets/search.html' %}
5 |
64 | {% snippet "home/snippets/subscription.html" %}
65 |
66 |
67 | {% snippet 'home/snippets/home_partner_logos.html' %}
68 |
69 |
70 | {% endblock %}
71 |
--------------------------------------------------------------------------------
/deploy/roles/solr/templates/init.d-solr.j2:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Licensed to the Apache Software Foundation (ASF) under one or more
3 | # contributor license agreements. See the NOTICE file distributed with
4 | # this work for additional information regarding copyright ownership.
5 | # The ASF licenses this file to You under the Apache License, Version 2.0
6 | # (the "License"); you may not use this file except in compliance with
7 | # 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 | ### BEGIN INIT INFO
18 | # Provides: solr
19 | # Required-Start: $remote_fs $syslog
20 | # Required-Stop: $remote_fs $syslog
21 | # Default-Start: 2 3 4 5
22 | # Default-Stop: 0 1 6
23 | # Description: Controls Apache Solr as a Service
24 | ### END INIT INFO
25 |
26 | # Example of a very simple *nix init script that delegates commands to the bin/solr script
27 | # Typical usage is to do:
28 | #
29 | # cp bin/init.d/solr /etc/init.d/solr
30 | # chmod 755 /etc/init.d/solr
31 | # chown root:root /etc/init.d/solr
32 | # update-rc.d solr defaults
33 | # update-rc.d solr enable
34 |
35 | # Where you extracted the Solr distribution bundle
36 | SOLR_INSTALL_DIR={{ solr_install_dir }}
37 |
38 | if [ ! -d "$SOLR_INSTALL_DIR" ]; then
39 | echo "$SOLR_INSTALL_DIR not found! Please check the SOLR_INSTALL_DIR setting in your $0 script."
40 | exit 1
41 | fi
42 |
43 | # Path to an include file that defines environment specific settings to override default
44 | # variables used by the bin/solr script. It's highly recommended to define this script so
45 | # that you can keep the Solr binary files separated from live files (pid, logs, index data, etc)
46 | # see bin/solr.in.sh for an example
47 | SOLR_ENV={{ solr_var_dir }}/solr.in.sh
48 |
49 | if [ ! -f "$SOLR_ENV" ]; then
50 | echo "$SOLR_ENV not found! Please check the SOLR_ENV setting in your $0 script."
51 | exit 1
52 | fi
53 |
54 | # Specify the user to run Solr as; if not set, then Solr will run as root.
55 | # Running Solr as root is not recommended for production environments
56 | RUNAS={{ solr_user.name }}
57 |
58 | # verify the specified run as user exists
59 | runas_uid=`id -u $RUNAS`
60 | if [ $? -ne 0 ]; then
61 | echo "User $RUNAS not found! Please create the $RUNAS user before running this script."
62 | exit 1
63 | fi
64 |
65 | case "$1" in
66 | start|stop|restart|status)
67 | SOLR_CMD=$1
68 | ;;
69 | *)
70 | echo "Usage: $0 {start|stop|restart|status}"
71 | exit
72 | esac
73 |
74 | if [ -n "$RUNAS" ]; then
75 | su -c "SOLR_INCLUDE=$SOLR_ENV $SOLR_INSTALL_DIR/bin/solr $SOLR_CMD" - $RUNAS
76 | else
77 | SOLR_INCLUDE=$SOLR_ENV $SOLR_INSTALL_DIR/bin/solr $SOLR_CMD
78 | fi
79 |
--------------------------------------------------------------------------------
/deploy/roles/ckan/templates/supervisor.conf.j2:
--------------------------------------------------------------------------------
1 | [program:ckan_gather_consumer]
2 |
3 | command=nice -n 20 {{ ckan_virtualenv }}/bin/paster --plugin=ckanext-harvest harvester gather_consumer --config="{{ ckan_conf_dir }}/production.ini"
4 | user=ubuntu
5 | numprocs=1
6 | stdout_logfile={{ log_path }}/gather_consumer.log
7 | stderr_logfile={{ log_path }}/gather_consumer.log
8 | autostart=true
9 | autorestart=true
10 | startsecs=10
11 |
12 |
13 | [program:ckan_fetch_consumer]
14 |
15 | command=nice -n 20 {{ ckan_virtualenv }}/bin/paster --plugin=ckanext-harvest harvester fetch_consumer --config="{{ ckan_conf_dir }}/production.ini"
16 | user=ubuntu
17 | numprocs=1
18 | stdout_logfile={{ log_path }}/fetch_consumer.log
19 | stderr_logfile={{ log_path }}/fetch_consumer.log
20 | autostart=true
21 | autorestart=true
22 | startsecs=10
23 |
24 |
25 | [program:celery_celery]
26 |
27 | command=nice -n 20 {{ ckan_virtualenv }}/bin/paster --plugin=ckan celeryd run concurrency=1 -q celery --config="{{ ckan_conf_dir }}/production.ini"
28 | user={{ celery_user }}
29 |
30 | numprocs=1
31 | stdout_logfile={{ log_path }}/celeryd.log
32 | stderr_logfile={{ log_path }}/celeryd.log
33 | autostart=true
34 | autorestart=true
35 | startsecs=10
36 |
37 | ; Need to wait for currently executing tasks to finish at shutdown.
38 | ; Increase this if you have very long running tasks.
39 | stopwaitsecs = 600
40 |
41 | ; if rabbitmq is supervised, set its priority higher
42 | ; so it starts first
43 | priority=998
44 |
45 | [program:celery_bulk]
46 |
47 | command=nice -n 20 {{ ckan_virtualenv }}/bin/paster --plugin=ckan celeryd run concurrency=1 -q bulk --config="{{ ckan_conf_dir }}/production.ini"
48 | user={{ celery_user }}
49 |
50 | numprocs=1
51 | stdout_logfile={{ log_path }}/celeryd_bulk.log
52 | stderr_logfile={{ log_path }}/celeryd_bulk.log
53 | autostart=true
54 | autorestart=true
55 | startsecs=10
56 |
57 | ; Need to wait for currently executing tasks to finish at shutdown.
58 | ; Increase this if you have very long running tasks.
59 | stopwaitsecs = 600
60 |
61 | ; if rabbitmq is supervised, set its priority higher
62 | ; so it starts first
63 | priority=998
64 |
65 |
66 | [program:celery_priority]
67 |
68 | command=nice -n 20 {{ ckan_virtualenv }}/bin/paster --plugin=ckan celeryd run concurrency=1 -q priority --config="{{ ckan_conf_dir }}/production.ini"
69 | user={{ celery_user }}
70 |
71 | numprocs=1
72 | stdout_logfile={{ log_path }}/celeryd_priority.log
73 | stderr_logfile={{ log_path }}/celeryd_priority.log
74 | autostart=true
75 | autorestart=true
76 | startsecs=10
77 |
78 | ; Need to wait for currently executing tasks to finish at shutdown.
79 | ; Increase this if you have very long running tasks.
80 | stopwaitsecs = 600
81 |
82 | ; if rabbitmq is supervised, set its priority higher
83 | ; so it starts first
84 | priority=998
85 |
86 | [program:celerybeat]
87 |
88 | command={{ ckan_virtualenv }}/bin/celery beat --config=africaopendata --workdir=/etc/ckan/africaopendata/ --pidfile=/tmp/celerybeat_pid --schedule=/tmp/celerybeat_schedule
89 | user={{ celery_user }}
90 |
91 | numprocs=1
92 | stdout_logfile={{ log_path }}/celerybeat.log
93 | stderr_logfile={{ log_path }}/celerybeat.log
94 | autostart=true
95 | autorestart=true
96 | startsecs=10
97 |
98 | priority=999
99 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/header.html:
--------------------------------------------------------------------------------
1 | {% ckan_extends %}
2 | {% block header_wrapper %}
3 |
4 |
5 |
6 |
7 |
8 |
9 | {% block header_logo %}
10 | {% if g.site_logo %}
11 |
13 | {% else %}
14 |
17 | {% endif %}
18 | {% endblock %}
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
67 |
68 |
69 |
75 |
76 | {% endblock %}
77 | {%- block scripts %}
78 | {% asset 'openafrica/openafrica_bootstrap-js' %}
79 | {{ super() }}
80 | {% endblock -%}
81 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | openAFRICA CKAN Extension
2 | =========================
3 |
4 | CKAN theme for openAFRICA platform accessible at https://openafrica.net/
5 |
6 | ### Development
7 |
8 | Then follow the steps below to install the openAfrica extension:
9 |
10 | Step 1:
11 |
12 | * Activate your virtual environment; use the path to your virtual environment. On Mac OSX, you may have to use `/usr/local/lib/ckan/default/bin/activate`. You can copy the code as it is below, including the preceeding dot.
13 | ```
14 | . /usr/lib/ckan/default/bin/activate
15 | ```
16 |
17 | Step 2:
18 |
19 | * Install the extension
20 |
21 | If you are not a developer and just want to install the extension from package, just run this command from your virtual environment:
22 | ```
23 | pip install ckanext-openafrica
24 | ```
25 | > **Note**: If you wish to modify the extension in any way, you can download the source code and install the extension manually. To do so, execute the following command:
26 | > ```
27 | > $ pip install -e git+https://github.com/CodeForAfrica/ckanext-openafrica.git#egg=ckanext-openafrica
28 | > ```
29 | > **Alternatively**: You can clone this repo (preferrably into the /src directory where you installed CKAN), cd into ckanext-openafrica and run
30 | > ```
31 | > $ python setup.py develop
32 | > ```
33 |
34 | Step 3:
35 |
36 | * Modify your configuration file (generally in `/etc/ckan/default/production.ini`) and add `openafrica` in the `ckan.plugins` property.
37 | ```
38 | ckan.plugins = openafrica
39 | ```
40 |
41 | Step 4:
42 |
43 | * Restart your server:
44 |
45 | ```
46 | paster serve /etc/ckan/default/production.ini
47 | ```
48 | OR
49 | ```
50 | paster serve --reload /etc/ckan/default/production.ini
51 | ```
52 | With `--reload`, your server is restarted automatically whenever you make changes in your source code.
53 |
54 | If your extension is installed successfully, your page will change to the openAfrica theme.
55 |
56 | **Note**: This extension, being a thememing extension, may override templates from other extensions. Templates in /ckanext/openafrica/templates
57 | may require some modifications to render properly with openAfrica extension.
58 |
59 |
60 | ## Contributing
61 |
62 | If you've found a bug/issue in the extension, open a new issue [here](https://github.com/CodeForAfrica/ckanext-openafrica/issues/new) _ (try
63 | searching first to see if there's already an [issue](https://github.com/CodeForAfrica/ckanext-openafrica/issues) for your bug).
64 |
65 | If you are interested in contributing to the development of openAfrica extension, you are welcome. A good starting point
66 | will be reading the CKAN general [Contributing guide](http://docs.ckan.org/en/ckan-2.7.0/contributing/index.html). Then you can checkout
67 | existing [issues](https://github.com/CodeForAfrica/ckanext-openafrica/issues) that are open for contribution; new features and issues are welcome.
68 | To work on any issue, comment on the issue to indicate your interest and the issue will be assigned to you. It is always a good idea to seek
69 | for clarification (where necessary) on any issue you work on.
70 |
71 | **It is important that changes that require some form of configurations should be documented in the README.**
72 |
73 | ---
74 |
75 |
76 | ## License
77 |
78 | GNU General Public License
79 |
80 | openAFRICA aims to be the largest independent repository of open data on the African continent.
81 | Copyright (C) 2017 Code for Africa
82 |
83 | This program is free software: you can redistribute it and/or modify
84 | it under the terms of the GNU General Public License as published by
85 | the Free Software Foundation, either version 3 of the License, or
86 | (at your option) any later version.
87 |
88 | This program is distributed in the hope that it will be useful,
89 | but WITHOUT ANY WARRANTY; without even the implied warranty of
90 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
91 | GNU General Public License for more details.
92 |
93 | You should have received a copy of the GNU General Public License
94 | along with this program. If not, see .
95 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/dataset-page.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {%- block page -%}
4 |
5 | {% block skip %}
6 |
7 | {% endblock %}
8 |
9 | {#
10 | Override the header on a page by page basis by extending this block. If
11 | making sitewide header changes it is preferable to override the header.html
12 | file.
13 | #}
14 | {%- block header %}
15 | {% include "header.html" %}
16 | {% endblock -%}
17 |
18 | {# The content block allows you to replace the content of the page if needed #}
19 | {%- block content %}
20 | {% block maintag %}{% endblock %}
21 |
22 | {% block main_content %}
23 | {% block flash %}
24 |
25 | {% block flash_inner %}
26 | {% for message in h.flash.pop_messages | list %}
27 |
28 | {{ h.literal(message) }}
29 |
30 | {% endfor %}
31 | {% endblock %}
32 |
33 | {% endblock %}
34 |
35 | {% block toolbar %}
36 |
46 | {% endblock %}
47 |
48 |
49 |
50 | {#
51 | The pre_primary block can be used to add content to before the
52 | rendering of the main content columns of the page.
53 | #}
54 | {% block pre_primary %}
55 | {% endblock %}
56 |
57 | {% block primary %}
58 |
59 | {#
60 | The primary_content block can be used to add content to the page.
61 | This is the main block that is likely to be used within a template.
62 |
63 | Example:
64 |
65 | {% block primary_content %}
66 |
My page content
67 |
Some content for the page
68 | {% endblock %}
69 | #}
70 | {% block primary_content %}
71 |
72 | {% block page_header %}
73 |
83 | {% endblock %}
84 |
85 | {% if self.page_primary_action() | trim %}
86 |
87 | {% block page_primary_action %}{% endblock %}
88 |
89 | {% endif %}
90 | {% block primary_content_inner %}
91 | {% endblock %}
92 |
93 |
94 | {% endblock %}
95 |
96 | {% block secondary %}
97 |
98 | {% endblock %}
99 | {% endblock %}
100 |
101 | {% endblock %}
102 |
103 |
104 | {% endblock -%}
105 |
106 | {#
107 | Override the footer on a page by page basis by extending this block. If
108 | making sitewide header changes it is preferable to override the footer.html-u
109 | file.
110 | #}
111 | {%- block footer %}
112 | {% include "footer.html" %}
113 | {% endblock -%}
114 | {%- endblock -%}
115 |
116 | {%- block scripts %}
117 | {% asset 'base/main' %}
118 | {% asset 'base/ckan' %}
119 | {% if g.tracking_enabled %}
120 | {% asset 'base/tracking.js' %}
121 | {% endif %}
122 | {{ super() }}
123 | {% endblock -%}
124 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/snippets/package_item.html:
--------------------------------------------------------------------------------
1 | {#
2 | Displays a single of dataset.
3 |
4 | package - A package to display.
5 | item_class - The class name to use on the list item.
6 | hide_resources - If true hides the resources (default: false).
7 | banner - If true displays a popular banner (default: false).
8 | truncate - The length to trucate the description to (default: 180)
9 | truncate_title - The length to truncate the title to (default: 80).
10 |
11 | Example:
12 |
13 | {% snippet 'snippets/package_item.html', package=c.datasets[0] %}
14 |
15 | #}
16 | {% set truncate = truncate or 180 %}
17 | {% set truncate_title = truncate_title or 80 %}
18 | {% set title = package.title or package.name %}
19 | {% set notes = h.markdown_extract(package.notes, extract_length=truncate) %}
20 | {% set updated_time = package.metadata_modified or package.metadata_created%}
21 | {% set created_time = package.metadata_created%}
22 | {% set f_updated_time = h.render_datetime(updated_time) %}
23 | {% set f_created_time = h.render_datetime(created_time) %}
24 |
25 | {% block package_item %}
26 |
27 | {% block content %}
28 |
29 |
30 | {% block heading %}
31 |
32 | {% block heading_private %}
33 | {% if package.private %}
34 |
35 |
36 | {{ _('Private') }}
37 |
38 | {% endif %}
39 | {% endblock %}
40 | {% block heading_title %}
41 | {{ h.link_to(h.truncate(title, truncate_title), h.url_for(controller='dataset', action='read', id=package.name)) }}
42 | {{package.total}}
43 | {{_('Updated')}} {{f_updated_time}} | {{_('Created')}} {{f_created_time}}
44 | {% if package.organization %}
45 |
51 | {% endif %}
52 | {% endblock %}
53 | {% block heading_meta %}
54 | {% if package.get('state', '').startswith('draft') %}
55 | {{ _('Draft') }}
56 | {% elif package.get('state', '').startswith('deleted') %}
57 | {{ _('Deleted') }}
58 | {% endif %}
59 | {% endblock %}
60 |
61 | {% endblock %}
62 | {% block banner %}
63 | {% if banner %}
64 |
{{ _('Popular') }}
65 | {% endif %}
66 | {% endblock %}
67 |
68 |
98 |
99 | {% endblock %}
100 |
101 | {% endblock %}
102 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/snippets/coc_text.html:
--------------------------------------------------------------------------------
1 | {% trans %}
2 | The data is provided to you the developers for you to develop applications which will make the world a better place, providing more or improved utility for the general public based on public sector datasets. We are here to help you do the great things we know you’re itching to do, but, as part of this being a trusted space in which we work together, there are some basic rules.
3 |
4 | You are encouraged to:
5 |
6 | use provided live sources for the datasets as your primary data source, where possible – much of the data provided is dynamic and fluid (although in many cases over an annual or longer period of time), and basing your application on the keys in the data we are providing will ensure that your application is as up to date as possible;
7 |
8 | where using our data feeds, please if possible cache the data over a short period of time to reduce load both on your application and our servers;
9 |
10 | where you cannot use our live sources as the primary data source, please still use the keys contained within the data as the primary or foreign keys within your application, as this will enable you to migrate as simply as possible to up-to-date data and information when it is made available;
11 |
12 | where using your own long-term caches of our data, please refresh the data within your application in a timely manner when a new set of the data is made available;
13 |
14 | engage with us when something’s wrong – point out any inconsistencies in the data you find, make suggestions about how to improve the service, request new data sources to be added, and tell us about what you have built so we can help you to promote it!
15 |
16 |
17 | You should:
18 |
19 | refer back to and cite the origin or source of the data when using it;
20 | clearly state where possible about which data is derived from official sources, which is from other sources, and which data is from any calculation within or out with your app.
21 |
22 |
23 | You must not:
24 |
25 | make an application that pretends to be an official government service;
26 | present the data in a misleading or incorrect manner or to misrepresent or change the data;
27 |
28 | use this site for party political purposes, as the site paid for with public money so it is not appropriate to engage in party-political activity here;
29 |
30 | use these materials in or to support a criminal or illicit activity;
31 |
32 | use these materials on an application to inflame or make comments that are racist, sexist or homophobic, or which promote or incite violence or illegal activity.
33 |
34 |
35 | Participation Guidelines
36 |
37 | When posting comments about ideas or applications, or posting to the site forum, please observe our site participation guidelines:
38 |
39 |
40 | Be respectful of other users of this site
41 | Stay on topic and do not upload content that is unrelated to the purpose of this site.
42 | Do not use language that is offensive, inflammatory or provocative (this includes swearing and obscene or vulgar comments)
43 | Do not select a user name that is offensive, inflammatory or provocative
44 | Do not break the law (this includes libel, condoning illegal activity and contempt of court)
45 | In the course of using the community areas of this site, please do not post personal information – addresses, phone numbers, email addresses or other online contact details – relating either to you or other individuals
46 | Do not register more than one user account per person
47 | Do not impersonate or falsely claim to represent a person or an organisation. Do not attempt to log on using another user’s account
48 | Do not make any commercial endorsement or promotion of any product, service or publication not relevant to the discussion
49 | Do not post in a language other than English
50 |
51 |
52 | If you are aged 16 or under, please get your parent’s/guardian’s permission before participating. Users without this consent are not allowed to participate or provide us with personal information.
53 |
54 |
55 |
56 | ** Attribution of content - data.gov.uk
57 | {% endtrans %}
58 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/page.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {%- block page -%}
4 |
5 | {% block skip %}
6 |
7 | {% endblock %}
8 |
9 | {#
10 | Override the header on a page by page basis by extending this block. If
11 | making sitewide header changes it is preferable to override the header.html
12 | file.
13 | #}
14 | {%- block header %}
15 | {% include "header.html" %}
16 | {% endblock -%}
17 |
18 | {# The content block allows you to replace the content of the page if needed #}
19 | {%- block content %}
20 | {% block maintag %}{% endblock %}
21 |
22 | {% block main_content %}
23 | {% block flash %}
24 |
25 | {% block flash_inner %}
26 | {% for message in h.flash.pop_messages | list %}
27 |
28 | {{ h.literal(message) }}
29 |
30 | {% endfor %}
31 | {% endblock %}
32 |
33 | {% endblock %}
34 |
35 | {% block toolbar %}
36 |
46 | {% endblock %}
47 |
48 |
49 |
50 | {#
51 | The pre_primary block can be used to add content to before the
52 | rendering of the main content columns of the page.
53 | #}
54 | {% block pre_primary %}
55 | {% endblock %}
56 |
57 | {% block primary %}
58 |
59 | {#
60 | The primary_content block can be used to add content to the page.
61 | This is the main block that is likely to be used within a template.
62 |
63 | Example:
64 |
65 | {% block primary_content %}
66 |
My page content
67 |
Some content for the page
68 | {% endblock %}
69 | #}
70 | {% block primary_content %}
71 |
72 | {% block page_header %}
73 |
83 | {% endblock %}
84 |
85 | {% if self.page_primary_action() | trim %}
86 |
87 | {% block page_primary_action %}{% endblock %}
88 |
89 | {% endif %}
90 | {% block primary_content_inner %}
91 | {% endblock %}
92 |
93 |
94 | {% endblock %}
95 |
96 | {% endblock %}
97 |
98 | {% block secondary %}
99 |
114 | {% endblock %}
115 |
116 | {% endblock %}
117 |
118 |
119 | {% endblock -%}
120 |
121 | {#
122 | Override the footer on a page by page basis by extending this block. If
123 | making sitewide header changes it is preferable to override the footer.html-u
124 | file.
125 | #}
126 | {%- block footer %}
127 | {% include "footer.html" %}
128 | {% endblock -%}
129 | {%- endblock -%}
130 |
131 | {%- block scripts %}
132 | {% asset 'base/main' %}
133 | {% asset 'base/ckan' %}
134 | {% if g.tracking_enabled %}
135 | {% asset 'base/tracking.js' %}
136 | {% endif %}
137 | {{ super() }}
138 | {% endblock -%}
139 |
--------------------------------------------------------------------------------
/deploy/roles/solr/templates/solr.in.sh.j2:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | # By default the script will use JAVA_HOME to determine which java
17 | # to use, but you can set a specific path for Solr to use without
18 | # affecting other Java applications on your server/workstation.
19 | #SOLR_JAVA_HOME=""
20 |
21 | # Increase Java Heap as needed to support your indexing / query needs
22 | #SOLR_HEAP="512m"
23 |
24 | # Expert: If you want finer control over memory options, specify them directly
25 | # Comment out SOLR_HEAP if you are using this though, that takes precedence
26 | SOLR_JAVA_MEM="{{ solr_java_mem }}"
27 |
28 | # Enable verbose GC logging
29 | GC_LOG_OPTS="-verbose:gc -XX:+PrintHeapAtGC -XX:+PrintGCDetails \
30 | -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime"
31 |
32 | # These GC settings have shown to work well for a number of common Solr workloads
33 | GC_TUNE="-XX:NewRatio=3 \
34 | -XX:SurvivorRatio=4 \
35 | -XX:TargetSurvivorRatio=90 \
36 | -XX:MaxTenuringThreshold=8 \
37 | -XX:+UseConcMarkSweepGC \
38 | -XX:+UseParNewGC \
39 | -XX:ConcGCThreads=4 -XX:ParallelGCThreads=4 \
40 | -XX:+CMSScavengeBeforeRemark \
41 | -XX:PretenureSizeThreshold=64m \
42 | -XX:+UseCMSInitiatingOccupancyOnly \
43 | -XX:CMSInitiatingOccupancyFraction=50 \
44 | -XX:CMSMaxAbortablePrecleanTime=6000 \
45 | -XX:+CMSParallelRemarkEnabled \
46 | -XX:+ParallelRefProcEnabled"
47 |
48 | # Set the ZooKeeper connection string if using an external ZooKeeper ensemble
49 | # e.g. host1:2181,host2:2181/chroot
50 | # Leave empty if not using SolrCloud
51 | #ZK_HOST=""
52 |
53 | # Set the ZooKeeper client timeout (for SolrCloud mode)
54 | #ZK_CLIENT_TIMEOUT="15000"
55 |
56 | # By default the start script uses "localhost"; override the hostname here
57 | # for production SolrCloud environments to control the hostname exposed to cluster state
58 | #SOLR_HOST="192.168.1.1"
59 |
60 | # By default the start script uses UTC; override the timezone if needed
61 | #SOLR_TIMEZONE="UTC"
62 |
63 | # Set to true to activate the JMX RMI connector to allow remote JMX client applications
64 | # to monitor the JVM hosting Solr; set to "false" to disable that behavior
65 | # (false is recommended in production environments)
66 | ENABLE_REMOTE_JMX_OPTS="false"
67 |
68 | # The script will use SOLR_PORT+10000 for the RMI_PORT or you can set it here
69 | # RMI_PORT=18983
70 |
71 | # Anything you add to the SOLR_OPTS variable will be included in the java
72 | # start command line as-is, in ADDITION to other options. If you specify the
73 | # -a option on start script, those options will be appended as well. Examples:
74 | #SOLR_OPTS="$SOLR_OPTS -Dsolr.autoSoftCommit.maxTime=3000"
75 | #SOLR_OPTS="$SOLR_OPTS -Dsolr.autoCommit.maxTime=60000"
76 | #SOLR_OPTS="$SOLR_OPTS -Dsolr.clustering.enabled=true"
77 |
78 | # Location where the bin/solr script will save PID files for running instances
79 | # If not set, the script will create PID files in $SOLR_TIP/bin
80 | SOLR_PID_DIR={{ solr_var_dir }}
81 |
82 | # Path to a directory where Solr creates index files, the specified directory
83 | # must contain a solr.xml; by default, Solr will use server/solr
84 | SOLR_HOME={{ solr_var_dir }}/data
85 |
86 | # Solr provides a default Log4J configuration properties file in server/resources
87 | # however, you may want to customize the log settings and file appender location
88 | # so you can point the script to use a different log4j.properties file
89 | LOG4J_PROPS={{ solr_var_dir }}/log4j.properties
90 |
91 | # Location where Solr should write logs to; should agree with the file appender
92 | # settings in server/resources/log4j.properties
93 | SOLR_LOGS_DIR={{ solr_var_dir }}/logs
94 |
95 | # Sets the port Solr binds to, default is 8983
96 | SOLR_PORT={{ solr_port }}
97 |
98 | # Uncomment to set SSL-related system properties
99 | # Be sure to update the paths to the correct keystore for your environment
100 | #SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks
101 | #SOLR_SSL_KEY_STORE_PASSWORD=secret
102 | #SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks
103 | #SOLR_SSL_TRUST_STORE_PASSWORD=secret
104 | #SOLR_SSL_NEED_CLIENT_AUTH=false
105 | #SOLR_SSL_WANT_CLIENT_AUTH=false
106 |
107 | # Uncomment if you want to override previously defined SSL values for HTTP client
108 | # otherwise keep them commented and the above values will automatically be set for HTTP clients
109 | #SOLR_SSL_CLIENT_KEY_STORE=
110 | #SOLR_SSL_CLIENT_KEY_STORE_PASSWORD=
111 | #SOLR_SSL_CLIENT_TRUST_STORE=
112 | #SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD=
113 |
114 | # Settings for authentication
115 | #SOLR_AUTHENTICATION_CLIENT_CONFIGURER=
116 | #SOLR_AUTHENTICATION_OPTS=
117 |
--------------------------------------------------------------------------------
/deploy/roles/db/templates/pg_hba-9.3.conf.j2:
--------------------------------------------------------------------------------
1 | # PostgreSQL Client Authentication Configuration File
2 | # ===================================================
3 | #
4 | # Refer to the "Client Authentication" section in the PostgreSQL
5 | # documentation for a complete description of this file. A short
6 | # synopsis follows.
7 | #
8 | # This file controls: which hosts are allowed to connect, how clients
9 | # are authenticated, which PostgreSQL user names they can use, which
10 | # databases they can access. Records take one of these forms:
11 | #
12 | # local DATABASE USER METHOD [OPTIONS]
13 | # host DATABASE USER ADDRESS METHOD [OPTIONS]
14 | # hostssl DATABASE USER ADDRESS METHOD [OPTIONS]
15 | # hostnossl DATABASE USER ADDRESS METHOD [OPTIONS]
16 | #
17 | # (The uppercase items must be replaced by actual values.)
18 | #
19 | # The first field is the connection type: "local" is a Unix-domain
20 | # socket, "host" is either a plain or SSL-encrypted TCP/IP socket,
21 | # "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a
22 | # plain TCP/IP socket.
23 | #
24 | # DATABASE can be "all", "sameuser", "samerole", "replication", a
25 | # database name, or a comma-separated list thereof. The "all"
26 | # keyword does not match "replication". Access to replication
27 | # must be enabled in a separate record (see example below).
28 | #
29 | # USER can be "all", a user name, a group name prefixed with "+", or a
30 | # comma-separated list thereof. In both the DATABASE and USER fields
31 | # you can also write a file name prefixed with "@" to include names
32 | # from a separate file.
33 | #
34 | # ADDRESS specifies the set of hosts the record matches. It can be a
35 | # host name, or it is made up of an IP address and a CIDR mask that is
36 | # an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that
37 | # specifies the number of significant bits in the mask. A host name
38 | # that starts with a dot (.) matches a suffix of the actual host name.
39 | # Alternatively, you can write an IP address and netmask in separate
40 | # columns to specify the set of hosts. Instead of a CIDR-address, you
41 | # can write "samehost" to match any of the server's own IP addresses,
42 | # or "samenet" to match any address in any subnet that the server is
43 | # directly connected to.
44 | #
45 | # METHOD can be "trust", "reject", "md5", "password", "gss", "sspi",
46 | # "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert". Note that
47 | # "password" sends passwords in clear text; "md5" is preferred since
48 | # it sends encrypted passwords.
49 | #
50 | # OPTIONS are a set of options for the authentication in the format
51 | # NAME=VALUE. The available options depend on the different
52 | # authentication methods -- refer to the "Client Authentication"
53 | # section in the documentation for a list of which options are
54 | # available for which authentication methods.
55 | #
56 | # Database and user names containing spaces, commas, quotes and other
57 | # special characters must be quoted. Quoting one of the keywords
58 | # "all", "sameuser", "samerole" or "replication" makes the name lose
59 | # its special character, and just match a database or username with
60 | # that name.
61 | #
62 | # This file is read on server startup and when the postmaster receives
63 | # a SIGHUP signal. If you edit the file on a running system, you have
64 | # to SIGHUP the postmaster for the changes to take effect. You can
65 | # use "pg_ctl reload" to do that.
66 |
67 | # Put your actual configuration here
68 | # ----------------------------------
69 | #
70 | # If you want to allow non-local connections, you need to add more
71 | # "host" records. In that case you will also need to make PostgreSQL
72 | # listen on a non-local interface via the listen_addresses
73 | # configuration parameter, or via the -i or -h command line switches.
74 |
75 |
76 |
77 |
78 | # DO NOT DISABLE!
79 | # If you change this first entry you will need to make sure that the
80 | # database superuser can access the database using some other method.
81 | # Noninteractive access to all databases is required during automatic
82 | # maintenance (custom daily cronjobs, replication, and similar tasks).
83 | #
84 | # Database administrative login by Unix domain socket
85 | # for local postgres user - we can also use md5(encrypted pass)
86 | local all postgres peer
87 |
88 | # TYPE DATABASE USER ADDRESS METHOD
89 |
90 | # "local" is for Unix domain socket connections only
91 | local all all md5
92 |
93 | # IPv4 local connections:
94 | #host all all 127.0.0.1/32 md5
95 | # allow db connections from specific ipsets
96 | {% if pg_db_connections is defined %}
97 | {% for rule in pg_db_connections|sort(attribute='src_addr') %}
98 | {{ rule.type }} {{ rule.db }} {{ rule.user }} {{ rule.src_addr }} {{ rule.method }}
99 | {% endfor %}
100 | {% endif %}
101 |
102 | # IPv6 local connections:
103 | host all all ::1/128 md5
104 | # Allow replication connections from localhost, by a user with the
105 | # replication privilege.
106 | #local replication postgres peer
107 | #host replication postgres 127.0.0.1/32 md5
108 | #host replication postgres ::1/128 md5
109 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/footer.html:
--------------------------------------------------------------------------------
1 | {% ckan_extends %}
2 | {% block footer_content %}
3 |
4 |
126 |
127 |
128 | {%block google_analytics %}
129 |
130 |
131 |
141 | {% endblock %}
142 | {% endblock %}
143 |
--------------------------------------------------------------------------------
/deploy/roles/ckan/templates/production-2.3.ini.j2:
--------------------------------------------------------------------------------
1 | #
2 | # CKAN - Pylons configuration
3 | #
4 | # These are some of the configuration options available for your CKAN
5 | # instance. Check the documentation in 'doc/configuration.rst' or at the
6 | # following URL for a description of what they do and the full list of
7 | # available options:
8 | #
9 | # http://docs.ckan.org/en/latest/maintaining/configuration.html
10 | #
11 | # The %(here)s variable will be replaced with the parent directory of this file
12 | #
13 |
14 | [DEFAULT]
15 |
16 | # WARNING: *THIS SETTING MUST BE SET TO FALSE ON A PRODUCTION ENVIRONMENT*
17 | debug = {{ ckan_debug_mode }}
18 |
19 | [server:main]
20 | use = egg:Paste#http
21 | host = 0.0.0.0
22 | port = 5000
23 |
24 | [app:main]
25 | use = egg:ckan
26 | full_stack = true
27 | cache_dir = /tmp/%(ckan.site_id)s/
28 | beaker.session.key = ckan
29 |
30 | # This is the secret token that the beaker library uses to hash the cookie sent
31 | # to the client. `paster make-config` generates a unique value for this each
32 | # time it generates a config file.
33 | # Ansible will run the following command & fill it using sed/lineinfile
34 | # {{ ckan_virtualenv }}/bin/python -c "from paste.script.util import secret; print secret.secret_string()"
35 | beaker.session.secret =
36 |
37 | # `paster make-config` generates a unique value for this each time it generates
38 | # a config file
39 | # Ansible will run the following command & fill it using sed/lineinfile
40 | # {{ ckan_virtualenv }}/bin/python -c "from paste.script.util import uuid; print uuid.uuid4()"
41 | app_instance_uuid =
42 |
43 | # repoze.who config
44 | who.config_file = %(here)s/who.ini
45 | who.log_level = warning
46 | who.log_file = %(cache_dir)s/who_log.ini
47 | # Session timeout (user logged out after period of inactivity, in seconds).
48 | # Inactive by default, so the session doesn't expire.
49 | # who.timeout = 86400
50 |
51 | ## Database Settings
52 | #sqlalchemy.url = postgres://USERNAME:PASSWORD@HOST/DBNAME
53 | sqlalchemy.url = postgresql://{{ ckan_db.username }}:{{ ckan_db.password }}@{{ ckan_db.dbhost }}/{{ ckan_db.dbname }}
54 |
55 | #ckan.datastore.write_url = postgresql://ckan_default:pass@localhost/datastore_default
56 | #ckan.datastore.read_url = postgresql://datastore_default:pass@localhost/datastore_default
57 |
58 | # PostgreSQL' full-text search parameters
59 | ckan.datastore.default_fts_lang = english
60 | ckan.datastore.default_fts_index_method = gist
61 |
62 | ## Site Settings
63 |
64 | ckan.site_url = {{ ckan_site_url }}
65 |
66 |
67 | ## Authorization Settings
68 |
69 | ckan.auth.anon_create_dataset = false
70 | ckan.auth.create_unowned_dataset = true
71 | ckan.auth.create_dataset_if_not_in_organization = true
72 | ckan.auth.user_create_groups = true
73 | ckan.auth.user_create_organizations = true
74 | ckan.auth.user_delete_groups = true
75 | ckan.auth.user_delete_organizations = true
76 | ckan.auth.create_user_via_api = false
77 | ckan.auth.create_user_via_web = true
78 | ckan.auth.roles_that_cascade_to_sub_groups = admin
79 |
80 |
81 | ## Search Settings
82 |
83 | ckan.site_id = {{ ckan_site_name }}
84 | #solr_url = http://127.0.0.1:8983/solr/ckan_default
85 | solr_url = {{ ckan_solr_url }}
86 |
87 | #ckan.simple_search = 1
88 |
89 |
90 | ## CORS Settings
91 |
92 | # If cors.origin_allow_all is true, all origins are allowed.
93 | # If false, the cors.origin_whitelist is used.
94 | # ckan.cors.origin_allow_all = true
95 | # cors.origin_whitelist is a space separated list of allowed domains.
96 | # ckan.cors.origin_whitelist = http://example1.com http://example2.com
97 |
98 |
99 | ## Plugins Settings
100 |
101 | # Note: Add ``datastore`` to enable the CKAN DataStore
102 | # Add ``datapusher`` to enable DataPusher
103 | # Add ``resource_proxy`` to enable resorce proxying and get around the
104 | # same origin policy
105 | ckan.plugins = stats text_view image_view recline_view openafrica
106 |
107 | # Define which views should be created by default
108 | # (plugins must be loaded in ckan.plugins)
109 | ckan.views.default_views = image_view text_view recline_view
110 |
111 |
112 | ## Front-End Settings
113 | ckan.site_title = CKAN
114 | ckan.site_logo = /images/logos/openafrica.png
115 | ckan.site_description =
116 | ckan.favicon = /images/icons/ckan.ico
117 | ckan.gravatar_default = identicon
118 | ckan.preview.direct = png jpg gif
119 | ckan.preview.loadable = html htm rdf+xml owl+xml xml n3 n-triples turtle plain atom csv tsv rss txt json
120 |
121 | # package_hide_extras = for_search_index_only
122 | #package_edit_return_url = http://another.frontend/dataset/
123 | #package_new_return_url = http://another.frontend/dataset/
124 | #ckan.recaptcha.publickey =
125 | #ckan.recaptcha.privatekey =
126 | #licenses_group_url = http://licenses.opendefinition.org/licenses/groups/ckan.json
127 | # ckan.template_footer_end =
128 |
129 |
130 | ## Internationalisation Settings
131 | ckan.locale_default = en
132 | ckan.locale_order = en pt_BR ja it cs_CZ ca es fr el sv sr sr@latin no sk fi ru de pl nl bg ko_KR hu sa sl lv
133 | ckan.locales_offered =
134 | ckan.locales_filtered_out = en_GB
135 |
136 | ## Feeds Settings
137 |
138 | ckan.feeds.authority_name =
139 | ckan.feeds.date =
140 | ckan.feeds.author_name =
141 | ckan.feeds.author_link =
142 |
143 | ## Storage Settings
144 |
145 | ckan.storage_path = {{ ckan_storage_path }}
146 | ckan.max_resource_size = {{ ckan_max_resource_size }}
147 | ckan.max_image_size = {{ ckan_max_image_size }}
148 |
149 | ## Datapusher settings
150 |
151 | # Make sure you have set up the DataStore
152 |
153 | #ckan.datapusher.formats = csv xls xlsx tsv application/csv application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
154 | #ckan.datapusher.url = http://127.0.0.1:8800/
155 |
156 | # Resource Proxy settings
157 | # Preview size limit, default: 1MB
158 | #ckan.resource_proxy.max_file_size = 1 * 1024 * 1024
159 |
160 | ## Activity Streams Settings
161 |
162 | #ckan.activity_streams_enabled = true
163 | #ckan.activity_list_limit = 31
164 | #ckan.activity_streams_email_notifications = true
165 | #ckan.email_notifications_since = 2 days
166 | ckan.hide_activity_from_users = %(ckan.site_id)s
167 |
168 |
169 | ## Email settings
170 |
171 | #email_to = {{ ckan_email_to }}
172 | #error_email_from = {{ ckan_error_email_from }}
173 | #smtp.server = {{ ckan_smtp_server }}
174 | #smtp.starttls = {{ ckan_smtp_starttls }}
175 | #smtp.user = {{ ckan_smtp_user }}
176 | #smtp.password = {{ ckan_smtp_password }}
177 | #smtp.mail_from = {{ ckan_smtp_mail_from }}
178 |
179 |
180 | ## Logging configuration
181 | [loggers]
182 | keys = root, ckan, ckanext
183 |
184 | [handlers]
185 | keys = console
186 |
187 | [formatters]
188 | keys = generic
189 |
190 | [logger_root]
191 | level = WARNING
192 | handlers = console
193 |
194 | [logger_ckan]
195 | level = INFO
196 | handlers = console
197 | qualname = ckan
198 | propagate = 0
199 |
200 | [logger_ckanext]
201 | level = DEBUG
202 | handlers = console
203 | qualname = ckanext
204 | propagate = 0
205 |
206 | [handler_console]
207 | class = StreamHandler
208 | args = (sys.stderr,)
209 | level = NOTSET
210 | formatter = generic
211 |
212 | [formatter_generic]
213 | format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s
214 |
--------------------------------------------------------------------------------
/deploy/roles/ckan/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # file: tasks/main.yml
3 |
4 | - name: Install ckan dependencies
5 | apt: name={{ item }} update_cache=yes state=latest
6 | with_items:
7 | - git-core
8 | - libpq-dev
9 | - python-dev
10 | - python-pip
11 | - python-virtualenv
12 |
13 | - name: Upgrade python-pip
14 | command: pip install --upgrade pip
15 |
16 | - name: Create ckan system user account
17 | when: ckan_user is defined
18 | user: name={{ ckan_user.name }} system={{ ckan_user.system }} createhome=yes home={{ ckan_user.home_path }} shell={{ ckan_user.shell }} comment="{{ckan_user.description}}"
19 |
20 | - name: Install ckan
21 | #become_user: "{{ ckan_user.name }}"
22 | pip: name="{{ckan_src_url}}" virtualenv={{ ckan_virtualenv }} state=present
23 |
24 | - name: Install ckan python modules
25 | #become_user: "{{ ckan_user.name }}"
26 | pip: requirements="{{ ckan_virtualenv }}/src/ckan/requirements.txt" virtualenv={{ ckan_virtualenv }} state=present
27 |
28 | - name: get openafrica
29 | action: git repo=https://github.com/jmwenda/ckanext-openafrica dest={{ ckan_virtualenv }}/src/ckanext-openafrica version=develop
30 |
31 | - name: run setup.py develop for openafrica
32 | action: command chdir={{ ckan_virtualenv }}/src/ckanext-openafrica/ ../../bin/python setup.py develop
33 |
34 | - name: get harvest
35 | action: git repo=https://github.com/ckan/ckanext-harvest.git dest={{ ckan_virtualenv }}/src/ckanext-harvest version=release-datagov
36 |
37 | - name: run setup.py develop for the harvester
38 | action: command chdir={{ ckan_virtualenv }}/src/ckanext-harvest/ ../../bin/python setup.py develop
39 |
40 | - name: install requirements for harvest
41 | action: pip requirements={{ ckan_virtualenv }}/src/ckanext-harvest/pip-requirements.txt virtualenv={{ ckan_virtualenv}}
42 |
43 | - name: get showcase
44 | action: git repo=https://github.com/ckan/ckanext-showcase dest={{ ckan_virtualenv }}/src/ckanext-showcase version=master
45 |
46 | - name: run setup.py develop for showcase
47 | action: command chdir={{ ckan_virtualenv }}/src/ckanext-showcase/ ../../bin/python setup.py develop
48 |
49 | - name: Create ckan postgresql user
50 | become_user: postgres
51 | postgresql_user: name={{ ckan_db.username }} password={{ ckan_db.password }}
52 | tags: db
53 |
54 | - name: Create ckan postgresql database
55 | become_user: postgres
56 | postgresql_db: name={{ ckan_db.dbname }} encoding='UTF-8' template='template0' owner={{ ckan_db.username }}
57 | tags: db
58 |
59 | - name: Create ckan config dir.
60 | file: path={{ ckan_conf_dir }} owner={{ ckan_user.name }} group={{ ckan_user.name }} mode=0755 state=directory
61 |
62 | # NOTE: Add production.ini template
63 | - name: Copy ckan production.ini config file
64 | template: src="production-{{ ckan_version }}.ini.j2" dest="{{ ckan_conf_dir }}/production.ini" owner={{ ckan_user.name }} group={{ ckan_user.name }} mode=0644
65 | notify: reload apache2
66 |
67 | - name: Create ckan data uploads dir.
68 | file: path={{ ckan_storage_path }} owner=www-data group={{ ckan_user.name }} mode=0775 state=directory
69 |
70 | - name: Generate beaker secret token
71 | command: "{{ ckan_virtualenv }}/bin/python -c 'from paste.script.util import secret; print secret.secret_string()'"
72 | register: beaker_secret_token
73 |
74 | - name: Set beaker.session.secret in production.ini
75 | lineinfile: regexp="^beaker\.session\.secret\ =$" line="beaker.session.secret = {{ beaker_secret_token.stdout }}" dest="{{ ckan_conf_dir }}/production.ini" backrefs=yes state=present
76 | when: beaker_secret_token is defined
77 |
78 | - name: Generate ckan aplication instance UUID
79 | command: "{{ ckan_virtualenv }}/bin/python -c 'from paste.script.util import uuid; print uuid.uuid4()'"
80 | register: app_instance_uuid
81 |
82 | - name: Set app_instance_uuid in production.ini
83 | lineinfile: regexp="^app_instance_uuid =$" line="app_instance_uuid = {{ app_instance_uuid.stdout }}" dest="{{ ckan_conf_dir }}/production.ini" backrefs=yes state=present
84 | when: app_instance_uuid is defined
85 |
86 | - name: Symlink who.ini to ckan config. dir
87 | file: src="{{ ckan_virtualenv }}/src/ckan/who.ini" dest="{{ ckan_conf_dir }}/who.ini" owner={{ ckan_user.name }} group={{ ckan_user.name }} state=link
88 |
89 | ## TODO: copy solr schema.xml. what about multi-core/multi-ckan instances ??
90 | - name: Configure solr core used by ckan
91 | # command: /bin/cp -a {{ ckan_virtualenv }}/src/ckan/ckan/config/solr/schema.xml {{ solr_var_dir }}/data/{{ item }}/conf/schema.xml creates={{ solr_var_dir }}/data/{{ item }}/conf/schema.xml
92 | command: /bin/cp -a {{ ckan_virtualenv }}/src/ckan/ckan/config/solr/schema.xml {{ solr_var_dir }}/data/{{ item }}/conf/schema.xml
93 | notify: reload solr
94 | with_items: "{{ solr_cores }}"
95 | tags: solr
96 |
97 | - name: Copy the schema to managed schema
98 | command: /bin/cp -a {{ solr_var_dir }}/data/{{ item }}/conf/schema.xml {{ solr_var_dir }}/data/{{ item }}/conf/managed-schema
99 | with_items: "{{ solr_cores }}"
100 | tags: solr
101 |
102 | - name: Copy the solrschema to the conf
103 | template: src="solrconfig.xml" dest="{{ solr_var_dir }}/data/{{ item }}/conf/" owner={{ solr_user.name }} group={{ solr_user.name }} mode=0644
104 | notify: restart solr
105 | with_items: "{{ solr_cores }}"
106 | tags: solr
107 |
108 | - name: Restart solr because of its ideosyncrancies
109 | sudo: yes
110 | service: name=solr state=restarted
111 | register: restart
112 |
113 | ## TODO: find a way of running paster & make it idempotent - maybe touch a file ??
114 | - name: Initialize ckan postgresql database
115 | become_user: "{{ckan_user.name}}"
116 | command: "{{ ckan_virtualenv }}/bin/paster --plugin=ckan db init -c {{ ckan_conf_dir }}/production.ini"
117 | # command: "{{ ckan_virtualenv }}/bin/paster db init -c {{ ckan_conf_dir }}/production.ini"
118 | # args:
119 | # chdir: "{{ ckan_virtualenv }}/src/ckan"
120 |
121 | - name: Rebuild search index
122 | command: "{{ckan_virtualenv}}/bin/paster --plugin=ckan search-index rebuild -c {{ ckan_conf_dir}}/production.ini"
123 |
124 | - name: Create apache2 default vhost for ckan
125 | template: src="apache/000-ckan-default.conf.j2" dest="/etc/apache2/sites-available/000-default.conf" owner=root group=root mode=0644
126 | notify: reload apache2
127 | tags:
128 | - ckan
129 | - apache
130 |
131 | - name: Enable apache2 default vhost for ckan
132 | file: src="/etc/apache2/sites-available/000-default.conf" dest="/etc/apache2/sites-enabled/000-default.conf" state=link owner=root group=root mode=0644
133 | notify: reload apache2
134 | tags:
135 | - ckan
136 | - apache
137 |
138 | - name: Create apache2 WSGI file
139 | template: src="apache/ckan-apache.wsgi.j2" dest="{{ ckan_conf_dir }}/apache.wsgi" owner={{ ckan_user.name }} group={{ ckan_user.name }} mode=0644
140 | notify: reload apache2
141 | tags:
142 | - ckan
143 | - apache
144 |
145 | - name: Create nginx default vhost for ckan
146 | template: src="nginx/default-vhost.conf.j2" dest="/etc/nginx/conf.d/default.conf" owner=root group=root mode=0644
147 | notify: reload nginx
148 | tags:
149 | - ckan
150 | - nginx
151 |
152 | - name: Copy supervisor configuration
153 | template: src="supervisor.conf.j2" dest="/etc/supervisor/conf.d/africaopendata.conf" mode="0644" owner=root group=root
154 | register: supervisor_configuration
155 | notify:
156 | - Restart Gather
157 | - Restart Fetch
158 | tags:
159 | - ckan
160 |
161 | - name: Create log directory
162 | file: path={{ log_path }} state=directory
163 |
164 | - name: Reread supervisor
165 | shell: supervisorctl reread
166 | when: supervisor_configuration|changed
167 | tags:
168 | - ckan
169 |
170 | - name: Ensure supervisor services
171 | shell: supervisorctl add {{ item }}
172 | when: supervisor_configuration|changed
173 | with_flattened:
174 | - supervisor_services
175 | tags:
176 | - ckan
177 |
178 | - name: Ensure supervisor services are restarted
179 | supervisorctl: name={{ item }} state=restarted
180 | #when: supervisor_configuration|changed or modules_install|changed or ckan_configuration|changed
181 | with_flattened:
182 | - supervisor_services
183 | tags:
184 | - ckan
185 |
186 | - name: Ensure supervisor services are started
187 | supervisorctl: name={{ item }} state=started
188 | with_flattened:
189 | - supervisor_services
190 | tags:
191 | - ckan
192 |
193 | # vim: set sw=2 ts=2:
194 |
--------------------------------------------------------------------------------
/ckanext/openafrica/templates/home/snippets/faq_text.html:
--------------------------------------------------------------------------------
1 | {% trans %}
2 |
3 |
4 | What is the project doing?
5 | What is the status of this site?
6 | Will personal information be at risk?
7 | What is a mashup?
8 | What is Linked Data and how does it fit into the Semantic Web?
9 | How can people submit applications and visualisations?
10 | How can people submit ideas?
11 | How can people use data.gov.uk?
12 | How were the datasets in data.gov.uk selected?
13 | Why is a particular dataset not available yet, and when will it be?
14 | Why is a particular dataset not available through an API yet, and when will it be?
15 | How can people make contact with the project?
16 | Is there a place for developers to discuss ideas, applications and using the data?
17 | Will more public data become available in the future?
18 | What are the commercial use rights if people have commercial ideas?
19 | Under what licence is the data available?
20 | Are there any “do”s and “don’t”s?
21 |
22 |
23 | Q. What is the project doing?
24 |
25 | A.The openAFRICA platform aims to be largest repository of Data on the Africa Continent. We are creating a Library of Congress of Data for African for use by Citizens, Media, Activists, Governments and Civil Society. This is only about non-personal, non-sensitive data – information like the list of schools, crime rates or the performance of your council. The site is the first step in creating a network of reusable and Linked Data that will also tie into the various Ujuzi initiatives.
26 |
27 | Q. What is the status of this site?
28 |
29 | A. The openAFRICA platform is still in Beta. Since then we have launched a number of enhancements which you can read about via the blog. Developments are continuing across the site so do check back regularly and of course please tell us what you think. We welcome your feedback
30 |
31 | Q. Will personal information be at risk?
32 |
33 | A. The data we publish here, and on related websites, will not identify or provide ways to identify individuals, unless that information is already published (like head teachers of schools).
34 |
35 | Q. What is a mashup?
36 |
37 | A. A mashup is a web page or, more usually, a web application that combines data or code from two or more sources. It provides information or functionality beyond that designed or envisaged by the original producers of the data. The attraction of data mashing lies in the ease and speed with which new web applications can be launched with limited resources. People also create visualisations – pictures that show the data in clear, imaginative ways and tell a story about the underlying information. For example, a mashup combining data sources such as school addresses and school league tables to display the results using a mapping tool could show where high-achieving schools are. This would be of interest to parents of school-age children who are considering moving house. We expect that new and exciting mashups will be the main product of collaboration through this website: be inventive and make things.
38 |
39 | Q. What is Linked Data and how does it fit into the Semantic Web?
40 |
41 | A. The Semantic Web is an evolution of the World Wide Web that, rather than just linking from one document to another, focuses on their meaning in relation to each other. Linked Data is a set of technologies to achieve this for data, creating a web of data.
42 |
43 | Here is Sir Tim Berners-Lee explaining the Semantic Web at TED this year:
44 |
45 | While the technical details are complicated, and very well explained by resources like Jeni Tennison’s practitioner’s blog or the Talis platform wiki, the important thing is how it enables people to exchange links to information and the context for that information.
46 | Tim Berners-Lee
47 |
48 |
49 | Q. How can people submit applications and visualisations?
50 |
51 | A. Go to the Apps Page, where you’ll find information on all applications and visualisations that people have submitted so far, a link for submitting your own application and facilities for joining in discussions.
52 |
53 | Q. How can people submit ideas
54 |
55 | A. This site is not just for people with technical know-how; it’s also for people who might have a good idea for an application, but aren’t in a position to build it themselves. Go to the ideas page where you’ll find all the ideas that people have submitted and the facility to submit yours.
56 |
57 | Q. How can people use data.gov.uk?
58 |
59 | A. The Open Africa Platform uses a search engine to offer several ways of finding the data you want. You can view all the datasets to see everything that is currently available, or search by keyword, category or department / agency. Each dataset provides guidance on accessing its data. You can also browse datasets by public body, by nation, a-z listing, as well as subject tags.
60 |
61 | Q. How were the datasets in data.gov.uk selected?
62 |
63 | A. Excluding personal and sensitive information, all information created by public sector bodies, other Government Agencies, Donor Agencies, International Institutions, Civil Society Organizations,to name a few is, in principle, available for re-use.
64 |
65 | Q. Why is a particular dataset not available yet?
66 |
67 | A. Given the vast volumes of data, it is difficult to get all Data however our aim is to get as much high value Datasets as we possibly can.
68 |
69 | Q. Why is a particular dataset not available through an API yet, and when will it be?
70 |
71 | A. The W3C guidance on opening up government data suggests that data should be published in its original raw format so that it’s available for re-use as soon as possible. Over time, we will convert datasets to use Linked Data standards for easy re-use.
72 |
73 | Q. How can people make contact with the project?
74 |
75 | A. We will provide developer community members who register through our Google Group with project updates. You can also follow the project on Twitter and by reading the blog pages. To keep up with the latest progress and developments, check the posts on the apps page and ideas page discussion boards.
76 |
77 | Q. Is there a place for developers to discuss ideas, applications and using of the data?
78 |
79 | A. Yes, the Google Group is for that purpose. We realise that you’ll want to ask us and each other questions and we’ll try and help as best we can. There is also a wiki where you can work together to share techniques, ideas, problems and tools, using data from various sources to help people understand and get more from their area, issues of interest, and the world we live in.
80 |
81 | Q. Will more public data become available in the future?
82 |
83 | A. Yes, this is just the start. As the project matures, more data will flow on to the site.
84 |
85 |
Q. What are the commercial use rights if people have commercial ideas?
86 |
87 | A. The Open Government License enables you to use all our data for commercial purposes. We are delighted that you see a commercial opportunity in using our data.
88 |
89 | Q. Under what licence is the data available?
90 |
91 | A. In general, the data is licensed under the Open Government License. You can read more details on what that means on our Licence Page.
92 |
93 | Q. Are there any “do”s and “don’t”s?
94 |
95 | A. We have a simple code of conduct, relating to your use of the data in your application. It covers how to relate your application data to the data we provide, and simple common-sense usage of the data.
96 |
97 |
98 |
99 | ** Attribution of content - data.gov.uk
100 | {% endtrans %}
101 |
--------------------------------------------------------------------------------
/deploy/roles/db/templates/postgresql-9.3.conf.j2:
--------------------------------------------------------------------------------
1 | # -----------------------------
2 | # PostgreSQL configuration file
3 | # -----------------------------
4 | #
5 | # This file consists of lines of the form:
6 | #
7 | # name = value
8 | #
9 | # (The "=" is optional.) Whitespace may be used. Comments are introduced with
10 | # "#" anywhere on a line. The complete list of parameter names and allowed
11 | # values can be found in the PostgreSQL documentation.
12 | #
13 | # The commented-out settings shown in this file represent the default values.
14 | # Re-commenting a setting is NOT sufficient to revert it to the default value;
15 | # you need to reload the server.
16 | #
17 | # This file is read on server startup and when the server receives a SIGHUP
18 | # signal. If you edit the file on a running system, you have to SIGHUP the
19 | # server for the changes to take effect, or use "pg_ctl reload". Some
20 | # parameters, which are marked below, require a server shutdown and restart to
21 | # take effect.
22 | #
23 | # Any parameter can also be given as a command-line option to the server, e.g.,
24 | # "postgres -c log_connections=on". Some parameters can be changed at run time
25 | # with the "SET" SQL command.
26 | #
27 | # Memory units: kB = kilobytes Time units: ms = milliseconds
28 | # MB = megabytes s = seconds
29 | # GB = gigabytes min = minutes
30 | # h = hours
31 | # d = days
32 |
33 |
34 | #------------------------------------------------------------------------------
35 | # FILE LOCATIONS
36 | #------------------------------------------------------------------------------
37 |
38 | # The default values of these variables are driven from the -D command-line
39 | # option or PGDATA environment variable, represented here as ConfigDir.
40 |
41 | data_directory = '/var/lib/postgresql/9.3/main' # use data in another directory
42 | # (change requires restart)
43 | hba_file = '/etc/postgresql/9.3/main/pg_hba.conf' # host-based authentication file
44 | # (change requires restart)
45 | ident_file = '/etc/postgresql/9.3/main/pg_ident.conf' # ident configuration file
46 | # (change requires restart)
47 |
48 | # If external_pid_file is not explicitly set, no extra PID file is written.
49 | external_pid_file = '/var/run/postgresql/9.3-main.pid' # write an extra PID file
50 | # (change requires restart)
51 |
52 |
53 | #------------------------------------------------------------------------------
54 | # CONNECTIONS AND AUTHENTICATION
55 | #------------------------------------------------------------------------------
56 |
57 | # - Connection Settings -
58 |
59 | #listen_addresses = 'localhost' # what IP address(es) to listen on;
60 | listen_addresses = '{{ pg_listen_addresses }}'
61 | # comma-separated list of addresses;
62 | # defaults to 'localhost'; use '*' for all
63 | # (change requires restart)
64 | port = 5432 # (change requires restart)
65 | max_connections = 100 # (change requires restart)
66 | # Note: Increasing max_connections costs ~400 bytes of shared memory per
67 | # connection slot, plus lock space (see max_locks_per_transaction).
68 | #superuser_reserved_connections = 3 # (change requires restart)
69 | unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories
70 | # (change requires restart)
71 | #unix_socket_group = '' # (change requires restart)
72 | #unix_socket_permissions = 0777 # begin with 0 to use octal notation
73 | # (change requires restart)
74 | #bonjour = off # advertise server via Bonjour
75 | # (change requires restart)
76 | #bonjour_name = '' # defaults to the computer name
77 | # (change requires restart)
78 |
79 | # - Security and Authentication -
80 |
81 | #authentication_timeout = 1min # 1s-600s
82 | ssl = true # (change requires restart)
83 | #ssl_ciphers = 'DEFAULT:!LOW:!EXP:!MD5:@STRENGTH' # allowed SSL ciphers
84 | ssl_ciphers = '{{ pg_tls_cipher_suite }}' # allowed SSL ciphers
85 | # (change requires restart)
86 | #ssl_renegotiation_limit = 512MB # amount of data between renegotiations
87 | ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' # (change requires restart)
88 | ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' # (change requires restart)
89 | #ssl_ca_file = '' # (change requires restart)
90 | #ssl_crl_file = '' # (change requires restart)
91 | #password_encryption = on
92 | #db_user_namespace = off
93 |
94 | # Kerberos and GSSAPI
95 | #krb_server_keyfile = ''
96 | #krb_srvname = 'postgres' # (Kerberos only)
97 | #krb_caseins_users = off
98 |
99 | # - TCP Keepalives -
100 | # see "man 7 tcp" for details
101 |
102 | #tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds;
103 | # 0 selects the system default
104 | #tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds;
105 | # 0 selects the system default
106 | #tcp_keepalives_count = 0 # TCP_KEEPCNT;
107 | # 0 selects the system default
108 |
109 |
110 | #------------------------------------------------------------------------------
111 | # RESOURCE USAGE (except WAL)
112 | #------------------------------------------------------------------------------
113 |
114 | # - Memory -
115 |
116 | shared_buffers = 128MB # min 128kB
117 | # (change requires restart)
118 | #temp_buffers = 8MB # min 800kB
119 | #max_prepared_transactions = 0 # zero disables the feature
120 | # (change requires restart)
121 | # Note: Increasing max_prepared_transactions costs ~600 bytes of shared memory
122 | # per transaction slot, plus lock space (see max_locks_per_transaction).
123 | # It is not advisable to set max_prepared_transactions nonzero unless you
124 | # actively intend to use prepared transactions.
125 | #work_mem = 1MB # min 64kB
126 | #maintenance_work_mem = 16MB # min 1MB
127 | #max_stack_depth = 2MB # min 100kB
128 |
129 | # - Disk -
130 |
131 | #temp_file_limit = -1 # limits per-session temp file space
132 | # in kB, or -1 for no limit
133 |
134 | # - Kernel Resource Usage -
135 |
136 | #max_files_per_process = 1000 # min 25
137 | # (change requires restart)
138 | #shared_preload_libraries = '' # (change requires restart)
139 |
140 | # - Cost-Based Vacuum Delay -
141 |
142 | #vacuum_cost_delay = 0 # 0-100 milliseconds
143 | #vacuum_cost_page_hit = 1 # 0-10000 credits
144 | #vacuum_cost_page_miss = 10 # 0-10000 credits
145 | #vacuum_cost_page_dirty = 20 # 0-10000 credits
146 | #vacuum_cost_limit = 200 # 1-10000 credits
147 |
148 | # - Background Writer -
149 |
150 | #bgwriter_delay = 200ms # 10-10000ms between rounds
151 | #bgwriter_lru_maxpages = 100 # 0-1000 max buffers written/round
152 | #bgwriter_lru_multiplier = 2.0 # 0-10.0 multipler on buffers scanned/round
153 |
154 | # - Asynchronous Behavior -
155 |
156 | #effective_io_concurrency = 1 # 1-1000; 0 disables prefetching
157 |
158 |
159 | #------------------------------------------------------------------------------
160 | # WRITE AHEAD LOG
161 | #------------------------------------------------------------------------------
162 |
163 | # - Settings -
164 |
165 | #wal_level = minimal # minimal, archive, or hot_standby
166 | # (change requires restart)
167 | #fsync = on # turns forced synchronization on or off
168 | #synchronous_commit = on # synchronization level;
169 | # off, local, remote_write, or on
170 | #wal_sync_method = fsync # the default is the first option
171 | # supported by the operating system:
172 | # open_datasync
173 | # fdatasync (default on Linux)
174 | # fsync
175 | # fsync_writethrough
176 | # open_sync
177 | #full_page_writes = on # recover from partial page writes
178 | #wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers
179 | # (change requires restart)
180 | #wal_writer_delay = 200ms # 1-10000 milliseconds
181 |
182 | #commit_delay = 0 # range 0-100000, in microseconds
183 | #commit_siblings = 5 # range 1-1000
184 |
185 | # - Checkpoints -
186 |
187 | #checkpoint_segments = 3 # in logfile segments, min 1, 16MB each
188 | #checkpoint_timeout = 5min # range 30s-1h
189 | #checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0
190 | #checkpoint_warning = 30s # 0 disables
191 |
192 | # - Archiving -
193 |
194 | #archive_mode = off # allows archiving to be done
195 | # (change requires restart)
196 | #archive_command = '' # command to use to archive a logfile segment
197 | # placeholders: %p = path of file to archive
198 | # %f = file name only
199 | # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
200 | #archive_timeout = 0 # force a logfile segment switch after this
201 | # number of seconds; 0 disables
202 |
203 |
204 | #------------------------------------------------------------------------------
205 | # REPLICATION
206 | #------------------------------------------------------------------------------
207 |
208 | # - Sending Server(s) -
209 |
210 | # Set these on the master and on any standby that will send replication data.
211 |
212 | #max_wal_senders = 0 # max number of walsender processes
213 | # (change requires restart)
214 | #wal_keep_segments = 0 # in logfile segments, 16MB each; 0 disables
215 | #wal_sender_timeout = 60s # in milliseconds; 0 disables
216 |
217 | # - Master Server -
218 |
219 | # These settings are ignored on a standby server.
220 |
221 | #synchronous_standby_names = '' # standby servers that provide sync rep
222 | # comma-separated list of application_name
223 | # from standby(s); '*' = all
224 | #vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed
225 |
226 | # - Standby Servers -
227 |
228 | # These settings are ignored on a master server.
229 |
230 | #hot_standby = off # "on" allows queries during recovery
231 | # (change requires restart)
232 | #max_standby_archive_delay = 30s # max delay before canceling queries
233 | # when reading WAL from archive;
234 | # -1 allows indefinite delay
235 | #max_standby_streaming_delay = 30s # max delay before canceling queries
236 | # when reading streaming WAL;
237 | # -1 allows indefinite delay
238 | #wal_receiver_status_interval = 10s # send replies at least this often
239 | # 0 disables
240 | #hot_standby_feedback = off # send info from standby to prevent
241 | # query conflicts
242 | #wal_receiver_timeout = 60s # time that receiver waits for
243 | # communication from master
244 | # in milliseconds; 0 disables
245 |
246 |
247 | #------------------------------------------------------------------------------
248 | # QUERY TUNING
249 | #------------------------------------------------------------------------------
250 |
251 | # - Planner Method Configuration -
252 |
253 | #enable_bitmapscan = on
254 | #enable_hashagg = on
255 | #enable_hashjoin = on
256 | #enable_indexscan = on
257 | #enable_indexonlyscan = on
258 | #enable_material = on
259 | #enable_mergejoin = on
260 | #enable_nestloop = on
261 | #enable_seqscan = on
262 | #enable_sort = on
263 | #enable_tidscan = on
264 |
265 | # - Planner Cost Constants -
266 |
267 | #seq_page_cost = 1.0 # measured on an arbitrary scale
268 | #random_page_cost = 4.0 # same scale as above
269 | #cpu_tuple_cost = 0.01 # same scale as above
270 | #cpu_index_tuple_cost = 0.005 # same scale as above
271 | #cpu_operator_cost = 0.0025 # same scale as above
272 | #effective_cache_size = 128MB
273 |
274 | # - Genetic Query Optimizer -
275 |
276 | #geqo = on
277 | #geqo_threshold = 12
278 | #geqo_effort = 5 # range 1-10
279 | #geqo_pool_size = 0 # selects default based on effort
280 | #geqo_generations = 0 # selects default based on effort
281 | #geqo_selection_bias = 2.0 # range 1.5-2.0
282 | #geqo_seed = 0.0 # range 0.0-1.0
283 |
284 | # - Other Planner Options -
285 |
286 | #default_statistics_target = 100 # range 1-10000
287 | #constraint_exclusion = partition # on, off, or partition
288 | #cursor_tuple_fraction = 0.1 # range 0.0-1.0
289 | #from_collapse_limit = 8
290 | #join_collapse_limit = 8 # 1 disables collapsing of explicit
291 | # JOIN clauses
292 |
293 |
294 | #------------------------------------------------------------------------------
295 | # ERROR REPORTING AND LOGGING
296 | #------------------------------------------------------------------------------
297 |
298 | # - Where to Log -
299 |
300 | #log_destination = 'stderr' # Valid values are combinations of
301 | # stderr, csvlog, syslog, and eventlog,
302 | # depending on platform. csvlog
303 | # requires logging_collector to be on.
304 |
305 | # This is used when logging to stderr:
306 | #logging_collector = off # Enable capturing of stderr and csvlog
307 | # into log files. Required to be on for
308 | # csvlogs.
309 | # (change requires restart)
310 |
311 | # These are only used if logging_collector is on:
312 | #log_directory = 'pg_log' # directory where log files are written,
313 | # can be absolute or relative to PGDATA
314 | #log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern,
315 | # can include strftime() escapes
316 | #log_file_mode = 0600 # creation mode for log files,
317 | # begin with 0 to use octal notation
318 | #log_truncate_on_rotation = off # If on, an existing log file with the
319 | # same name as the new log file will be
320 | # truncated rather than appended to.
321 | # But such truncation only occurs on
322 | # time-driven rotation, not on restarts
323 | # or size-driven rotation. Default is
324 | # off, meaning append to existing files
325 | # in all cases.
326 | #log_rotation_age = 1d # Automatic rotation of logfiles will
327 | # happen after that time. 0 disables.
328 | #log_rotation_size = 10MB # Automatic rotation of logfiles will
329 | # happen after that much log output.
330 | # 0 disables.
331 |
332 | # These are relevant when logging to syslog:
333 | #syslog_facility = 'LOCAL0'
334 | #syslog_ident = 'postgres'
335 |
336 | # This is only relevant when logging to eventlog (win32):
337 | #event_source = 'PostgreSQL'
338 |
339 | # - When to Log -
340 |
341 | #client_min_messages = notice # values in order of decreasing detail:
342 | # debug5
343 | # debug4
344 | # debug3
345 | # debug2
346 | # debug1
347 | # log
348 | # notice
349 | # warning
350 | # error
351 |
352 | #log_min_messages = warning # values in order of decreasing detail:
353 | # debug5
354 | # debug4
355 | # debug3
356 | # debug2
357 | # debug1
358 | # info
359 | # notice
360 | # warning
361 | # error
362 | # log
363 | # fatal
364 | # panic
365 |
366 | #log_min_error_statement = error # values in order of decreasing detail:
367 | # debug5
368 | # debug4
369 | # debug3
370 | # debug2
371 | # debug1
372 | # info
373 | # notice
374 | # warning
375 | # error
376 | # log
377 | # fatal
378 | # panic (effectively off)
379 |
380 | #log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements
381 | # and their durations, > 0 logs only
382 | # statements running at least this number
383 | # of milliseconds
384 |
385 |
386 | # - What to Log -
387 |
388 | #debug_print_parse = off
389 | #debug_print_rewritten = off
390 | #debug_print_plan = off
391 | #debug_pretty_print = on
392 | #log_checkpoints = off
393 | #log_connections = off
394 | #log_disconnections = off
395 | #log_duration = off
396 | #log_error_verbosity = default # terse, default, or verbose messages
397 | #log_hostname = off
398 | log_line_prefix = '%t ' # special values:
399 | # %a = application name
400 | # %u = user name
401 | # %d = database name
402 | # %r = remote host and port
403 | # %h = remote host
404 | # %p = process ID
405 | # %t = timestamp without milliseconds
406 | # %m = timestamp with milliseconds
407 | # %i = command tag
408 | # %e = SQL state
409 | # %c = session ID
410 | # %l = session line number
411 | # %s = session start timestamp
412 | # %v = virtual transaction ID
413 | # %x = transaction ID (0 if none)
414 | # %q = stop here in non-session
415 | # processes
416 | # %% = '%'
417 | # e.g. '<%u%%%d> '
418 | #log_lock_waits = off # log lock waits >= deadlock_timeout
419 | #log_statement = 'none' # none, ddl, mod, all
420 | #log_temp_files = -1 # log temporary files equal or larger
421 | # than the specified size in kilobytes;
422 | # -1 disables, 0 logs all temp files
423 | log_timezone = 'localtime'
424 |
425 |
426 | #------------------------------------------------------------------------------
427 | # RUNTIME STATISTICS
428 | #------------------------------------------------------------------------------
429 |
430 | # - Query/Index Statistics Collector -
431 |
432 | #track_activities = on
433 | #track_counts = on
434 | #track_io_timing = off
435 | #track_functions = none # none, pl, all
436 | #track_activity_query_size = 1024 # (change requires restart)
437 | #update_process_title = on
438 | #stats_temp_directory = 'pg_stat_tmp'
439 |
440 |
441 | # - Statistics Monitoring -
442 |
443 | #log_parser_stats = off
444 | #log_planner_stats = off
445 | #log_executor_stats = off
446 | #log_statement_stats = off
447 |
448 |
449 | #------------------------------------------------------------------------------
450 | # AUTOVACUUM PARAMETERS
451 | #------------------------------------------------------------------------------
452 |
453 | #autovacuum = on # Enable autovacuum subprocess? 'on'
454 | # requires track_counts to also be on.
455 | #log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and
456 | # their durations, > 0 logs only
457 | # actions running at least this number
458 | # of milliseconds.
459 | #autovacuum_max_workers = 3 # max number of autovacuum subprocesses
460 | # (change requires restart)
461 | #autovacuum_naptime = 1min # time between autovacuum runs
462 | #autovacuum_vacuum_threshold = 50 # min number of row updates before
463 | # vacuum
464 | #autovacuum_analyze_threshold = 50 # min number of row updates before
465 | # analyze
466 | #autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum
467 | #autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze
468 | #autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum
469 | # (change requires restart)
470 | #autovacuum_multixact_freeze_max_age = 400000000 # maximum Multixact age
471 | # before forced vacuum
472 | # (change requires restart)
473 | #autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for
474 | # autovacuum, in milliseconds;
475 | # -1 means use vacuum_cost_delay
476 | #autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for
477 | # autovacuum, -1 means use
478 | # vacuum_cost_limit
479 |
480 |
481 | #------------------------------------------------------------------------------
482 | # CLIENT CONNECTION DEFAULTS
483 | #------------------------------------------------------------------------------
484 |
485 | # - Statement Behavior -
486 |
487 | #search_path = '"$user",public' # schema names
488 | #default_tablespace = '' # a tablespace name, '' uses the default
489 | #temp_tablespaces = '' # a list of tablespace names, '' uses
490 | # only default tablespace
491 | #check_function_bodies = on
492 | #default_transaction_isolation = 'read committed'
493 | #default_transaction_read_only = off
494 | #default_transaction_deferrable = off
495 | #session_replication_role = 'origin'
496 | #statement_timeout = 0 # in milliseconds, 0 is disabled
497 | #lock_timeout = 0 # in milliseconds, 0 is disabled
498 | #vacuum_freeze_min_age = 50000000
499 | #vacuum_freeze_table_age = 150000000
500 | #vacuum_multixact_freeze_min_age = 5000000
501 | #vacuum_multixact_freeze_table_age = 150000000
502 | #bytea_output = 'hex' # hex, escape
503 | #xmlbinary = 'base64'
504 | #xmloption = 'content'
505 |
506 | # - Locale and Formatting -
507 |
508 | datestyle = 'iso, mdy'
509 | #intervalstyle = 'postgres'
510 | timezone = 'localtime'
511 | #timezone_abbreviations = 'Default' # Select the set of available time zone
512 | # abbreviations. Currently, there are
513 | # Default
514 | # Australia
515 | # India
516 | # You can create your own file in
517 | # share/timezonesets/.
518 | #extra_float_digits = 0 # min -15, max 3
519 | #client_encoding = sql_ascii # actually, defaults to database
520 | # encoding
521 |
522 | # These settings are initialized by initdb, but they can be changed.
523 | lc_messages = 'en_US.UTF-8' # locale for system error message
524 | # strings
525 | lc_monetary = 'en_US.UTF-8' # locale for monetary formatting
526 | lc_numeric = 'en_US.UTF-8' # locale for number formatting
527 | lc_time = 'en_US.UTF-8' # locale for time formatting
528 |
529 | # default configuration for text search
530 | default_text_search_config = 'pg_catalog.english'
531 |
532 | # - Other Defaults -
533 |
534 | #dynamic_library_path = '$libdir'
535 | #local_preload_libraries = ''
536 |
537 |
538 | #------------------------------------------------------------------------------
539 | # LOCK MANAGEMENT
540 | #------------------------------------------------------------------------------
541 |
542 | #deadlock_timeout = 1s
543 | #max_locks_per_transaction = 64 # min 10
544 | # (change requires restart)
545 | # Note: Each lock table slot uses ~270 bytes of shared memory, and there are
546 | # max_locks_per_transaction * (max_connections + max_prepared_transactions)
547 | # lock table slots.
548 | #max_pred_locks_per_transaction = 64 # min 10
549 | # (change requires restart)
550 |
551 |
552 | #------------------------------------------------------------------------------
553 | # VERSION/PLATFORM COMPATIBILITY
554 | #------------------------------------------------------------------------------
555 |
556 | # - Previous PostgreSQL Versions -
557 |
558 | #array_nulls = on
559 | #backslash_quote = safe_encoding # on, off, or safe_encoding
560 | #default_with_oids = off
561 | #escape_string_warning = on
562 | #lo_compat_privileges = off
563 | #quote_all_identifiers = off
564 | #sql_inheritance = on
565 | #standard_conforming_strings = on
566 | #synchronize_seqscans = on
567 |
568 | # - Other Platforms and Clients -
569 |
570 | #transform_null_equals = off
571 |
572 |
573 | #------------------------------------------------------------------------------
574 | # ERROR HANDLING
575 | #------------------------------------------------------------------------------
576 |
577 | #exit_on_error = off # terminate session on any error?
578 | #restart_after_crash = on # reinitialize after backend crash?
579 |
580 |
581 | #------------------------------------------------------------------------------
582 | # CONFIG FILE INCLUDES
583 | #------------------------------------------------------------------------------
584 |
585 | # These options allow settings to be loaded from files other than the
586 | # default postgresql.conf.
587 |
588 | #include_dir = 'conf.d' # include files ending in '.conf' from
589 | # directory 'conf.d'
590 | #include_if_exists = 'exists.conf' # include file only if it exists
591 | #include = 'special.conf' # include file
592 |
593 |
594 | #------------------------------------------------------------------------------
595 | # CUSTOMIZED OPTIONS
596 | #------------------------------------------------------------------------------
597 |
598 | # Add settings for extensions here
599 |
--------------------------------------------------------------------------------
/ckanext/openafrica/assets/css/bootstrap-responsive.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap Responsive v2.3.2
3 | *
4 | * Copyright 2013 Twitter, Inc
5 | * Licensed under the Apache License v2.0
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Designed and built with all the love in the world by @mdo and @fat.
9 | */
10 | .clearfix {
11 | *zoom: 1;
12 | }
13 | .clearfix:before,
14 | .clearfix:after {
15 | display: table;
16 | line-height: 0;
17 | content: "";
18 | }
19 | .clearfix:after {
20 | clear: both;
21 | }
22 | .hide-text {
23 | font: 0/0 a;
24 | color: transparent;
25 | text-shadow: none;
26 | background-color: transparent;
27 | border: 0;
28 | }
29 | .input-block-level {
30 | display: block;
31 | width: 100%;
32 | min-height: 30px;
33 | -webkit-box-sizing: border-box;
34 | -moz-box-sizing: border-box;
35 | box-sizing: border-box;
36 | }
37 | @-ms-viewport {
38 | width: device-width;
39 | }
40 | .hidden {
41 | display: none;
42 | visibility: hidden;
43 | }
44 | .visible-phone {
45 | display: none !important;
46 | }
47 | .visible-tablet {
48 | display: none !important;
49 | }
50 | .hidden-desktop {
51 | display: none !important;
52 | }
53 | .visible-desktop {
54 | display: inherit !important;
55 | }
56 | @media (min-width: 768px) and (max-width: 979px) {
57 | .hidden-desktop {
58 | display: inherit !important;
59 | }
60 | .visible-desktop {
61 | display: none !important;
62 | }
63 | .visible-tablet {
64 | display: inherit !important;
65 | }
66 | .hidden-tablet {
67 | display: none !important;
68 | }
69 | }
70 | @media (max-width: 767px) {
71 | .hidden-desktop {
72 | display: inherit !important;
73 | }
74 | .visible-desktop {
75 | display: none !important;
76 | }
77 | .visible-phone {
78 | display: inherit !important;
79 | }
80 | .hidden-phone {
81 | display: none !important;
82 | }
83 | }
84 | .visible-print {
85 | display: none !important;
86 | }
87 | @media print {
88 | .visible-print {
89 | display: inherit !important;
90 | }
91 | .hidden-print {
92 | display: none !important;
93 | }
94 | }
95 | @media (min-width: 1200px) {
96 | .row {
97 | margin-left: -30px;
98 | *zoom: 1;
99 | }
100 | .row:before,
101 | .row:after {
102 | display: table;
103 | line-height: 0;
104 | content: "";
105 | }
106 | .row:after {
107 | clear: both;
108 | }
109 | [class*="span"] {
110 | float: left;
111 | min-height: 1px;
112 | margin-left: 30px;
113 | }
114 | .container,
115 | .navbar-static-top .container,
116 | .navbar-fixed-top .container,
117 | .navbar-fixed-bottom .container {
118 | width: 1170px;
119 | }
120 | .span12 {
121 | width: 1170px;
122 | }
123 | .span11 {
124 | width: 1070px;
125 | }
126 | .span10 {
127 | width: 970px;
128 | }
129 | .span9 {
130 | width: 870px;
131 | }
132 | .span8 {
133 | width: 770px;
134 | }
135 | .span7 {
136 | width: 670px;
137 | }
138 | .span6 {
139 | width: 570px;
140 | }
141 | .span5 {
142 | width: 470px;
143 | }
144 | .span4 {
145 | width: 370px;
146 | }
147 | .span3 {
148 | width: 270px;
149 | }
150 | .span2 {
151 | width: 170px;
152 | }
153 | .span1 {
154 | width: 70px;
155 | }
156 | .offset12 {
157 | margin-left: 1230px;
158 | }
159 | .offset11 {
160 | margin-left: 1130px;
161 | }
162 | .offset10 {
163 | margin-left: 1030px;
164 | }
165 | .offset9 {
166 | margin-left: 930px;
167 | }
168 | .offset8 {
169 | margin-left: 830px;
170 | }
171 | .offset7 {
172 | margin-left: 730px;
173 | }
174 | .offset6 {
175 | margin-left: 630px;
176 | }
177 | .offset5 {
178 | margin-left: 530px;
179 | }
180 | .offset4 {
181 | margin-left: 430px;
182 | }
183 | .offset3 {
184 | margin-left: 330px;
185 | }
186 | .offset2 {
187 | margin-left: 230px;
188 | }
189 | .offset1 {
190 | margin-left: 130px;
191 | }
192 | .row-fluid {
193 | width: 100%;
194 | *zoom: 1;
195 | }
196 | .row-fluid:before,
197 | .row-fluid:after {
198 | display: table;
199 | line-height: 0;
200 | content: "";
201 | }
202 | .row-fluid:after {
203 | clear: both;
204 | }
205 | .row-fluid [class*="span"] {
206 | display: block;
207 | float: left;
208 | width: 100%;
209 | min-height: 30px;
210 | margin-left: 2.564102564102564%;
211 | *margin-left: 2.5109110747408616%;
212 | -webkit-box-sizing: border-box;
213 | -moz-box-sizing: border-box;
214 | box-sizing: border-box;
215 | }
216 | .row-fluid [class*="span"]:first-child {
217 | margin-left: 0;
218 | }
219 | .row-fluid .controls-row [class*="span"] + [class*="span"] {
220 | margin-left: 2.564102564102564%;
221 | }
222 | .row-fluid .span12 {
223 | width: 100%;
224 | *width: 99.94680851063829%;
225 | }
226 | .row-fluid .span11 {
227 | width: 91.45299145299145%;
228 | *width: 91.39979996362975%;
229 | }
230 | .row-fluid .span10 {
231 | width: 82.90598290598291%;
232 | *width: 82.8527914166212%;
233 | }
234 | .row-fluid .span9 {
235 | width: 74.35897435897436%;
236 | *width: 74.30578286961266%;
237 | }
238 | .row-fluid .span8 {
239 | width: 65.81196581196582%;
240 | *width: 65.75877432260411%;
241 | }
242 | .row-fluid .span7 {
243 | width: 57.26495726495726%;
244 | *width: 57.21176577559556%;
245 | }
246 | .row-fluid .span6 {
247 | width: 48.717948717948715%;
248 | *width: 48.664757228587014%;
249 | }
250 | .row-fluid .span5 {
251 | width: 40.17094017094017%;
252 | *width: 40.11774868157847%;
253 | }
254 | .row-fluid .span4 {
255 | width: 31.623931623931625%;
256 | *width: 31.570740134569924%;
257 | }
258 | .row-fluid .span3 {
259 | width: 23.076923076923077%;
260 | *width: 23.023731587561375%;
261 | }
262 | .row-fluid .span2 {
263 | width: 14.52991452991453%;
264 | *width: 14.476723040552828%;
265 | }
266 | .row-fluid .span1 {
267 | width: 5.982905982905983%;
268 | *width: 5.929714493544281%;
269 | }
270 | .row-fluid .offset12 {
271 | margin-left: 105.12820512820512%;
272 | *margin-left: 105.02182214948171%;
273 | }
274 | .row-fluid .offset12:first-child {
275 | margin-left: 102.56410256410257%;
276 | *margin-left: 102.45771958537915%;
277 | }
278 | .row-fluid .offset11 {
279 | margin-left: 96.58119658119658%;
280 | *margin-left: 96.47481360247316%;
281 | }
282 | .row-fluid .offset11:first-child {
283 | margin-left: 94.01709401709402%;
284 | *margin-left: 93.91071103837061%;
285 | }
286 | .row-fluid .offset10 {
287 | margin-left: 88.03418803418803%;
288 | *margin-left: 87.92780505546462%;
289 | }
290 | .row-fluid .offset10:first-child {
291 | margin-left: 85.47008547008548%;
292 | *margin-left: 85.36370249136206%;
293 | }
294 | .row-fluid .offset9 {
295 | margin-left: 79.48717948717949%;
296 | *margin-left: 79.38079650845607%;
297 | }
298 | .row-fluid .offset9:first-child {
299 | margin-left: 76.92307692307693%;
300 | *margin-left: 76.81669394435352%;
301 | }
302 | .row-fluid .offset8 {
303 | margin-left: 70.94017094017094%;
304 | *margin-left: 70.83378796144753%;
305 | }
306 | .row-fluid .offset8:first-child {
307 | margin-left: 68.37606837606839%;
308 | *margin-left: 68.26968539734497%;
309 | }
310 | .row-fluid .offset7 {
311 | margin-left: 62.393162393162385%;
312 | *margin-left: 62.28677941443899%;
313 | }
314 | .row-fluid .offset7:first-child {
315 | margin-left: 59.82905982905982%;
316 | *margin-left: 59.72267685033642%;
317 | }
318 | .row-fluid .offset6 {
319 | margin-left: 53.84615384615384%;
320 | *margin-left: 53.739770867430444%;
321 | }
322 | .row-fluid .offset6:first-child {
323 | margin-left: 51.28205128205128%;
324 | *margin-left: 51.175668303327875%;
325 | }
326 | .row-fluid .offset5 {
327 | margin-left: 45.299145299145295%;
328 | *margin-left: 45.1927623204219%;
329 | }
330 | .row-fluid .offset5:first-child {
331 | margin-left: 42.73504273504273%;
332 | *margin-left: 42.62865975631933%;
333 | }
334 | .row-fluid .offset4 {
335 | margin-left: 36.75213675213675%;
336 | *margin-left: 36.645753773413354%;
337 | }
338 | .row-fluid .offset4:first-child {
339 | margin-left: 34.18803418803419%;
340 | *margin-left: 34.081651209310785%;
341 | }
342 | .row-fluid .offset3 {
343 | margin-left: 28.205128205128204%;
344 | *margin-left: 28.0987452264048%;
345 | }
346 | .row-fluid .offset3:first-child {
347 | margin-left: 25.641025641025642%;
348 | *margin-left: 25.53464266230224%;
349 | }
350 | .row-fluid .offset2 {
351 | margin-left: 19.65811965811966%;
352 | *margin-left: 19.551736679396257%;
353 | }
354 | .row-fluid .offset2:first-child {
355 | margin-left: 17.094017094017094%;
356 | *margin-left: 16.98763411529369%;
357 | }
358 | .row-fluid .offset1 {
359 | margin-left: 11.11111111111111%;
360 | *margin-left: 11.004728132387708%;
361 | }
362 | .row-fluid .offset1:first-child {
363 | margin-left: 8.547008547008547%;
364 | *margin-left: 8.440625568285142%;
365 | }
366 | input,
367 | textarea,
368 | .uneditable-input {
369 | margin-left: 0;
370 | }
371 | .controls-row [class*="span"] + [class*="span"] {
372 | margin-left: 30px;
373 | }
374 | input.span12,
375 | textarea.span12,
376 | .uneditable-input.span12 {
377 | width: 1156px;
378 | }
379 | input.span11,
380 | textarea.span11,
381 | .uneditable-input.span11 {
382 | width: 1056px;
383 | }
384 | input.span10,
385 | textarea.span10,
386 | .uneditable-input.span10 {
387 | width: 956px;
388 | }
389 | input.span9,
390 | textarea.span9,
391 | .uneditable-input.span9 {
392 | width: 856px;
393 | }
394 | input.span8,
395 | textarea.span8,
396 | .uneditable-input.span8 {
397 | width: 756px;
398 | }
399 | input.span7,
400 | textarea.span7,
401 | .uneditable-input.span7 {
402 | width: 656px;
403 | }
404 | input.span6,
405 | textarea.span6,
406 | .uneditable-input.span6 {
407 | width: 556px;
408 | }
409 | input.span5,
410 | textarea.span5,
411 | .uneditable-input.span5 {
412 | width: 456px;
413 | }
414 | input.span4,
415 | textarea.span4,
416 | .uneditable-input.span4 {
417 | width: 356px;
418 | }
419 | input.span3,
420 | textarea.span3,
421 | .uneditable-input.span3 {
422 | width: 256px;
423 | }
424 | input.span2,
425 | textarea.span2,
426 | .uneditable-input.span2 {
427 | width: 156px;
428 | }
429 | input.span1,
430 | textarea.span1,
431 | .uneditable-input.span1 {
432 | width: 56px;
433 | }
434 | .thumbnails {
435 | margin-left: -30px;
436 | }
437 | .thumbnails > li {
438 | margin-left: 30px;
439 | }
440 | .row-fluid .thumbnails {
441 | margin-left: 0;
442 | }
443 | }
444 | @media (min-width: 768px) and (max-width: 979px) {
445 | .row {
446 | margin-left: -20px;
447 | *zoom: 1;
448 | }
449 | .row:before,
450 | .row:after {
451 | display: table;
452 | line-height: 0;
453 | content: "";
454 | }
455 | .row:after {
456 | clear: both;
457 | }
458 | [class*="span"] {
459 | float: left;
460 | min-height: 1px;
461 | margin-left: 20px;
462 | }
463 | .container,
464 | .navbar-static-top .container,
465 | .navbar-fixed-top .container,
466 | .navbar-fixed-bottom .container {
467 | width: 724px;
468 | }
469 | .span12 {
470 | width: 724px;
471 | }
472 | .span11 {
473 | width: 662px;
474 | }
475 | .span10 {
476 | width: 600px;
477 | }
478 | .span9 {
479 | width: 538px;
480 | }
481 | .span8 {
482 | width: 476px;
483 | }
484 | .span7 {
485 | width: 414px;
486 | }
487 | .span6 {
488 | width: 352px;
489 | }
490 | .span5 {
491 | width: 290px;
492 | }
493 | .span4 {
494 | width: 228px;
495 | }
496 | .span3 {
497 | width: 166px;
498 | }
499 | .span2 {
500 | width: 104px;
501 | }
502 | .span1 {
503 | width: 42px;
504 | }
505 | .offset12 {
506 | margin-left: 764px;
507 | }
508 | .offset11 {
509 | margin-left: 702px;
510 | }
511 | .offset10 {
512 | margin-left: 640px;
513 | }
514 | .offset9 {
515 | margin-left: 578px;
516 | }
517 | .offset8 {
518 | margin-left: 516px;
519 | }
520 | .offset7 {
521 | margin-left: 454px;
522 | }
523 | .offset6 {
524 | margin-left: 392px;
525 | }
526 | .offset5 {
527 | margin-left: 330px;
528 | }
529 | .offset4 {
530 | margin-left: 268px;
531 | }
532 | .offset3 {
533 | margin-left: 206px;
534 | }
535 | .offset2 {
536 | margin-left: 144px;
537 | }
538 | .offset1 {
539 | margin-left: 82px;
540 | }
541 | .row-fluid {
542 | width: 100%;
543 | *zoom: 1;
544 | }
545 | .row-fluid:before,
546 | .row-fluid:after {
547 | display: table;
548 | line-height: 0;
549 | content: "";
550 | }
551 | .row-fluid:after {
552 | clear: both;
553 | }
554 | .row-fluid [class*="span"] {
555 | display: block;
556 | float: left;
557 | width: 100%;
558 | min-height: 30px;
559 | margin-left: 2.7624309392265194%;
560 | *margin-left: 2.709239449864817%;
561 | -webkit-box-sizing: border-box;
562 | -moz-box-sizing: border-box;
563 | box-sizing: border-box;
564 | }
565 | .row-fluid [class*="span"]:first-child {
566 | margin-left: 0;
567 | }
568 | .row-fluid .controls-row [class*="span"] + [class*="span"] {
569 | margin-left: 2.7624309392265194%;
570 | }
571 | .row-fluid .span12 {
572 | width: 100%;
573 | *width: 99.94680851063829%;
574 | }
575 | .row-fluid .span11 {
576 | width: 91.43646408839778%;
577 | *width: 91.38327259903608%;
578 | }
579 | .row-fluid .span10 {
580 | width: 82.87292817679558%;
581 | *width: 82.81973668743387%;
582 | }
583 | .row-fluid .span9 {
584 | width: 74.30939226519337%;
585 | *width: 74.25620077583166%;
586 | }
587 | .row-fluid .span8 {
588 | width: 65.74585635359117%;
589 | *width: 65.69266486422946%;
590 | }
591 | .row-fluid .span7 {
592 | width: 57.18232044198895%;
593 | *width: 57.12912895262725%;
594 | }
595 | .row-fluid .span6 {
596 | width: 48.61878453038674%;
597 | *width: 48.56559304102504%;
598 | }
599 | .row-fluid .span5 {
600 | width: 40.05524861878453%;
601 | *width: 40.00205712942283%;
602 | }
603 | .row-fluid .span4 {
604 | width: 31.491712707182323%;
605 | *width: 31.43852121782062%;
606 | }
607 | .row-fluid .span3 {
608 | width: 22.92817679558011%;
609 | *width: 22.87498530621841%;
610 | }
611 | .row-fluid .span2 {
612 | width: 14.3646408839779%;
613 | *width: 14.311449394616199%;
614 | }
615 | .row-fluid .span1 {
616 | width: 5.801104972375691%;
617 | *width: 5.747913483013988%;
618 | }
619 | .row-fluid .offset12 {
620 | margin-left: 105.52486187845304%;
621 | *margin-left: 105.41847889972962%;
622 | }
623 | .row-fluid .offset12:first-child {
624 | margin-left: 102.76243093922652%;
625 | *margin-left: 102.6560479605031%;
626 | }
627 | .row-fluid .offset11 {
628 | margin-left: 96.96132596685082%;
629 | *margin-left: 96.8549429881274%;
630 | }
631 | .row-fluid .offset11:first-child {
632 | margin-left: 94.1988950276243%;
633 | *margin-left: 94.09251204890089%;
634 | }
635 | .row-fluid .offset10 {
636 | margin-left: 88.39779005524862%;
637 | *margin-left: 88.2914070765252%;
638 | }
639 | .row-fluid .offset10:first-child {
640 | margin-left: 85.6353591160221%;
641 | *margin-left: 85.52897613729868%;
642 | }
643 | .row-fluid .offset9 {
644 | margin-left: 79.8342541436464%;
645 | *margin-left: 79.72787116492299%;
646 | }
647 | .row-fluid .offset9:first-child {
648 | margin-left: 77.07182320441989%;
649 | *margin-left: 76.96544022569647%;
650 | }
651 | .row-fluid .offset8 {
652 | margin-left: 71.2707182320442%;
653 | *margin-left: 71.16433525332079%;
654 | }
655 | .row-fluid .offset8:first-child {
656 | margin-left: 68.50828729281768%;
657 | *margin-left: 68.40190431409427%;
658 | }
659 | .row-fluid .offset7 {
660 | margin-left: 62.70718232044199%;
661 | *margin-left: 62.600799341718584%;
662 | }
663 | .row-fluid .offset7:first-child {
664 | margin-left: 59.94475138121547%;
665 | *margin-left: 59.838368402492065%;
666 | }
667 | .row-fluid .offset6 {
668 | margin-left: 54.14364640883978%;
669 | *margin-left: 54.037263430116376%;
670 | }
671 | .row-fluid .offset6:first-child {
672 | margin-left: 51.38121546961326%;
673 | *margin-left: 51.27483249088986%;
674 | }
675 | .row-fluid .offset5 {
676 | margin-left: 45.58011049723757%;
677 | *margin-left: 45.47372751851417%;
678 | }
679 | .row-fluid .offset5:first-child {
680 | margin-left: 42.81767955801105%;
681 | *margin-left: 42.71129657928765%;
682 | }
683 | .row-fluid .offset4 {
684 | margin-left: 37.01657458563536%;
685 | *margin-left: 36.91019160691196%;
686 | }
687 | .row-fluid .offset4:first-child {
688 | margin-left: 34.25414364640884%;
689 | *margin-left: 34.14776066768544%;
690 | }
691 | .row-fluid .offset3 {
692 | margin-left: 28.45303867403315%;
693 | *margin-left: 28.346655695309746%;
694 | }
695 | .row-fluid .offset3:first-child {
696 | margin-left: 25.69060773480663%;
697 | *margin-left: 25.584224756083227%;
698 | }
699 | .row-fluid .offset2 {
700 | margin-left: 19.88950276243094%;
701 | *margin-left: 19.783119783707537%;
702 | }
703 | .row-fluid .offset2:first-child {
704 | margin-left: 17.12707182320442%;
705 | *margin-left: 17.02068884448102%;
706 | }
707 | .row-fluid .offset1 {
708 | margin-left: 11.32596685082873%;
709 | *margin-left: 11.219583872105325%;
710 | }
711 | .row-fluid .offset1:first-child {
712 | margin-left: 8.56353591160221%;
713 | *margin-left: 8.457152932878806%;
714 | }
715 | input,
716 | textarea,
717 | .uneditable-input {
718 | margin-left: 0;
719 | }
720 | .controls-row [class*="span"] + [class*="span"] {
721 | margin-left: 20px;
722 | }
723 | input.span12,
724 | textarea.span12,
725 | .uneditable-input.span12 {
726 | width: 710px;
727 | }
728 | input.span11,
729 | textarea.span11,
730 | .uneditable-input.span11 {
731 | width: 648px;
732 | }
733 | input.span10,
734 | textarea.span10,
735 | .uneditable-input.span10 {
736 | width: 586px;
737 | }
738 | input.span9,
739 | textarea.span9,
740 | .uneditable-input.span9 {
741 | width: 524px;
742 | }
743 | input.span8,
744 | textarea.span8,
745 | .uneditable-input.span8 {
746 | width: 462px;
747 | }
748 | input.span7,
749 | textarea.span7,
750 | .uneditable-input.span7 {
751 | width: 400px;
752 | }
753 | input.span6,
754 | textarea.span6,
755 | .uneditable-input.span6 {
756 | width: 338px;
757 | }
758 | input.span5,
759 | textarea.span5,
760 | .uneditable-input.span5 {
761 | width: 276px;
762 | }
763 | input.span4,
764 | textarea.span4,
765 | .uneditable-input.span4 {
766 | width: 214px;
767 | }
768 | input.span3,
769 | textarea.span3,
770 | .uneditable-input.span3 {
771 | width: 152px;
772 | }
773 | input.span2,
774 | textarea.span2,
775 | .uneditable-input.span2 {
776 | width: 90px;
777 | }
778 | input.span1,
779 | textarea.span1,
780 | .uneditable-input.span1 {
781 | width: 28px;
782 | }
783 | }
784 | @media (max-width: 767px) {
785 | body {
786 | padding-right: 20px;
787 | padding-left: 20px;
788 | }
789 | .navbar-fixed-top,
790 | .navbar-fixed-bottom,
791 | .navbar-static-top {
792 | margin-right: -20px;
793 | margin-left: -20px;
794 | }
795 | .container-fluid {
796 | padding: 0;
797 | }
798 | .dl-horizontal dt {
799 | float: none;
800 | width: auto;
801 | clear: none;
802 | text-align: left;
803 | }
804 | .dl-horizontal dd {
805 | margin-left: 0;
806 | }
807 | .container {
808 | width: auto;
809 | }
810 | .row-fluid {
811 | width: 100%;
812 | }
813 | .row,
814 | .thumbnails {
815 | margin-left: 0;
816 | }
817 | .thumbnails > li {
818 | float: none;
819 | margin-left: 0;
820 | }
821 | [class*="span"],
822 | .uneditable-input[class*="span"],
823 | .row-fluid [class*="span"] {
824 | display: block;
825 | float: none;
826 | width: 100%;
827 | margin-left: 0;
828 | -webkit-box-sizing: border-box;
829 | -moz-box-sizing: border-box;
830 | box-sizing: border-box;
831 | }
832 | .span12,
833 | .row-fluid .span12 {
834 | width: 100%;
835 | -webkit-box-sizing: border-box;
836 | -moz-box-sizing: border-box;
837 | box-sizing: border-box;
838 | }
839 | .row-fluid [class*="offset"]:first-child {
840 | margin-left: 0;
841 | }
842 | .input-large,
843 | .input-xlarge,
844 | .input-xxlarge,
845 | input[class*="span"],
846 | select[class*="span"],
847 | textarea[class*="span"],
848 | .uneditable-input {
849 | display: block;
850 | width: 100%;
851 | min-height: 30px;
852 | -webkit-box-sizing: border-box;
853 | -moz-box-sizing: border-box;
854 | box-sizing: border-box;
855 | }
856 | .input-prepend input,
857 | .input-append input,
858 | .input-prepend input[class*="span"],
859 | .input-append input[class*="span"] {
860 | display: inline-block;
861 | width: auto;
862 | }
863 | .controls-row [class*="span"] + [class*="span"] {
864 | margin-left: 0;
865 | }
866 | .modal {
867 | position: fixed;
868 | top: 20px;
869 | right: 20px;
870 | left: 20px;
871 | width: auto;
872 | margin: 0;
873 | }
874 | .modal.fade {
875 | top: -100px;
876 | }
877 | .modal.fade.in {
878 | top: 20px;
879 | }
880 | }
881 | @media (max-width: 480px) {
882 | .nav-collapse {
883 | -webkit-transform: translate3d(0, 0, 0);
884 | }
885 | .page-header h1 small {
886 | display: block;
887 | line-height: 20px;
888 | }
889 | input[type="checkbox"],
890 | input[type="radio"] {
891 | border: 1px solid #ccc;
892 | }
893 | .form-horizontal .control-label {
894 | float: none;
895 | width: auto;
896 | padding-top: 0;
897 | text-align: left;
898 | }
899 | .form-horizontal .controls {
900 | margin-left: 0;
901 | }
902 | .form-horizontal .control-list {
903 | padding-top: 0;
904 | }
905 | .form-horizontal .form-actions {
906 | padding-right: 10px;
907 | padding-left: 10px;
908 | }
909 | .media .pull-left,
910 | .media .pull-right {
911 | display: block;
912 | float: none;
913 | margin-bottom: 10px;
914 | }
915 | .media-object {
916 | margin-right: 0;
917 | margin-left: 0;
918 | }
919 | .modal {
920 | top: 10px;
921 | right: 10px;
922 | left: 10px;
923 | }
924 | .modal-header .close {
925 | padding: 10px;
926 | margin: -10px;
927 | }
928 | .carousel-caption {
929 | position: static;
930 | }
931 | }
932 | @media (max-width: 979px) {
933 | body {
934 | padding-top: 0;
935 | }
936 | .navbar-fixed-top,
937 | .navbar-fixed-bottom {
938 | position: static;
939 | }
940 | .navbar-fixed-top {
941 | margin-bottom: 20px;
942 | }
943 | .navbar-fixed-bottom {
944 | margin-top: 20px;
945 | }
946 | .navbar-fixed-top .navbar-inner,
947 | .navbar-fixed-bottom .navbar-inner {
948 | padding: 5px;
949 | }
950 | .navbar .container {
951 | width: auto;
952 | padding: 0;
953 | }
954 | .navbar .brand {
955 | padding-right: 10px;
956 | padding-left: 10px;
957 | margin: 0 0 0 -5px;
958 | }
959 | .nav-collapse {
960 | clear: both;
961 | }
962 | .nav-collapse .nav {
963 | float: none;
964 | margin: 0 0 10px;
965 | }
966 | .nav-collapse .nav > li {
967 | float: none;
968 | }
969 | .nav-collapse .nav > li > a {
970 | margin-bottom: 2px;
971 | }
972 | .nav-collapse .nav > .divider-vertical {
973 | display: none;
974 | }
975 | .nav-collapse .nav .nav-header {
976 | color: #777;
977 | text-shadow: none;
978 | }
979 | .nav-collapse .nav > li > a,
980 | .nav-collapse .dropdown-menu a {
981 | padding: 9px 15px;
982 | font-weight: bold;
983 | color: #777;
984 | -webkit-border-radius: 3px;
985 | -moz-border-radius: 3px;
986 | border-radius: 3px;
987 | }
988 | .nav-collapse .btn {
989 | padding: 4px 10px 4px;
990 | font-weight: normal;
991 | -webkit-border-radius: 4px;
992 | -moz-border-radius: 4px;
993 | border-radius: 4px;
994 | }
995 | .nav-collapse .dropdown-menu li + li a {
996 | margin-bottom: 2px;
997 | }
998 | .nav-collapse .nav > li > a:hover,
999 | .nav-collapse .nav > li > a:focus,
1000 | .nav-collapse .dropdown-menu a:hover,
1001 | .nav-collapse .dropdown-menu a:focus {
1002 | background-color: #f2f2f2;
1003 | }
1004 | .navbar-inverse .nav-collapse .nav > li > a,
1005 | .navbar-inverse .nav-collapse .dropdown-menu a {
1006 | color: #999;
1007 | }
1008 | .navbar-inverse .nav-collapse .nav > li > a:hover,
1009 | .navbar-inverse .nav-collapse .nav > li > a:focus,
1010 | .navbar-inverse .nav-collapse .dropdown-menu a:hover,
1011 | .navbar-inverse .nav-collapse .dropdown-menu a:focus {
1012 | background-color: #111;
1013 | }
1014 | .nav-collapse.in .btn-group {
1015 | padding: 0;
1016 | margin-top: 5px;
1017 | }
1018 | .nav-collapse .dropdown-menu {
1019 | position: static;
1020 | top: auto;
1021 | left: auto;
1022 | display: none;
1023 | float: none;
1024 | max-width: none;
1025 | padding: 0;
1026 | margin: 0 15px;
1027 | background-color: transparent;
1028 | border: 0;
1029 | -webkit-border-radius: 0;
1030 | -moz-border-radius: 0;
1031 | border-radius: 0;
1032 | -webkit-box-shadow: none;
1033 | -moz-box-shadow: none;
1034 | box-shadow: none;
1035 | }
1036 | .nav-collapse .open > .dropdown-menu {
1037 | display: block;
1038 | }
1039 | .nav-collapse .dropdown-menu:before,
1040 | .nav-collapse .dropdown-menu:after {
1041 | display: none;
1042 | }
1043 | .nav-collapse .dropdown-menu .divider {
1044 | display: none;
1045 | }
1046 | .nav-collapse .nav > li > .dropdown-menu:before,
1047 | .nav-collapse .nav > li > .dropdown-menu:after {
1048 | display: none;
1049 | }
1050 | .nav-collapse .navbar-form,
1051 | .nav-collapse .navbar-search {
1052 | float: none;
1053 | padding: 10px 15px;
1054 | margin: 10px 0;
1055 | border-top: 1px solid #f2f2f2;
1056 | border-bottom: 1px solid #f2f2f2;
1057 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1),
1058 | 0 1px 0 rgba(255, 255, 255, 0.1);
1059 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1),
1060 | 0 1px 0 rgba(255, 255, 255, 0.1);
1061 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1),
1062 | 0 1px 0 rgba(255, 255, 255, 0.1);
1063 | }
1064 | .navbar-inverse .nav-collapse .navbar-form,
1065 | .navbar-inverse .nav-collapse .navbar-search {
1066 | border-top-color: #111;
1067 | border-bottom-color: #111;
1068 | }
1069 | .navbar .nav-collapse .nav.pull-right {
1070 | float: none;
1071 | margin-left: 0;
1072 | }
1073 | .nav-collapse,
1074 | .nav-collapse.collapse {
1075 | height: 0;
1076 | overflow: hidden;
1077 | }
1078 | .navbar .btn-navbar {
1079 | display: block;
1080 | }
1081 | .navbar-static .navbar-inner {
1082 | padding-right: 10px;
1083 | padding-left: 10px;
1084 | }
1085 | }
1086 | @media (min-width: 980px) {
1087 | .nav-collapse.collapse {
1088 | height: auto !important;
1089 | overflow: visible !important;
1090 | }
1091 | }
1092 |
--------------------------------------------------------------------------------