├── 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 |
    {{ _('Skip to content') }}
    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 |
    4 | 5 | 12 | 13 |
    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 | 4 |

    We will not spam or share your email with third parties

    5 |
    6 |
    7 |
    8 | 9 |
    10 |
    11 |
    12 | 13 |
    14 |
    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 | 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 | 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 | 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 |
    37 | {% block breadcrumb %} 38 | {% if self.breadcrumb_content() | trim %} 39 | 43 | {% endif %} 44 | {% endblock %} 45 |
    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 | 65 | {% endif %} 66 | {% endblock %} 67 |
    68 |
    69 |
    70 | {% block notes %} 71 | {% if notes %} 72 |
    {{ notes|urlize }}
    73 | {% else %} 74 |

    {{ _("This dataset has no description") }}

    75 | {% endif %} 76 | {% endblock %} 77 | 78 |
    79 |
    80 | {% block resources %} 81 | {% if package.resources and not hide_resources %} 82 | {% block resources_outer %} 83 |
      84 | {% block resources_inner %} 85 | {% for resource in h.dict_list_reduce(package.resources, 'format') %} 86 |
    • 87 | {{ resource }} 89 |
    • 90 | {% endfor %} 91 | {% endblock %} 92 |
    93 | {% endblock %} 94 | {% endif %} 95 | {% endblock %} 96 |
    97 |
    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 |
    37 | {% block breadcrumb %} 38 | {% if self.breadcrumb_content() | trim %} 39 | 43 | {% endif %} 44 | {% endblock %} 45 |
    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 |
    1. What is the project doing?
    2. 5 |
    3. What is the status of this site?
    4. 6 |
    5. Will personal information be at risk?
    6. 7 |
    7. What is a mashup?
    8. 8 |
    9. What is Linked Data and how does it fit into the Semantic Web?
    10. 9 |
    11. How can people submit applications and visualisations?
    12. 10 |
    13. How can people submit ideas?
    14. 11 |
    15. How can people use data.gov.uk?
    16. 12 |
    17. How were the datasets in data.gov.uk selected?
    18. 13 |
    19. Why is a particular dataset not available yet, and when will it be?
    20. 14 |
    21. Why is a particular dataset not available through an API yet, and when will it be?
    22. 15 |
    23. How can people make contact with the project?
    24. 16 |
    25. Is there a place for developers to discuss ideas, applications and using the data?
    26. 17 |
    27. Will more public data become available in the future?
    28. 18 |
    29. What are the commercial use rights if people have commercial ideas?
    30. 19 |
    31. Under what licence is the data available?
    32. 20 |
    33. Are there any “do”s and “don’t”s?
    34. 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 | --------------------------------------------------------------------------------