/cc-legal-tools-app

Legal tool (licenses, public domain dedication, etc.) management application for Creative Commons

Primary LanguagePythonMIT LicenseMIT

cc-legal-tools-app

Creative Commons (CC) Legal Tools Application. This repository contains the application that manages the license tools and public domain tools (static HTML, internationalization and localization files, etc.). It consumes and generates data in the creativecommons/cc-legal-tools-data repository.

Not the live site

This project is not intended to serve the license and deed pages directly. Though if it's deployed on a public server it could do that, performance would probably not be acceptable.

Instead, a command line tool can be used to save all the rendered HTML pages for deeds and legal code as files. Then those files are used as part of the real creativecommons.org site, just served as static files. See details farther down.

For the parent project for the entire creativecommons.org site (of which this project is a component, see creativecommons/project_creativecommons.org.

Software Versions

Both versions are specified in the Pipfile.

Setting up the Project

Data Repository

Visit Cloning a Repository on how to clone a GitHub repository.

The creativecommons/cc-legal-tools-data project repository should be cloned into a directory adjacent to this one:

PARENT_DIR
├── cc-legal-tools-app
└── cc-legal-tools-data

If it is not cloned into the default location, the Django DATA_REPOSITORY_DIR django configuration setting, or the DATA_REPOSITORY_DIR environment variable can be used to configure its location.

Docker Compose Setup

Use the following instructions to start the project with Docker compose. cc staff do not use Windows for development.

  1. Ensure the Data Repository, above, is in place
  2. Install Docker
  3. Ensure you are the top level of directory where you cloned this repository (where manage.py is)
  4. Create Django local settings file
    cp cc_legal_tools/settings/local.example.py cc_legal_tools/settings/local.py
    
  5. Build the containers
    docker compose build
    
  6. Run the containers
    docker compose up
    
    1. app (127.0.0.1:8005): this Django application
      • Any changes made to Python will be detected and rebuilt transparently as long as the development server is running.
    2. static (127.0.0.1:8006): a static web server serving creativecommons/cc-legal-tools-data/docs.
  7. Run database migrations
    docker compose exec app ./manage.py migrate
    
  8. Clear data in the database
    docker compose exec app ./manage.py clear_license_data
    
  9. Load legacy HTML in the database
    docker compose exec app ./manage.py load_html_files
    

Manual Setup

  1. Development Environment
    1. Ensure the Data Repository, above, is in place
    2. Install dependencies
      • Linux:
        sudo apt-get install python3.9 python3.9-dev python3-pip
        
        pip3 install pipenv
        
      • macOS: via Homebrew:
        brew install pipenv python@3.9
        
      • Windows: install Python and then use pip to install pipenv:
        pip install pipenv
        
    3. Install Python environment and modules via pipenv to create a virtualenv
      • Linux:
        pipenv install --dev --python /usr/bin/python3.9
        
      • macOS: via Homebrew:
        pipenv install --dev --python /usr/local/opt/python@3.9/libexec/bin/python
        
      • Windows:
        pipenv install --dev --python \User\Appdata\programs\python
        
    4. Install pre-commit hooks
    pipenv run pre-commit install
    
  2. Configure Django
    1. Create Django local settings file
    cp cc_legal_tools/settings/local.example.py cc_legal_tools/settings/local.py
    
    1. Create project database
      • Linux:
        sudo createdb -E UTF-8 cc_legal_tools
        
      • macOS:
        createdb -E UTF-8 cc_legal_tools
        
      • Windows:
        createdb -E UTF-8 cc_legal_tools
        
    2. Load database schema
    pipenv run ./manage.py migrate
    
  3. Run development server (127.0.0.1:8005)
    pipenv run ./manage.py runserver
    
    • Any changes made to Python will be detected and rebuilt transparently as long as the development server is running.

Manual Commands

NOTE: The rest of the documentation assumes Docker. If you are using a manual setup, use pipenv run instead of docker compose exec app for the commands below.

Tooling

Helper Scripts

Best run before every commit:

  • ./dev/coverage.sh - Run coverage tests and report
  • ./dev/tools.sh - Run Python code tools (isort, black, flake8)

Esoteric and dangerous:

  • ./dev/concatenatemessages.sh - Concatenate legacy ccEngine translations into cc-legal-tools-app
    • rarely used (only after source strings are updated)
  • ./dev/resetdb.sh - Reset Django application database data (!!DANGER!!)
    • usually only helpful if you're doing model/schema work
  • ./dev/updatemessages.sh - Run Django Management nofuzzy_makemessages with helpful options (including excluding legalcode) and compilemessages

Coverage Tests and Report

The coverage tests and report are run as part of pre-commit and as a GitHub Action. To run it manually:

  1. Ensure the Data Repository, above, is in place
  2. Ensure [Docker Compose Setup](#docker compose-setup), above, is complete
  3. Coverage test
    docker compose exec app coverage run manage.py test --noinput --keepdb
    
  4. Coverage report
    docker compose exec app coverage report
    

Commit Errors

Error building trees

If you encounter an error: Error building trees error from pre-commit when you commit, try adding your files (git add <FILES>) prior to committing them.

Frontend Dependencies

The following CC projects are used to achieve a consistent look and feel:

Dependencies:

  • axios/axios: Promise based HTTP client for the browser and node.js
  • jgthms/bulma: Modern CSS framework based on Flexbox
  • vuejs/core: 🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

Data

The legal tools metadata is in a database. The metadata tracks which legal tools exist, their translations, their ports, and their characteristics like what they permit, require, and prohibit.

The metadata can be downloaded by visiting URL path: 127.0.0.1:8005/licenses/metadata.yaml

There are two main models (Django terminology for tables) in legal_tools/models.py:

  1. LegalCode
  2. Tool

A Tool can be identified by a unit (ex. by, by-nc-sa, devnations) which is a proxy for the complete set of permissions, requirements, and prohibitions; a version (ex. 4.0, 3.0), and an optional jurisdiction for ports. So we might refer to the tool by it's identifier "BY 3.0 AM" which would be the 3.0 version of the BY license terms as ported to the Armenia jurisdiction. For additional information see: Legal Tools Namespace - creativecommons/cc-legal-tools-data: CC Legal Tools Data (static HTML, language files, etc.).

There are three places legal code text could be:

  1. gettext files (.po and .mo) in the creativecommons/cc-legal-tools-data repository (legal tools with full translation support):
    • 4.0 Licenses
    • CC0
  2. django template (legalcode_licenses_3.0_unported.html):
    • Unported 3.0 Licenses (English-only)
  3. html field (in the LegalCode model):
    • Everything else

The text that's in gettext files can be translated via Transifex at Creative Commons localization. For additional information the Django translation domains / Transifex resources, see How the license translation is implemented, below.

Documentation:

Importing the existing legal tool text

The process of getting the text into the site varies by legal tool.

Note that once the site is up and running in production, the data in the site will become the canonical source, and the process described here should not need to be repeated after that.

The implementation is the Django management command load_html_files, which reads from the legacy HTML legal code files in the creativecommons/cc-legal-tools-data repository, and populates the database records and translation files.

load_html_files uses BeautifulSoup4 to parse the legacy HTML legal code:

  1. import_zero_license_html for CC0 Public Domain tool
    • HTML is handled specificially (using tag ids and classes) to populate translation strings and to be used with specific HTML formatting when displayed via template
  2. import_by_40_license_html for 4.0 License tools
    • HTML is handled specificially (using tag ids and classes) to populate translation strings and to be used with specific HTML formatting when displayed via a template
  3. import_by_30_unported_license_html for unported 3.0 License tools (English-only)
    • HTML is handled specificially to be used with specific HTML formatting when displayed via a template
  4. simple_import_license_html for everything else
    • HTML is handled generically; only the title and license body are identified. The body is stored in the html field of the LegalCode model

Import Process

This process will read the HTML files from the specified directory, populate LegalCode and Tool models, and create .po files in creativecommons/cc-legal-tools-data.

  1. Ensure the Data Repository, above, is in place
  2. Ensure [Docker Compose Setup](#docker compose-setup), above, is complete
  3. Clear data in the database
    docker compose exec app ./manage.py clear_license_data
    
  4. Load legacy HTML in the database
    docker compose exec app ./manage.py load_html_files
    
  5. Optionally (and only as appropriate):
    1. commit .po file changes in creativecommons/cc-legal-tools-data
    2. Translation Update Process, below
    3. Generate Static Files, below

Import Dependency Documentation

Translation

To upload/download translation files to/from Transifex, you'll need an account there with access to these translations. Then follow the Authentication - Transifex API v3: to get an API token, and set TRANSIFEX["API_TOKEN"] in your environment with its value.

The creativecommons/cc-legal-tools-data repository must be cloned next to this cc-legal-tools-app repository. (It can be elsewhere, then you need to set DATA_REPOSITORY_DIR to its location.) Be sure to clone using a URL that starts with git@github... and not https://github..., or you won't be able to push to it. Also see Data Repository, above.

In production, the check_for_translation_updates management command should be run hourly. See Check for Translation Updates, below.

Also see Publishing changes to git repo, below.

Babel is used for localization information.

Documentation:

How the tool translation is implemented

Django Translation uses two sets of Gettext Files in the creativecommons/cc-legal-tools-data repository (the Data Repository, above). See that repository for detailed information and definitions.

Documentation:

Check for Translation Updates

⚠️ This functionality is currently disabled.

The hourly run of check_for_translation_updates looks to see if any of the translation files in Transifex have newer last modification times than we know about. It performs the following process (which can also be done manually:

  1. Ensure the Data Repository, above, is in place
  2. Within the creativecommons/cc-legal-tools-data (the Data Repository):
    1. Checkout or create the appropriate branch.
      • For example, if a French translation file for BY 4.0 has changed, the branch name will be cc4-fr.
    2. Download the updated .po file from Transifex
    3. Do the Translation Update Process (below)
      • This is important and easy to forget, but without it, Django will keep using the old translations
    4. Commit that change and push it upstream.
  3. Within this cc-legal-tools-app repository:
    1. For each branch that has been updated, Generate Static Files (below). Use the options to update git and push the changes.

Check for Translation Updates Dependency Documentation

Translation Update Process

This Django Admin command must be run any time the .po files are created or changed.

  1. Ensure the Data Repository, above, is in place
  2. Ensure [Docker Compose Setup](#docker compose-setup), above, is complete
  3. Compile translation messages (update .mo files)
    docker compose exec app ./manage.py compilemessages
    

Generate Static Files

Generating static files updates the static files in the doc directory of the creativecommons/cc-legal-tools-data repository (the Data Repository, above).

Static Files Process

This process will write the HTML files in the cc-legal-tools-data clone directory under docs/. It will not commit the changes (--nogit) and will not push any commits (--nopush is implied by --nogit).

  1. Ensure the Data Repository, above, is in place
  2. Ensure [Docker Compose Setup](#docker compose-setup), above, is complete
  3. Compile translation messages (update .mo files)
    docker compose exec app ./manage.py publish --nogit --branch=main
    

Publishing changes to git repo

When the site is deployed, to enable pushing and pulling the licenses data repo with GitHub, create an ssh deploy key for the cc-legal-tools-data repo with write permissions, and put the private key file (not password protected) somewhere safe (owned by www-data if on a server), and readable only by its owner (0o400). Then in settings, make TRANSLATION_REPOSITORY_DEPLOY_KEY be the full path to that deploy key file.

Publishing Dependency Documentation

License