Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add gazettes.africa #1751

Merged
merged 1 commit into from
Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,26 @@ jobs:
git_remote_url: 'ssh://[email protected]:22/ulii-peachjam'
git_push_flags: '--force'

deploy-gazettes:
if: ${{ !cancelled() }}
needs: deploy-gazettes
name: Deploy to gazettes.africa
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: git push to gazettes.africa
uses: dokku/github-action@master
with:
ssh_private_key: ${{ secrets.SSH_DEPLOYMENT_KEY }}
git_remote_url: 'ssh://[email protected]:22/gazettes'
git_push_flags: '--force'

deploy-zanzibarlii:
if: ${{ !cancelled() }}
needs: deploy-lawlibrary
needs: deploy-gazettes
name: Deploy to zanzibarlii
runs-on: ubuntu-latest
steps:
Expand Down
1 change: 1 addition & 0 deletions gazettes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = "gazettes.apps.GazettesAfricaConfig"
6 changes: 6 additions & 0 deletions gazettes/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class GazettesAfricaConfig(AppConfig):
name = "gazettes"
verbose_name = "Gazettes.Africa"
5 changes: 5 additions & 0 deletions gazettes/context_processors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from gazettes.jurisdictions import jurisdiction_list


def jurisdictions(request):
return {"jurisdictions": jurisdiction_list()}
211 changes: 211 additions & 0 deletions gazettes/jurisdictions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
from dataclasses import dataclass
from typing import List


@dataclass
class Jurisdiction:
code: str
name: str
parent_code: str = None
publication: str = "Government Gazette"
sub_publication_label: str = "Sub-publication"
sub_publication_required: bool = False
sub_publications: List[str] = None
number_short: str = "no"
number_long: str = "number"
stitched_supplements: bool = False
ident_requires_last_page: bool = False

@property
def parent(self):
if self.parent_code:
return JURISDICTION_MAP[self.parent_code]

@property
def full_name(self):
if self.parent_code:
return f"{self.name}, {self.parent.name}"
return self.name

@property
def full_name_for_search(self):
if self.parent_code:
return f"{self.parent.name} - {self.name}"
return self.name

@property
def children(self):
return sorted(
[x for x in JURISDICTIONS if x.parent_code == self.code],
key=lambda x: x.name,
)

@property
def place_code(self):
return self.code


JURISDICTIONS = [
Jurisdiction("dz", "Algeria"),
Jurisdiction(
"ao",
"Angola",
sub_publications=["Series I", "Series II", "Series III"],
sub_publication_label="Series",
sub_publication_required=True,
),
Jurisdiction("bw", "Botswana"),
Jurisdiction("cg", "Congo", publication="Journal Officiel"),
Jurisdiction("aa", "African Regional Bodies"),
Jurisdiction("aa-eac", "East African Community", "aa", publication="Gazette"),
Jurisdiction(
"aa-ecowas",
"Economic Community of West African States",
"aa",
publication="Official Journal",
number_short="vol",
number_long="volume",
),
Jurisdiction("gh", "Ghana"),
Jurisdiction("ke", "Kenya"),
Jurisdiction("ls", "Lesotho"),
Jurisdiction("mu", "Mauritius"),
Jurisdiction("mw", "Malawi"),
Jurisdiction(
"mz",
"Mozambique",
sub_publications=["Series I", "Series II", "Series III"],
sub_publication_label="Series",
sub_publication_required=True,
),
Jurisdiction("na", "Namibia"),
Jurisdiction("ng", "Nigeria"),
Jurisdiction("rw", "Rwanda"),
Jurisdiction("sc", "Seychelles", stitched_supplements=True),
Jurisdiction("sl", "Sierra Leone"),
Jurisdiction("sz", "Eswatini"),
Jurisdiction("tz", "Tanzania"),
Jurisdiction("tz-znz", "Zanzibar", "tz"),
Jurisdiction("ug", "Uganda"),
Jurisdiction("zm", "Zambia"),
# ZW supplements require the date from the last page
Jurisdiction(
"zw", "Zimbabwe", ident_requires_last_page=True, stitched_supplements=True
),
Jurisdiction(
"za",
"South Africa",
sub_publications=[
"Regulation Gazette",
"Legal Notices A",
"Legal Notices B",
"Legal Notices C",
"Legal Notices D",
],
),
Jurisdiction("za-wc", "Western Cape", "za", "Provincial Gazette"),
Jurisdiction("za-ec", "Eastern Cape", "za", "Provincial Gazette"),
Jurisdiction("za-gp", "Gauteng", "za", "Provincial Gazette"),
Jurisdiction("za-kzn", "KwaZulu-Natal", "za", "Provincial Gazette"),
Jurisdiction("za-lp", "Limpopo", "za", "Provincial Gazette"),
Jurisdiction("za-mp", "Mpumalanga", "za", "Provincial Gazette"),
Jurisdiction("za-nw", "North-West", "za", "Provincial Gazette"),
Jurisdiction("za-nc", "Northern Cape", "za", "Provincial Gazette"),
Jurisdiction("za-fs", "Free State", "za", "Provincial Gazette"),
Jurisdiction("za-transvaal", "Transvaal", "za", "Provincial Gazette"),
Jurisdiction("ng-la", "Lagos State", "ng", "Official Gazette"),
Jurisdiction("ma", "Morocco", publication="Bulletin Officiel"),
Jurisdiction("so", "Somalia"),
Jurisdiction("so-sl", "Somaliland", "so", "Official Gazette"),
]
JURISDICTION_MAP = {x.code: x for x in JURISDICTIONS}
JURISDICTION_CHOICES = [(x.code, x.name) for x in JURISDICTIONS]

COMMUNITIES = {"aa-eac", "aa-ecowas"}

CONTRIBUTORS = {
"sz": [
{
"name": "Werksmans",
"url": "https://www.werksmans.com/",
"img": "werksmans-logo.png",
}
],
"bw": [
{
"name": "Werksmans",
"url": "https://www.werksmans.com/",
"img": "werksmans-logo.png",
}
],
"za": [
{
"name": "GIZ",
"url": "https://www.giz.de/",
"img": "giz-logo.gif",
},
{
"name": "Webber Wentzel",
"url": "https://www.webberwentzel.com",
"img": "ww-logo.png",
},
],
"za-fs": [
{
"name": "Free State Province",
"url": "http://www.premier.fs.gov.za",
"img": "za-fs-logo.jpg",
}
],
"zw": [
{
"name": "Veritas Zimbabwe",
"url": "https://www.veritaszim.net/",
"img": "veritas-logo.png",
}
],
None: [
{
"name": "The Indigo Trust",
"url": "https://indigotrust.org.uk/",
"img": "indigo-trust-logo.png",
},
{
"name": "UCT Government Publications",
"url": "http://www.governmentpublications.lib.uct.ac.za/",
"img": "uct-logo.png",
},
{
"name": "C4ADS",
"url": "https://c4ads.org",
"img": "c4ads-logo.png",
},
],
}
ALL_CONTRIBUTORS = sorted(
list({c["name"]: c for x in CONTRIBUTORS.values() for c in x}.values()),
key=lambda c: c["name"],
)


def get_country_locality(code):
from countries_plus.models import Country

from peachjam.models import Locality

if "-" in code:
ctry, loc = code.split("-", 1)
else:
ctry = code
loc = None

ctry = Country.objects.get(pk=ctry.upper())
if loc:
loc = Locality.objects.get(jurisdiction=ctry, code=loc)

return ctry, loc


def jurisdiction_list():
"""List of (code, name) tuples for active jurisdictions."""
return sorted(JURISDICTIONS, key=lambda j: j.name)
41 changes: 41 additions & 0 deletions gazettes/middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from django.conf import settings
from django.http import HttpResponseNotFound, HttpResponsePermanentRedirect
from django.utils.deprecation import MiddlewareMixin


class RedirectMiddleware(MiddlewareMixin):
"""Middleware that redirects requests to:

- the legacy archive.gazettes.laws.africa
- www.gazettes.africa

to gazettes.africa.
"""

def process_request(self, request):
host = request.get_host()
if host in ["archive.gazettes.laws.africa", "www.gazettes.africa"]:
uri = f"https://gazettes.africa{request.get_full_path()}"
return HttpResponsePermanentRedirect(uri)


class NoIPMiddleware(MiddlewareMixin):
"""Middleware that forces a 404 for an request that does not use a
domain name.

We use this because otherwise Google indexes the gazettes archive using
the IP of the server, for some odd reason.

Note that during deployment, the dokku aliveness check comes from a local host
with an ip, but with ':5000'
"""

def process_request(self, request):
host = request.get_host()
if (
not settings.DEBUG
and "africa" not in host
and "localhost" not in host
and not host.endswith(":5000")
):
return HttpResponseNotFound("not found")
55 changes: 55 additions & 0 deletions gazettes/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from peachjam.settings import * # noqa

# Application definition
INSTALLED_APPS = [
"gazettes",
"django.contrib.humanize",
] + INSTALLED_APPS # noqa


MIDDLEWARE = [
"gazettes.middleware.RedirectMiddleware",
"gazettes.middleware.NoIPMiddleware",
"allauth.account.middleware.AccountMiddleware",
] + MIDDLEWARE # noqa


# allow cross-site access from all secure origins
CORS_ALLOWED_ORIGIN_REGEXES = [r"^https://.*"]
CORS_ALLOW_CREDENTIALS = True
CORS_URLS_REGEX = r"^.*$"


ROOT_URLCONF = "gazettes.urls"


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
default_db_url = "postgres://gazettes:gazettes@localhost:5432/gazettes"
db_config = dj_database_url.config( # noqa
default=os.environ.get("DATABASE_URL", default_db_url) # noqa
)
db_config["ATOMIC_REQUESTS"] = True # noqa
DATABASES["default"] = db_config # noqa


SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True

X_FRAME_OPTIONS = "SAMEORIGIN"


LANGUAGES = [
("en", "English"),
]


PEACHJAM["APP_NAME"] = "Gazettes.Africa" # noqa
PEACHJAM["ES_INDEX"] = "gazettemachine" # noqa
PEACHJAM["SEARCH_JURISDICTION_FILTER"] = True # noqa
PEACHJAM["MULTIPLE_JURISDICTIONS"] = True # noqa


TEMPLATES[0]["OPTIONS"]["context_processors"].append( # noqa
"gazettes.context_processors.jurisdictions"
)
Loading
Loading