├── links └── .gitignore ├── ckanext ├── canada │ ├── __init__.py │ ├── templates │ │ ├── security │ │ │ └── emails │ │ │ │ ├── lockout_footer.txt │ │ │ │ ├── lockout_subject.txt │ │ │ │ └── lockout_mail.txt │ │ ├── user │ │ │ ├── snippets │ │ │ │ ├── followee_dropdown.html │ │ │ │ ├── placeholder.html │ │ │ │ ├── api_token_list.html │ │ │ │ └── user_search.html │ │ │ ├── logout.html │ │ │ ├── edit.html │ │ │ ├── edit_base.html │ │ │ ├── api_tokens.html │ │ │ ├── activity_stream.html │ │ │ ├── request_reset.html │ │ │ ├── dashboard_datasets.html │ │ │ ├── new_user_email.html │ │ │ ├── confirm_delete.html │ │ │ ├── perform_reset.html │ │ │ ├── recover_username.html │ │ │ ├── dashboard.html │ │ │ └── user_welcome_email.html │ │ ├── package │ │ │ ├── snippets │ │ │ │ ├── info.html │ │ │ │ ├── dictionary_table.html │ │ │ │ ├── share_widget.html │ │ │ │ ├── resource_view_embed.html │ │ │ │ ├── data_api_button.html │ │ │ │ ├── resource_view.html │ │ │ │ ├── socialmedia.html │ │ │ │ ├── resources_list.html │ │ │ │ ├── resource_views_list_item.html │ │ │ │ └── view_form.html │ │ │ ├── edit_view.html │ │ │ ├── new.html │ │ │ ├── view_edit_base.html │ │ │ ├── resource_edit.html │ │ │ ├── edit.html │ │ │ ├── resources.html │ │ │ ├── confirm_delete.html │ │ │ ├── base.html │ │ │ ├── deleted.html │ │ │ ├── edit_base.html │ │ │ ├── resource_edit_base.html │ │ │ ├── base_form_page.html │ │ │ └── new_resource_not_draft.html │ │ ├── revision │ │ │ └── read_base.html │ │ ├── scheming │ │ │ ├── display_snippets │ │ │ │ ├── validation_timestamp.html │ │ │ │ ├── canada_license.html │ │ │ │ ├── filesize.html │ │ │ │ ├── validation_status.html │ │ │ │ ├── list_inline.html │ │ │ │ ├── email_with_parameters.html │ │ │ │ ├── credit_name.html │ │ │ │ ├── br_multiple_choice.html │ │ │ │ ├── resource_relationship.html │ │ │ │ ├── dataset_relationship.html │ │ │ │ └── fluent_tags.html │ │ │ ├── form_snippets │ │ │ │ ├── portal_release_date.html │ │ │ │ ├── ro_fluent_title.html │ │ │ │ ├── ro_fluent_markdown.html │ │ │ │ ├── ro_select.html │ │ │ │ ├── ro_date.html │ │ │ │ ├── organization.html │ │ │ │ ├── ro_org.html │ │ │ │ ├── ro_fluent_tags.html │ │ │ │ ├── repeating_subfields.html │ │ │ │ └── ro_multiple_choice.html │ │ │ ├── snippets │ │ │ │ ├── errors.html │ │ │ │ └── form_field.html │ │ │ ├── organization │ │ │ │ └── group_form.html │ │ │ └── package │ │ │ │ └── read.html │ │ ├── footer.html │ │ ├── tabledesigner │ │ │ └── view_snippets │ │ │ │ ├── cra_business_number.html │ │ │ │ └── province.html │ │ ├── snippets │ │ │ ├── tag_list.html │ │ │ ├── follow_button.html │ │ │ ├── activities │ │ │ │ ├── changed_datastore.html │ │ │ │ ├── created_datastore.html │ │ │ │ └── deleted_datastore.html │ │ │ ├── cdts │ │ │ │ └── footer.html │ │ │ ├── package_list.html │ │ │ ├── share_page.html │ │ │ ├── license.html │ │ │ ├── stream.html │ │ │ ├── activity_item.html │ │ │ ├── social.html │ │ │ └── activity_type_selector.html │ │ ├── validation │ │ │ └── validation_read.html │ │ ├── datatables │ │ │ └── datatables_form.html │ │ ├── header.html │ │ ├── organization │ │ │ ├── base_form_page.html │ │ │ ├── snippets │ │ │ │ ├── organization_list.html │ │ │ │ ├── helper.html │ │ │ │ ├── organization_item.html │ │ │ │ └── organization_search.html │ │ │ ├── edit.html │ │ │ ├── manage_members.html │ │ │ ├── read.html │ │ │ ├── about.html │ │ │ ├── search_rebuild.html │ │ │ ├── activity_stream.html │ │ │ ├── confirm_delete_member.html │ │ │ └── index.html │ │ ├── text_view.html │ │ ├── admin │ │ │ ├── snippets │ │ │ │ ├── package_item.html │ │ │ │ └── portal_sync_package_item.html │ │ │ ├── search_rebuild.html │ │ │ ├── trash.html │ │ │ ├── index.html │ │ │ └── base.html │ │ ├── xloader │ │ │ └── resource_data.html │ │ ├── datastore │ │ │ └── snippets │ │ │ │ ├── dictionary_view.html │ │ │ │ └── dictionary_form.html │ │ ├── recombinant │ │ │ └── snippets │ │ │ │ ├── service_delete_fk_error.html │ │ │ │ └── service_std_upsert_fk_error.html │ │ ├── home │ │ │ └── robots.txt │ │ └── macros │ │ │ └── canada_activity.html │ ├── tables │ │ └── choices │ │ │ ├── .gitignore │ │ │ ├── yes_no.yaml │ │ │ ├── level_number.yaml │ │ │ ├── year.yaml │ │ │ ├── online_service_yes_no.yaml │ │ │ ├── gregor_month.yaml │ │ │ └── fiscal_year.yaml │ ├── public │ │ └── static │ │ │ ├── schema.json │ │ │ └── img │ │ │ ├── data_img │ │ │ ├── dot.svg │ │ │ ├── dot-white.svg │ │ │ ├── dot-blue.svg │ │ │ ├── dot-grey.svg │ │ │ ├── dash.svg │ │ │ ├── check.svg │ │ │ ├── chevron-down.svg │ │ │ ├── burger.svg │ │ │ ├── check-green.svg │ │ │ ├── burger-lite.svg │ │ │ ├── chevron-left.svg │ │ │ ├── chevron-right.svg │ │ │ ├── chevron-down-blue.svg │ │ │ ├── chevron-down-grey.svg │ │ │ ├── danger.svg │ │ │ ├── close-black.svg │ │ │ └── modal-close.svg │ │ │ ├── dotted.png │ │ │ ├── leaves │ │ │ ├── stars.png │ │ │ ├── onestar.png │ │ │ ├── twostar.png │ │ │ ├── fivestar.png │ │ │ ├── fourstar.png │ │ │ ├── threestar.png │ │ │ └── zerostar.png │ │ │ ├── stars │ │ │ ├── star0.png │ │ │ ├── star1.png │ │ │ ├── star2.png │ │ │ ├── star3.png │ │ │ ├── star4.png │ │ │ └── star5.png │ │ │ ├── canada_default.png │ │ │ ├── select2x2_white.png │ │ │ ├── sprite-resource-additional-icons.png │ │ │ └── badges │ │ │ ├── en │ │ │ ├── datastore-error.svg │ │ │ ├── datastore-active.svg │ │ │ ├── datastore-pending.svg │ │ │ ├── datastore-running.svg │ │ │ ├── datastore-unknown.svg │ │ │ ├── datastore-complete.svg │ │ │ └── datastore-inactive.svg │ │ │ └── fr │ │ │ ├── datastore-active.svg │ │ │ ├── datastore-error.svg │ │ │ ├── datastore-complete.svg │ │ │ ├── datastore-inactive.svg │ │ │ ├── datastore-unknown.svg │ │ │ ├── datastore-pending.svg │ │ │ └── datastore-running.svg │ ├── migration │ │ └── canada_public │ │ │ ├── README │ │ │ └── script.py.mako │ ├── tests │ │ ├── samples │ │ │ ├── sample.csv │ │ │ ├── sample_with_empty_lines.csv │ │ │ ├── sample_with_extra_white_space.csv │ │ │ └── sample_with_bad_ds_headers.csv │ │ ├── fixtures.py │ │ ├── test_helpers.py │ │ ├── helpers.py │ │ └── __init__.py │ ├── assets │ │ ├── public │ │ │ ├── check_all.js │ │ │ ├── more_like_this.js │ │ │ ├── i18n.js │ │ │ ├── webassets.yml │ │ │ └── adobe_analytics_fix.js │ │ ├── invitation-manager │ │ │ └── webassets.yml │ │ ├── datatables │ │ │ ├── webassets.yml │ │ │ └── canada_datatables.js │ │ └── internal │ │ │ ├── recombinant_webform.js │ │ │ ├── registry_package_edit.js │ │ │ ├── registry_resource_edit.js │ │ │ └── registry_organization_edit.js │ ├── schemas │ │ └── validation_placeholder_presets.yaml │ ├── plugin │ │ ├── __init__.py │ │ └── validation_plugin.py │ └── strings.js └── __init__.py ├── bin ├── warehouse │ ├── warehouse_reports │ │ └── .gitignore │ └── .gitignore ├── resource_urls.py ├── filter │ ├── filter_dac.py │ ├── filter_contracts.py │ ├── filter_qpnotes.py │ ├── filter_contractsa.py │ ├── filter_experiment.py │ ├── filter_wrongdoing.py │ ├── filter_contracts_nil.py │ ├── filter_current_consultations.py │ ├── filter_grants.py │ ├── filter_reclassification.py │ ├── filter_aistrategy.py │ ├── filter_adminaircraft.py │ ├── filter_disclosure_group.py │ ├── filter_modified_created.py │ ├── filter_ati.py │ └── filter_travela.py ├── user_list_filter.py ├── user_import_filter.py ├── resource_management │ └── update_resource_size.py ├── restore_trade_agreement_exceptions.py └── transitional_orgs_filter.py ├── changes ├── 1502.changes ├── 1570.bugfix ├── 1593.changes ├── 1594.bugfix ├── 0003.changes ├── 0017.changes ├── 1473.removal ├── 1481.changes ├── 1503.feature ├── 1546.changes ├── 1548.changes ├── 1567.feature ├── 1603.removal ├── 1630.removal ├── v210.release ├── 0016.changes ├── 1490.misc ├── 1520.changes ├── 1572.changes ├── 1592.changes ├── 1599.c.changes ├── 1607.hotfix ├── 1634.changes ├── 0004.feature ├── 0013.changes ├── 1472.bugfix ├── 1473.a.bugfix ├── 1487.changes ├── 1517.changes ├── 1542.bugfix ├── 1568.changes ├── 1581.changes ├── 1606.changes ├── 1616.changes ├── 1626.changes ├── 0001.a.feature ├── 0001.b.feature ├── 1498.feature ├── 1511.bugfix ├── 1531.feature ├── 1539.bugfix ├── 1549.changes ├── 1552.changes ├── 1553.a.feature ├── 1561.changes ├── 1585.changes ├── 1596.changes ├── 1597.changes ├── 1473.changes ├── 1547.changes ├── 1547.removal ├── 1564.changes ├── 1578.changes ├── 1624.changes ├── 0002.bugfix ├── 1479.bugfix ├── 1480.a.feature ├── 1491.changes ├── 1504.bugfix ├── 1534.feature ├── 1535.hotfix ├── 1537.changes ├── 1550.removal ├── 1557.changes ├── 1598.changes ├── 1617.changes ├── 1620.changes ├── 1635.feature ├── 1478.changes ├── 1495.feature ├── 1586.changes ├── 0015.bugfix ├── 1472.a.feature ├── 1473.b.bugfix ├── 1474.removal ├── 1488.changes ├── 1501.bugfix ├── 1503.b.changes ├── 1527.changes ├── 1557.bugfix ├── 1566.changes ├── 1604.bugfix ├── 1605.feature ├── 1611.changes ├── 1613.changes ├── 1614.changes ├── 1509.bugfix ├── 1542.changes ├── 1562.feature ├── 1609.hotfix ├── 0007.hotfix ├── 1475.bugfix ├── 1492.bugfix ├── 1555.changes ├── 1559.feature ├── 1573.feature ├── 1575.changes ├── 1599.b.changes ├── 1608.bugfix ├── 0018.hotfix ├── 1494.removal ├── 1558.changes ├── 1588.changes ├── 1612.changes ├── 1619.feature ├── 0009.bugfix ├── 1496.changes ├── 1529.changes ├── 1554.feature ├── 1576.changes ├── 1587.changes ├── 1615.changes ├── 0010.hotfix ├── 0011.changes ├── 0012.hotfix ├── 1486.changes ├── 1493.feature ├── 1500.feature ├── 1507.changes ├── 1563.removal ├── 0006.bugfix ├── 1483.bugfix ├── 1523.changes ├── 1524.changes ├── 1532.changes ├── 1533.changes ├── 1543.feature ├── 1553.b.feature ├── 1574.bugfix ├── 1601.changes ├── 1637.feature ├── 0014.changes ├── 1513.changes ├── 1514.feature ├── 1541.changes ├── 1569.changes ├── 1573.a.changes ├── 1589.changes ├── 1477.changes ├── 1553.changes ├── 1573.b.changes ├── 1606.bugfix ├── 1621.feature ├── 1623.changes ├── 1503.a.changes ├── 1512.bugfix ├── 1599.a.changes ├── 1610.changes ├── 0008.changes ├── 1485.changes ├── 1521.feature ├── 1530.feature ├── 1628.changes ├── 0005.bugfix ├── 1522.feature ├── 1536.bugfix ├── 1580.changes ├── 1595.feature ├── 1480.b.feature ├── 1489.bugfix ├── 1540.changes ├── 1618.feature ├── 1515.bugfix ├── 1584.hotfix ├── 1528.changes ├── 1538.hotfix ├── 1579.changes ├── 1545.changes ├── 1518.changes ├── 1632.changes ├── 1482.bugfix ├── 1599.feature ├── 1556.changes ├── 1508.bugfix ├── 1497.changes ├── 1622.changes ├── 1472.b.feature ├── 1510.feature ├── 1591.changes ├── 1577.feature ├── 1600.changes ├── 1551.changes ├── 1499.feature ├── 1571.feature ├── 1505.changes └── 1342.changes ├── .test_durations.gz ├── docs ├── pd-data-flow.jpg ├── pd-data-flow.odg ├── pd-data-flow.png └── suggest-dataset-dfd.vsdx ├── samples ├── dq170529a-eng.pdf ├── dq170529a-fra.pdf ├── dq170529b-eng.pdf ├── dq170529b-fra.pdf ├── dq170529c-eng.pdf ├── dq170529c-fra.pdf ├── dq170529d-eng.pdf ├── dq170529d-fra.pdf └── upload_file.sh ├── MANIFEST.in ├── test-requirements.txt ├── requirements.txt ├── .coveragerc ├── codecov.yml ├── .gitignore ├── .travis.yml ├── package.json ├── .github └── workflows │ ├── flake8.yml │ ├── test.yml │ └── dac.yml ├── setup.cfg ├── conf ├── who.ini └── who-security.ini └── azure-pipelines.yml /links/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/warehouse/warehouse_reports/.gitignore: -------------------------------------------------------------------------------- 1 | *.csv -------------------------------------------------------------------------------- /changes/1502.changes: -------------------------------------------------------------------------------- 1 | Update the ministers json file -------------------------------------------------------------------------------- /changes/1570.bugfix: -------------------------------------------------------------------------------- 1 | Added missing French translations. -------------------------------------------------------------------------------- /changes/1593.changes: -------------------------------------------------------------------------------- 1 | Service Inventory updates for 2025 FY. -------------------------------------------------------------------------------- /changes/1594.bugfix: -------------------------------------------------------------------------------- 1 | filter recovery email sent to logs 2 | -------------------------------------------------------------------------------- /changes/0003.changes: -------------------------------------------------------------------------------- 1 | Translated more colons for French. 2 | -------------------------------------------------------------------------------- /changes/0017.changes: -------------------------------------------------------------------------------- 1 | Increased `pytest` dependency versions. -------------------------------------------------------------------------------- /changes/1473.removal: -------------------------------------------------------------------------------- 1 | Removed old, unused Jinja2 macros. 2 | -------------------------------------------------------------------------------- /changes/1481.changes: -------------------------------------------------------------------------------- 1 | Released Python 3 compatible code. 2 | -------------------------------------------------------------------------------- /changes/1503.feature: -------------------------------------------------------------------------------- 1 | Released new Service Inventory schema. 2 | -------------------------------------------------------------------------------- /changes/1546.changes: -------------------------------------------------------------------------------- 1 | Update ministers list for December, 2024. -------------------------------------------------------------------------------- /changes/1548.changes: -------------------------------------------------------------------------------- 1 | Update ministers list for January, 2025. -------------------------------------------------------------------------------- /changes/1567.feature: -------------------------------------------------------------------------------- 1 | Added support for ckanext-citeproc 2 | -------------------------------------------------------------------------------- /changes/1603.removal: -------------------------------------------------------------------------------- 1 | Removed old WET Maps files from codebase. -------------------------------------------------------------------------------- /changes/1630.removal: -------------------------------------------------------------------------------- 1 | Remove warning alert from the Contracts PD. -------------------------------------------------------------------------------- /changes/v210.release: -------------------------------------------------------------------------------- 1 | Released CKAN 2.10 compatible code. 2 | -------------------------------------------------------------------------------- /ckanext/canada/templates/security/emails/lockout_footer.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/warehouse/.gitignore: -------------------------------------------------------------------------------- 1 | data/* 2 | temp/* 3 | warehouse_reports/* -------------------------------------------------------------------------------- /changes/0016.changes: -------------------------------------------------------------------------------- 1 | Updated the README with up to date information. -------------------------------------------------------------------------------- /changes/1490.misc: -------------------------------------------------------------------------------- 1 | add 3 open maps file formats: COG, APRX, PBF 2 | -------------------------------------------------------------------------------- /changes/1520.changes: -------------------------------------------------------------------------------- 1 | Markdown help popup has been translated. 2 | -------------------------------------------------------------------------------- /changes/1572.changes: -------------------------------------------------------------------------------- 1 | Update ministers list for March 14, 2025. 2 | -------------------------------------------------------------------------------- /changes/1592.changes: -------------------------------------------------------------------------------- 1 | service program id list: update from csv 2 | -------------------------------------------------------------------------------- /changes/1599.c.changes: -------------------------------------------------------------------------------- 1 | Customized `robots.txt` for CKAN instances. -------------------------------------------------------------------------------- /changes/1607.hotfix: -------------------------------------------------------------------------------- 1 | Fixed an issue with the DCAT links not rendering. -------------------------------------------------------------------------------- /changes/1634.changes: -------------------------------------------------------------------------------- 1 | Update ministers list for December, 2025. 2 | -------------------------------------------------------------------------------- /ckanext/canada/tables/choices/.gitignore: -------------------------------------------------------------------------------- 1 | commodity_code.json 2 | -------------------------------------------------------------------------------- /changes/0004.feature: -------------------------------------------------------------------------------- 1 | Added UI for sysadmins to unlock user accounts. 2 | -------------------------------------------------------------------------------- /changes/0013.changes: -------------------------------------------------------------------------------- 1 | Aligned test cases with new Recombinant code. 2 | -------------------------------------------------------------------------------- /changes/1472.bugfix: -------------------------------------------------------------------------------- 1 | Only Sysadmins can view the Admin index page. 2 | -------------------------------------------------------------------------------- /changes/1473.a.bugfix: -------------------------------------------------------------------------------- 1 | Fixed search facet for portal_release_date. 2 | -------------------------------------------------------------------------------- /changes/1487.changes: -------------------------------------------------------------------------------- 1 | Minor changes to the FAQ page for the Registry users. -------------------------------------------------------------------------------- /changes/1517.changes: -------------------------------------------------------------------------------- 1 | Update ministers list after changes on Sept 19, 2024. -------------------------------------------------------------------------------- /changes/1542.bugfix: -------------------------------------------------------------------------------- 1 | Fixed Excel formulae for Grants & Contributions. 2 | -------------------------------------------------------------------------------- /changes/1568.changes: -------------------------------------------------------------------------------- 1 | Updated country names to latest ISO dataset. 2 | -------------------------------------------------------------------------------- /changes/1581.changes: -------------------------------------------------------------------------------- 1 | Hide the new "Unpublish" button in dataset forms. -------------------------------------------------------------------------------- /changes/1606.changes: -------------------------------------------------------------------------------- 1 | Added `mrc` file format as a valid Resource format. -------------------------------------------------------------------------------- /changes/1616.changes: -------------------------------------------------------------------------------- 1 | Added alert copy for Organization deleted states. -------------------------------------------------------------------------------- /changes/1626.changes: -------------------------------------------------------------------------------- 1 | Small changes to the AI Strategy yaml (OPEN-4278). -------------------------------------------------------------------------------- /ckanext/canada/public/static/schema.json: -------------------------------------------------------------------------------- 1 | ../../metadata_schema/schema.json -------------------------------------------------------------------------------- /changes/0001.a.feature: -------------------------------------------------------------------------------- 1 | Added test coverage for Validation into DataStore. 2 | -------------------------------------------------------------------------------- /changes/0001.b.feature: -------------------------------------------------------------------------------- 1 | Added test coverage for Xloader into DataStore. 2 | -------------------------------------------------------------------------------- /changes/1498.feature: -------------------------------------------------------------------------------- 1 | Add feature to delete selected rows from pd preview table. -------------------------------------------------------------------------------- /changes/1511.bugfix: -------------------------------------------------------------------------------- 1 | nap5: enforce validation on status, progress fields 2 | -------------------------------------------------------------------------------- /changes/1531.feature: -------------------------------------------------------------------------------- 1 | Add new Indigenous language "Innu-Aimun" to presets.yaml. -------------------------------------------------------------------------------- /changes/1539.bugfix: -------------------------------------------------------------------------------- 1 | Add translations for the resource field validation_status -------------------------------------------------------------------------------- /changes/1549.changes: -------------------------------------------------------------------------------- 1 | Remove rebuilding wrongdoing for the Drupal search. 2 | -------------------------------------------------------------------------------- /changes/1552.changes: -------------------------------------------------------------------------------- 1 | Use `ckan.plugins.toolkit` instead of `ckantoolkit` 2 | -------------------------------------------------------------------------------- /changes/1553.a.feature: -------------------------------------------------------------------------------- 1 | Added a select all checkbox to the PD DataTables. 2 | -------------------------------------------------------------------------------- /changes/1561.changes: -------------------------------------------------------------------------------- 1 | Set the correct `template_updated` for all PD types. 2 | -------------------------------------------------------------------------------- /changes/1585.changes: -------------------------------------------------------------------------------- 1 | Updated "Examplar" to "Example" for French translation -------------------------------------------------------------------------------- /changes/1596.changes: -------------------------------------------------------------------------------- 1 | Fix missing translation updates for support email change. -------------------------------------------------------------------------------- /changes/1597.changes: -------------------------------------------------------------------------------- 1 | Service Inventory updates to the data dictionary (2025). -------------------------------------------------------------------------------- /changes/1473.changes: -------------------------------------------------------------------------------- 1 | Improved HTML layouts and uniformity across search forms. 2 | -------------------------------------------------------------------------------- /changes/1547.changes: -------------------------------------------------------------------------------- 1 | Refactor code to meet CKAN and Python coding standards. 2 | -------------------------------------------------------------------------------- /changes/1547.removal: -------------------------------------------------------------------------------- 1 | Removed old, unused scripts from `bin` and `migration` 2 | -------------------------------------------------------------------------------- /changes/1564.changes: -------------------------------------------------------------------------------- 1 | Set configuration for public_activity_stream_detail to False. -------------------------------------------------------------------------------- /changes/1578.changes: -------------------------------------------------------------------------------- 1 | Update ministers list after elections on May 13, 2025. 2 | -------------------------------------------------------------------------------- /changes/1624.changes: -------------------------------------------------------------------------------- 1 | Heavily improved the automated pytests and GitHub workflows. -------------------------------------------------------------------------------- /ckanext/canada/migration/canada_public/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /changes/0002.bugfix: -------------------------------------------------------------------------------- 1 | Fixed an issue with the Registry Organizations to CSV script. 2 | -------------------------------------------------------------------------------- /changes/1479.bugfix: -------------------------------------------------------------------------------- 1 | Fixed the database trigger name for Question Period Notes NTR. 2 | -------------------------------------------------------------------------------- /changes/1480.a.feature: -------------------------------------------------------------------------------- 1 | Load the GCWeb and WET assets and scripts from the CDTS CDN. 2 | -------------------------------------------------------------------------------- /changes/1491.changes: -------------------------------------------------------------------------------- 1 | Added new CSS layout for Datatables' column visibility modal. 2 | -------------------------------------------------------------------------------- /changes/1504.bugfix: -------------------------------------------------------------------------------- 1 | Check for `None` type in update_pd_record for the money field 2 | -------------------------------------------------------------------------------- /changes/1534.feature: -------------------------------------------------------------------------------- 1 | Added Dataset & Resource repeating Relationship field groups. 2 | -------------------------------------------------------------------------------- /changes/1535.hotfix: -------------------------------------------------------------------------------- 1 | Service Inventory primary key fields no longer allow commas. 2 | -------------------------------------------------------------------------------- /changes/1537.changes: -------------------------------------------------------------------------------- 1 | Resource file size now displays in a human-readable format. 2 | -------------------------------------------------------------------------------- /changes/1550.removal: -------------------------------------------------------------------------------- 1 | Removed the old API Key modal from the user profile template. 2 | -------------------------------------------------------------------------------- /changes/1557.changes: -------------------------------------------------------------------------------- 1 | Added test coverage for the `filter_service_std.py` script. 2 | -------------------------------------------------------------------------------- /changes/1598.changes: -------------------------------------------------------------------------------- 1 | Added `rel="noopener norefferer"` to all `_blank` target anchors. -------------------------------------------------------------------------------- /changes/1617.changes: -------------------------------------------------------------------------------- 1 | Pin python3-cryptography to 45.0.7 in response to RHSA-2025:14553. -------------------------------------------------------------------------------- /changes/1620.changes: -------------------------------------------------------------------------------- 1 | Added SHA384 hash integrities to 3rd party scripts and stylesheets. -------------------------------------------------------------------------------- /changes/1635.feature: -------------------------------------------------------------------------------- 1 | Added capability to add and override strings in the CKAN i18n API. -------------------------------------------------------------------------------- /changes/1478.changes: -------------------------------------------------------------------------------- 1 | Create and Update PD Record forms now have better error messaging. 2 | -------------------------------------------------------------------------------- /changes/1495.feature: -------------------------------------------------------------------------------- 1 | Integrate survey pop-up using GC invitation-manager on dataset pages. -------------------------------------------------------------------------------- /changes/1586.changes: -------------------------------------------------------------------------------- 1 | Modified Url to add language in order for the dropdown to be bilingual -------------------------------------------------------------------------------- /ckanext/canada/templates/user/snippets/followee_dropdown.html: -------------------------------------------------------------------------------- 1 | {# Do not use followees #} 2 | -------------------------------------------------------------------------------- /.test_durations.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/.test_durations.gz -------------------------------------------------------------------------------- /changes/0015.bugfix: -------------------------------------------------------------------------------- 1 | Fixed an issue with the app global `is_registry` for new Jinja versions. 2 | -------------------------------------------------------------------------------- /changes/1472.a.feature: -------------------------------------------------------------------------------- 1 | Organization and Group views need a user session to view on Registry. 2 | -------------------------------------------------------------------------------- /changes/1473.b.bugfix: -------------------------------------------------------------------------------- 1 | Fixed an issue with the search facet dictionary resizing inside loops. 2 | -------------------------------------------------------------------------------- /changes/1474.removal: -------------------------------------------------------------------------------- 1 | Remove the Suggest a Dataset status update link from Registry homepage 2 | -------------------------------------------------------------------------------- /changes/1488.changes: -------------------------------------------------------------------------------- 1 | Update 'Get started' sentence on the FAQ page for the Registry users. 2 | -------------------------------------------------------------------------------- /changes/1501.bugfix: -------------------------------------------------------------------------------- 1 | - Fix translation for content type 2 | - Add space with colon (:) on forms 3 | -------------------------------------------------------------------------------- /changes/1503.b.changes: -------------------------------------------------------------------------------- 1 | DataDictionary description fields now renders the markdown contents. 2 | -------------------------------------------------------------------------------- /changes/1527.changes: -------------------------------------------------------------------------------- 1 | Adding the Django Search to the PD Makefile for the Hospitalityq type. 2 | -------------------------------------------------------------------------------- /changes/1557.bugfix: -------------------------------------------------------------------------------- 1 | Fixed the logic for `target_met` calculated field for Service Standard. 2 | -------------------------------------------------------------------------------- /changes/1566.changes: -------------------------------------------------------------------------------- 1 | Remove the unused --quiet option for Search csv import from the PD Makefile -------------------------------------------------------------------------------- /changes/1604.bugfix: -------------------------------------------------------------------------------- 1 | Fixed an issue with Adobe analytics scripts not loading with CSP directives. -------------------------------------------------------------------------------- /changes/1605.feature: -------------------------------------------------------------------------------- 1 | Use the new `nocache_store` blueprint decorator for login and reset pages. -------------------------------------------------------------------------------- /changes/1611.changes: -------------------------------------------------------------------------------- 1 | Update activity codes for AI Strategy yaml to fix the underlying data model. -------------------------------------------------------------------------------- /changes/1613.changes: -------------------------------------------------------------------------------- 1 | If there is no login session, `/links` will now redirect to the login page. -------------------------------------------------------------------------------- /changes/1614.changes: -------------------------------------------------------------------------------- 1 | Front end guess mimetypes no longer manipulates the upload field's fake path. -------------------------------------------------------------------------------- /changes/1509.bugfix: -------------------------------------------------------------------------------- 1 | add published_resource_id for the QPNOTES-nil.csv resource file. Needed for PR 1507 -------------------------------------------------------------------------------- /changes/1542.changes: -------------------------------------------------------------------------------- 1 | Updated various field descriptions and obligations for Grants & Contributions. 2 | -------------------------------------------------------------------------------- /changes/1562.feature: -------------------------------------------------------------------------------- 1 | Adds another Recombinant alert area, use `template_warning` in the Schema. 2 | -------------------------------------------------------------------------------- /changes/1609.hotfix: -------------------------------------------------------------------------------- 1 | Fixed a major issue with Google Analytics not loading and sending tracking data. -------------------------------------------------------------------------------- /docs/pd-data-flow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/docs/pd-data-flow.jpg -------------------------------------------------------------------------------- /docs/pd-data-flow.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/docs/pd-data-flow.odg -------------------------------------------------------------------------------- /docs/pd-data-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/docs/pd-data-flow.png -------------------------------------------------------------------------------- /changes/0007.hotfix: -------------------------------------------------------------------------------- 1 | Added casting to `NUMERIC` for the DAC triggers to support old `money` column types. 2 | -------------------------------------------------------------------------------- /changes/1475.bugfix: -------------------------------------------------------------------------------- 1 | Fixed an issue with the Organization Autocomplete endpoint not working properly. 2 | -------------------------------------------------------------------------------- /changes/1492.bugfix: -------------------------------------------------------------------------------- 1 | Bugfix for the validation report not rendering because it does not recognize this.ckan -------------------------------------------------------------------------------- /changes/1555.changes: -------------------------------------------------------------------------------- 1 | The Portal Update command will send correct exit codes when the worker pool fails. 2 | -------------------------------------------------------------------------------- /changes/1559.feature: -------------------------------------------------------------------------------- 1 | Foreign keys will now display HTML links to the referential data in PD DataTables. 2 | -------------------------------------------------------------------------------- /changes/1573.feature: -------------------------------------------------------------------------------- 1 | Added 2025-2026 fiscal quarters to the valid choices for Proactive Disclosure schemas. -------------------------------------------------------------------------------- /changes/1575.changes: -------------------------------------------------------------------------------- 1 | The `place_of_publication` and `geographic_region` fields now render as Select2 fields. -------------------------------------------------------------------------------- /changes/1599.b.changes: -------------------------------------------------------------------------------- 1 | Moved inline styles and JS attributes to classes and event listeners respectfully. -------------------------------------------------------------------------------- /changes/1608.bugfix: -------------------------------------------------------------------------------- 1 | Fixed an issue with the Admin Publish Workflow page not rendering paging links properly. -------------------------------------------------------------------------------- /changes/0018.hotfix: -------------------------------------------------------------------------------- 1 | Extend the Adobe Analytics cookie setting to sanitize `javascript:void(0);` href attributes. -------------------------------------------------------------------------------- /changes/1494.removal: -------------------------------------------------------------------------------- 1 | Remove alert about contracts proactive publication from the Registry login and home pages. -------------------------------------------------------------------------------- /changes/1558.changes: -------------------------------------------------------------------------------- 1 | Display resource format labels in the Additional Information section on Resource pages. 2 | -------------------------------------------------------------------------------- /changes/1588.changes: -------------------------------------------------------------------------------- 1 | Change the format of "name" field in the Travel and Hospitality Quarterly templates. 2 | -------------------------------------------------------------------------------- /changes/1612.changes: -------------------------------------------------------------------------------- 1 | Added `autocomplete=off` for password fields to secure fields for older browser architecture -------------------------------------------------------------------------------- /changes/1619.feature: -------------------------------------------------------------------------------- 1 | API Token Names have more rigorous validation to help protect the application and database. -------------------------------------------------------------------------------- /samples/dq170529a-eng.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/samples/dq170529a-eng.pdf -------------------------------------------------------------------------------- /samples/dq170529a-fra.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/samples/dq170529a-fra.pdf -------------------------------------------------------------------------------- /samples/dq170529b-eng.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/samples/dq170529b-eng.pdf -------------------------------------------------------------------------------- /samples/dq170529b-fra.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/samples/dq170529b-fra.pdf -------------------------------------------------------------------------------- /samples/dq170529c-eng.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/samples/dq170529c-eng.pdf -------------------------------------------------------------------------------- /samples/dq170529c-fra.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/samples/dq170529c-fra.pdf -------------------------------------------------------------------------------- /samples/dq170529d-eng.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/samples/dq170529d-eng.pdf -------------------------------------------------------------------------------- /samples/dq170529d-fra.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/samples/dq170529d-fra.pdf -------------------------------------------------------------------------------- /changes/0009.bugfix: -------------------------------------------------------------------------------- 1 | Fixed an issue with the Standard Service filter script not handling null `performance` fields. 2 | -------------------------------------------------------------------------------- /changes/1496.changes: -------------------------------------------------------------------------------- 1 | Money fields for PD types now get rounded to 2 decimals when inserting into the database. 2 | -------------------------------------------------------------------------------- /changes/1529.changes: -------------------------------------------------------------------------------- 1 | Added `--include-types` and `--exclude-types` options to the `delete-activities` command. 2 | -------------------------------------------------------------------------------- /changes/1554.feature: -------------------------------------------------------------------------------- 1 | Added more resource formats: 2 | 3 | - `BUFR` 4 | - `CAP` 5 | - `WATERML1` 6 | - `WATERML2` 7 | -------------------------------------------------------------------------------- /changes/1576.changes: -------------------------------------------------------------------------------- 1 | Updated the page title, stage/phase labels, and stage/phase buttons on the Dataset form pages. -------------------------------------------------------------------------------- /changes/1587.changes: -------------------------------------------------------------------------------- 1 | Add yearly quarters for 2025-2026 to the Departmental Audit Committee proactive publication 2 | -------------------------------------------------------------------------------- /changes/1615.changes: -------------------------------------------------------------------------------- 1 | NotAuthorized HTTP responses now have a status code of 404 instead of 403 for logged out users. -------------------------------------------------------------------------------- /ckanext/canada/tables/choices/yes_no.yaml: -------------------------------------------------------------------------------- 1 | 'N': 2 | en: "No" 3 | fr: Non 4 | 'Y': 5 | en: "Yes" 6 | fr: Oui 7 | -------------------------------------------------------------------------------- /docs/suggest-dataset-dfd.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/docs/suggest-dataset-dfd.vsdx -------------------------------------------------------------------------------- /changes/0010.hotfix: -------------------------------------------------------------------------------- 1 | Fixed Service Inventory `service_name` fields character limit increase to `350` at the DB level. 2 | -------------------------------------------------------------------------------- /changes/0011.changes: -------------------------------------------------------------------------------- 1 | Updated Service Inventory fields `volume_meeting_target` and `total_volume` from `int` to `bigint` 2 | -------------------------------------------------------------------------------- /changes/0012.hotfix: -------------------------------------------------------------------------------- 1 | Fixed a typo in the `originating_sector_fr` field example for Briefing Note Titles and Numbers. 2 | -------------------------------------------------------------------------------- /changes/1486.changes: -------------------------------------------------------------------------------- 1 | Updated the `CanadaSecurityPlugin` class for the improved frameworking from `ckanext-security`. 2 | -------------------------------------------------------------------------------- /changes/1493.feature: -------------------------------------------------------------------------------- 1 | Add translations for feature to validate password. The user password cannot be the same as username. -------------------------------------------------------------------------------- /changes/1500.feature: -------------------------------------------------------------------------------- 1 | Show password requirements for "Password" and "Confirm Password" fields on new user registration page. -------------------------------------------------------------------------------- /changes/1507.changes: -------------------------------------------------------------------------------- 1 | Enabling upload of the QPNOTES-nil.csv file now that there is nothing-to-report data for QPNOTES PDs. -------------------------------------------------------------------------------- /changes/1563.removal: -------------------------------------------------------------------------------- 1 | Move PCO sub-org migration scripts to https://github.com/open-data/data-ops/tree/main/pco/migrate 2 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/snippets/info.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block package_info %}{% endblock %} 4 | -------------------------------------------------------------------------------- /changes/0006.bugfix: -------------------------------------------------------------------------------- 1 | Contextual temporary database table `datastore_user` now only gets created if it does not already exist. 2 | -------------------------------------------------------------------------------- /changes/1483.bugfix: -------------------------------------------------------------------------------- 1 | Fixed inline colons for French in various templates. E.g. `Date Published:` -> `Date de publication :` 2 | -------------------------------------------------------------------------------- /changes/1523.changes: -------------------------------------------------------------------------------- 1 | Display resource metadata such as Language, Format etc. on the resource page under 'Additional Information'. -------------------------------------------------------------------------------- /changes/1524.changes: -------------------------------------------------------------------------------- 1 | The old GCPedia links now link to the Operations Guide. Text `GCPEDIA` changed to `Operations Guide`. 2 | -------------------------------------------------------------------------------- /changes/1532.changes: -------------------------------------------------------------------------------- 1 | TravelQ schema has additional `destination` fields added, along with validation for expected format. 2 | -------------------------------------------------------------------------------- /changes/1533.changes: -------------------------------------------------------------------------------- 1 | HospitalityQ schema has additional `vendor` fields added, along with validation for expected format. 2 | -------------------------------------------------------------------------------- /changes/1543.feature: -------------------------------------------------------------------------------- 1 | Allow remote DataStore sources. Allow domains with `ckanext.canada.datastore_source_domain_allow_list` 2 | -------------------------------------------------------------------------------- /changes/1553.b.feature: -------------------------------------------------------------------------------- 1 | Added the capability to set a search query to the PD DataTables with the URI parameter `dt_query` 2 | -------------------------------------------------------------------------------- /changes/1574.bugfix: -------------------------------------------------------------------------------- 1 | Fixed an issue with the User Activity template. Sysadmins can now easily navigate to a User's activity page. -------------------------------------------------------------------------------- /changes/1601.changes: -------------------------------------------------------------------------------- 1 | Modified French translation in the new user form for the password field. It was missing the length limit. -------------------------------------------------------------------------------- /changes/1637.feature: -------------------------------------------------------------------------------- 1 | New CLI command `export-pd-reporting-info` exports data publisher info for Proactive Disclosures into a CSV. -------------------------------------------------------------------------------- /ckanext/canada/templates/revision/read_base.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block package_social %}{% endblock %} 4 | 5 | -------------------------------------------------------------------------------- /changes/0014.changes: -------------------------------------------------------------------------------- 1 | Limit `datastore_search` with FTS searching with `ckanext.canada.max_ds_fts_rows` (default: `100,000` rows) 2 | -------------------------------------------------------------------------------- /changes/1513.changes: -------------------------------------------------------------------------------- 1 | Add an alert on login page for users to change password in order to comply with the new password requirements. -------------------------------------------------------------------------------- /changes/1514.feature: -------------------------------------------------------------------------------- 1 | Updated CKAN and Drupal ATI Search Solr configs and schemas to Solr 9 and CKAN 2.10 compatible versions. 2 | -------------------------------------------------------------------------------- /changes/1541.changes: -------------------------------------------------------------------------------- 1 | Code changes to handle the additions from [open-data/ckan:185](https://github.com/open-data/ckan/pull/185) 2 | -------------------------------------------------------------------------------- /changes/1569.changes: -------------------------------------------------------------------------------- 1 | Resource list sidebar now only shows 8 resources with a "Show more" button to display all the resources. 2 | -------------------------------------------------------------------------------- /changes/1573.a.changes: -------------------------------------------------------------------------------- 1 | Moved the validation for TravelQ `destination_` and `disclosure_group` fields to be on or after April 1st 2025. -------------------------------------------------------------------------------- /changes/1589.changes: -------------------------------------------------------------------------------- 1 | Switch HelpDesk email address from open-ouvert@tbs-sct.gc.ca to PortalSupport-Soutienportail@tbs-sct.gc.ca. 2 | -------------------------------------------------------------------------------- /changes/1477.changes: -------------------------------------------------------------------------------- 1 | New `canada_theme` plugin contains merged Internal and Public templates, assets, and new `is_registry` global. 2 | -------------------------------------------------------------------------------- /changes/1553.changes: -------------------------------------------------------------------------------- 1 | Aligned the Delete and Create PD view functions with new Recombinant code for improved constraint error messages. 2 | -------------------------------------------------------------------------------- /changes/1573.b.changes: -------------------------------------------------------------------------------- 1 | Moved the validation for HospitalityQ `disclosure_group` and `_attendee` fields to be on or after April 1st 2025. -------------------------------------------------------------------------------- /changes/1606.bugfix: -------------------------------------------------------------------------------- 1 | Resource format validator will now fallback to `other` if the guessed mimetype is not in the list of Scheming choices. -------------------------------------------------------------------------------- /changes/1621.feature: -------------------------------------------------------------------------------- 1 | Use the new `promise-download` CKAN JS module for DataStore Dump links for better UX with larger DataStore tables. -------------------------------------------------------------------------------- /changes/1623.changes: -------------------------------------------------------------------------------- 1 | OPEN-4268: Consistently display controlled list Y,N,NA options without labels for Service Inventory Excel template. -------------------------------------------------------------------------------- /changes/1503.a.changes: -------------------------------------------------------------------------------- 1 | Create and Update PD Record views will now log the fatal warnings with their tracebacks instead of eating errors. 2 | -------------------------------------------------------------------------------- /changes/1512.bugfix: -------------------------------------------------------------------------------- 1 | Bugfix for character encoding on title_en and title_fr columns on the Open Government Portal Department List dataset 2 | -------------------------------------------------------------------------------- /changes/1599.a.changes: -------------------------------------------------------------------------------- 1 | Loads image assets instead of `data:image` URIs for stricter Content-Security-Policy support. Saved SVG data as images. -------------------------------------------------------------------------------- /changes/1610.changes: -------------------------------------------------------------------------------- 1 | Display link for AI Strategy Implementation Tracker on homepage and main menu for users belonging to the TBS organization. -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/dot.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/validation_timestamp.html: -------------------------------------------------------------------------------- 1 | {{ h.render_datetime(data[field.field_name], with_hours=True) }} -------------------------------------------------------------------------------- /changes/0008.changes: -------------------------------------------------------------------------------- 1 | Proactive Disclosure `money` field values now always display as a money format in DataTables and Update Single Record form. 2 | -------------------------------------------------------------------------------- /changes/1485.changes: -------------------------------------------------------------------------------- 1 | Moved FAQ page content from Markdown files into a Jinja template. Moved the French translated strings into the PO file. 2 | -------------------------------------------------------------------------------- /changes/1521.feature: -------------------------------------------------------------------------------- 1 | Added additional Resource formats sprite sheet and added supported Resource formats: 2 | 3 | * FLV 4 | * MKV 5 | * MP4 6 | -------------------------------------------------------------------------------- /changes/1530.feature: -------------------------------------------------------------------------------- 1 | The number of resources per dataset can now be limited with the `ckanext.canada.max_resources_per_dataset` config option. 2 | -------------------------------------------------------------------------------- /changes/1628.changes: -------------------------------------------------------------------------------- 1 | Add the following fields to the `Edit Member` page under download CSV option: 2 | - Date created 3 | - Last active date 4 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/dot-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/dotted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/dotted.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/dot-blue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /changes/0005.bugfix: -------------------------------------------------------------------------------- 1 | Fixed the Openness Report script. Moved the code inside of the CKAN app context. Use the `ckan canada openness-report` command now. 2 | -------------------------------------------------------------------------------- /changes/1522.feature: -------------------------------------------------------------------------------- 1 | Added `PackageSync` model for the `package_sync` table which tracks the PortalUpdater process and saves the states for the packages. 2 | -------------------------------------------------------------------------------- /changes/1536.bugfix: -------------------------------------------------------------------------------- 1 | Add validation fields to info schema. 2 | Add missing translations for validation: 3 | - Validation timestamp 4 | - Validation status 5 | -------------------------------------------------------------------------------- /changes/1580.changes: -------------------------------------------------------------------------------- 1 | Now checks the subdomain for `registry` to see if the user is in the "Registry" instead of checking if `canada_internal` plugin is loaded. -------------------------------------------------------------------------------- /changes/1595.feature: -------------------------------------------------------------------------------- 1 | Add new template for AI Strategy Tracker proactive publication. Data to be collected only by TBS over a period of 2 fiscal years. 2 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/leaves/stars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/leaves/stars.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/stars/star0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/stars/star0.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/stars/star1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/stars/star1.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/stars/star2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/stars/star2.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/stars/star3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/stars/star3.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/stars/star4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/stars/star4.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/stars/star5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/stars/star5.png -------------------------------------------------------------------------------- /ckanext/canada/templates/security/emails/lockout_subject.txt: -------------------------------------------------------------------------------- 1 | Too many logins detected for / Trop de tentatives de connexion détectées à {{ site_title }} 2 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/canada_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/canada_default.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/dot-grey.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/leaves/onestar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/leaves/onestar.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/leaves/twostar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/leaves/twostar.png -------------------------------------------------------------------------------- /ckanext/canada/templates/footer.html: -------------------------------------------------------------------------------- 1 | 2 | {% snippet 'snippets/cdts/footer.html' %} 3 | 4 | {% block footer_debug %}{% endblock %} 5 | -------------------------------------------------------------------------------- /changes/1480.b.feature: -------------------------------------------------------------------------------- 1 | Use the WET JS Builder to comply with the CDTS templates. Updated the error template. The Registry now uses the WET Application templates. 2 | -------------------------------------------------------------------------------- /changes/1489.bugfix: -------------------------------------------------------------------------------- 1 | Trim Proactive Disclosure text fields to 28kB for Solr record indexing. This affects PD types that do not use the Advanced Search (Django) app. 2 | -------------------------------------------------------------------------------- /changes/1540.changes: -------------------------------------------------------------------------------- 1 | Updated description copy for Service Inventory `Fiscal Year` fields. Updated maximum characters for `Service Name` fields from `250` to `350`. 2 | -------------------------------------------------------------------------------- /changes/1618.feature: -------------------------------------------------------------------------------- 1 | Obfuscates email addresses rendered in HTML with entity code points. Helps prevent non-advanced Bots from crawling email addresses in HTML content. -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/leaves/fivestar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/leaves/fivestar.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/leaves/fourstar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/leaves/fourstar.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/leaves/threestar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/leaves/threestar.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/leaves/zerostar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/leaves/zerostar.png -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/select2x2_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/select2x2_white.png -------------------------------------------------------------------------------- /ckanext/canada/templates/tabledesigner/view_snippets/cra_business_number.html: -------------------------------------------------------------------------------- 1 | {% call dictionary_field(_('Format')) %} 2 | {{ _('9-digit number') }} 3 | {% endcall %} 4 | -------------------------------------------------------------------------------- /changes/1515.bugfix: -------------------------------------------------------------------------------- 1 | fix: datatables column headings missing spaces 2 | remove broken nbsp-replacement code instead of fixing 3 | (doesn't handle other whitespace characters) 4 | -------------------------------------------------------------------------------- /changes/1584.hotfix: -------------------------------------------------------------------------------- 1 | Now properly checks package permissions for the XLoader and Validation UI pieces, fixes Organization Members not being able to view Datasets and Resources. -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/form_snippets/portal_release_date.html: -------------------------------------------------------------------------------- 1 | {% if h.may_publish_datasets() %} 2 | {% include "scheming/form_snippets/date.html" %} 3 | {% endif %} 4 | -------------------------------------------------------------------------------- /changes/1528.changes: -------------------------------------------------------------------------------- 1 | Remove rebuilding the following searches from the Makefike: 2 | - reclassification 3 | - hospitalityq 4 | The above searches are now rebuilt using the Django search. -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include COPYING COPYING.fr 2 | include ckanext/canada/metadata_schema/schema.json 3 | recursive-include ckanext/canada/public * 4 | recursive-include ckanext/canada/templates * 5 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/tag_list.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% set _class = 'menu-horizontal margin-top-none' %} 4 | 5 | {% block tag_list_item_class %}button{% endblock %} 6 | -------------------------------------------------------------------------------- /ckanext/canada/templates/validation/validation_read.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block scripts %} 4 | {{ super() }} 5 | {% asset 'canada_internal/frictionless' %} 6 | {% endblock %} -------------------------------------------------------------------------------- /changes/1538.hotfix: -------------------------------------------------------------------------------- 1 | Fixed a reference assignment error in the deleting views code block of PortalUpdater. PortalUpdater will now give a system exit code 1 if there are any errors in the process. 2 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/sprite-resource-additional-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-data/ckanext-canada/HEAD/ckanext/canada/public/static/img/sprite-resource-additional-icons.png -------------------------------------------------------------------------------- /ckanext/canada/tests/samples/sample.csv: -------------------------------------------------------------------------------- 1 | date,temperature,place 2 | 2011-01-01,1,Galway 3 | 2011-01-02,-1,Galway 4 | 2011-01-03,0,Galway 5 | 2011-01-01,6,Berkeley 6 | ,,Berkeley 7 | 2011-01-03,5, 8 | -------------------------------------------------------------------------------- /changes/1579.changes: -------------------------------------------------------------------------------- 1 | Support email address is now configurable with `ckanext.canada.support_email_address`. Default `maintainer_email` is now configurable with `ckanext.canada.default_open_email_address` -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/follow_button.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block following_class %}btn btn-default{% endblock %} 4 | {% block unfollowing_class %}btn btn-default{% endblock %} 5 | -------------------------------------------------------------------------------- /changes/1545.changes: -------------------------------------------------------------------------------- 1 | Wrongdoing Search has been implemented on OC Search. For now, the Proactive Disclosure Makefile is being modified to rebuild both the Drupal and Django searches during the nightly rebuild. 2 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/activities/changed_datastore.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block message %} 4 | {# wrap in p from margin and font size #} 5 |

{{ super() }}

6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/activities/created_datastore.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block message %} 4 | {# wrap in p from margin and font size #} 5 |

{{ super() }}

6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/activities/deleted_datastore.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block message %} 4 | {# wrap in p from margin and font size #} 5 |

{{ super() }}

6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /changes/1518.changes: -------------------------------------------------------------------------------- 1 | Reclassification Search has been implemented on OC Search. For now, the Proactive Disclosure Makefile is being modified to rebuild both the Drupal and Django searches during the nightly rebuild. 2 | -------------------------------------------------------------------------------- /ckanext/canada/templates/datatables/datatables_form.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {%- block dict_field_label -%} 4 | {%- set label = 'label_' + h.lang() -%} 5 | {{ f.get('info', {})[label] }} 6 | {%- endblock -%} 7 | -------------------------------------------------------------------------------- /ckanext/canada/tests/samples/sample_with_empty_lines.csv: -------------------------------------------------------------------------------- 1 | date,temperature,place 2 | 2011-01-01,1,Galway 3 | 2011-01-02,-1,Galway 4 | 2011-01-03,0,Galway 5 | 2011-01-01,6,Berkeley 6 | ,, 7 | ,,Berkeley 8 | 2011-01-03,5, 9 | -------------------------------------------------------------------------------- /changes/1632.changes: -------------------------------------------------------------------------------- 1 | Added `--dataset-id` (`-D`) and `--ignore-hashes` (`-i`) options to the `portal_update` command. This is an interim fix to some DataStore tables not syncing to the Portal during the Post to Portal process. -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/dash.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/tests/samples/sample_with_extra_white_space.csv: -------------------------------------------------------------------------------- 1 | date,temperature,place 2 | 2011-01-01,1, Galway 3 | 2011-01-02,-1, Galway 4 | 2011-01-03,0, Galway 5 | 2011-01-01,6, Berkeley 6 | , ,Berkeley 7 | 2011-01-03,5, 8 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/check.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /changes/1482.bugfix: -------------------------------------------------------------------------------- 1 | Ignore the `metadata_modified` Resource field in the "Post to Portal" code. Fixing a major issue where a Dataset's `metadata_modified` field would be updated, and a lot of activities would be created on the Portal. 2 | -------------------------------------------------------------------------------- /changes/1599.feature: -------------------------------------------------------------------------------- 1 | Added functionality to define the `Content-Security-Policy` header in the Flask App instead of NGINX, allowing for script and style dynamic nonce generation. Configurable with `ckanext.canada.content_security_policy` -------------------------------------------------------------------------------- /ckanext/canada/templates/header.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block header_wrapper %} 4 |
5 | {% snippet 'snippets/cdts/header.html', breadcrumb_content=breadcrumb_content() %} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/chevron-down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/burger.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/check-green.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | factory-boy>=2 2 | mock 3 | importlib-metadata==4.11.4 4 | zipp==3.19.1 5 | beautifulsoup4==4.11.1 6 | pytest==7.4.4 7 | pytest-ckan 8 | pytest-cov==3.0.0 9 | coverage==7.7.1 10 | junitparser==3.2.0 11 | junit2html==31.0.2 -------------------------------------------------------------------------------- /changes/1556.changes: -------------------------------------------------------------------------------- 1 | Display errors on the Confirm Resource Delete page. Added new translations for nested resource validation errors. Adds a ckanext-scheming template for the nested resource validation errors to display field labels from the Schema. 2 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/burger-lite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/chevron-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/chevron-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/cdts/footer.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/snippets/placeholder.html: -------------------------------------------------------------------------------- 1 | {# 2 | blank to disable default gravatar. 3 | ckan.gravatar_default in DataGCCAPublic plugin class 4 | is always set to `disabled` so this template will 5 | always be used for user gravatars. 6 | #} 7 | -------------------------------------------------------------------------------- /changes/1508.bugfix: -------------------------------------------------------------------------------- 1 | The URL on resource pages shows English URL from cloudstorage for resources uploaded to the datastore. The immediate fix is to remove the URL since it is repetitive. This would not have any impact on UX because users can use the blue button to download resources. -------------------------------------------------------------------------------- /changes/1497.changes: -------------------------------------------------------------------------------- 1 | The Makefile no longer falls back to `/tmp` for the temporary directory. It will always use the `PD_TMP_DIRECTORY` or `TMPDIR` environment variables. You can now supply `tmpdir=/path/to/tmp/directory`. The Makefile will fail if no temporary directory is found. 2 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/base_form_page.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block primary_content_inner %} 4 | {% block form %} 5 |
6 | {{ form | safe }} 7 |
8 | {% endblock %} 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /changes/1622.changes: -------------------------------------------------------------------------------- 1 | AI Strategy YAML updates: 2 | - Increased character limit for description and progress fields from 1000 to 1500 characters. 3 | - Improved labels for activity choices based on input from the policy team. 4 | - Fixed ordering of primary keys to resolve the delete bug. 5 | -------------------------------------------------------------------------------- /ckanext/canada/assets/public/check_all.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('load', function(){ 2 | $(function () { 3 | $('#publish_all').on('click', function () { 4 | $('#publish_form').find(':checkbox').prop('checked', this.checked); 5 | }); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /ckanext/canada/assets/public/more_like_this.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('load', function(){ 2 | $( document ).on( "wb-ready.wb", function( event ) { 3 | $('#related_pkgs ul').removeClass('list-unstyled'); 4 | $('#related_pkgs li:gt(4)').remove(); 5 | }); 6 | }); 7 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/chevron-down-blue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/chevron-down-grey.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/snippets/dictionary_table.html: -------------------------------------------------------------------------------- 1 | 2 | {{ field.id }} 3 | {{ field.type }} 4 | {{ field.get('info', {}).get('label_' + h.lang()) }} 5 | {{ h.render_markdown(field.get('info', {}).get('notes_' + h.lang())) }} 6 | 7 | -------------------------------------------------------------------------------- /changes/1472.b.feature: -------------------------------------------------------------------------------- 1 | Recombinant (Proactive Disclosure) dataset types search pages need session to view on Registry. Following a direct link to a Recombinant dataset will redirect you to the correct Owner Organization for that type. The searches will redirect to the default Dataset search on Portal. 2 | -------------------------------------------------------------------------------- /ckanext/__init__.py: -------------------------------------------------------------------------------- 1 | # this is a namespace package 2 | try: 3 | import pkg_resources 4 | # type_ignore_reason: reportAttributeAccessIssue 5 | pkg_resources.declare_namespace(__name__) 6 | except ImportError: 7 | import pkgutil 8 | __path__ = pkgutil.extend_path(__path__, __name__) 9 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/edit_view.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block subtitle %} 4 | {{ super() }} 5 | {% if resource_view.get('canada_disabled_view') %} 6 | {{ _('Disabled') }} 7 | {% endif %} 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/canada_license.html: -------------------------------------------------------------------------------- 1 | {% set license = h.get_license(data.license_id) %} 2 | {% if h.lang() == 'fr' %} 3 | {{ license.title_fra }} 4 | {% else %} 5 | {{ license.title }} 6 | {% endif %} 7 | -------------------------------------------------------------------------------- /changes/1510.feature: -------------------------------------------------------------------------------- 1 | Re-enable service inventory in the Makefile. Search will continue to stay disabled at this time. 2 | Add filters for service inventory tables for populating the following fields: 3 | - num_applications_total 4 | - program_name_en and program_name_fr 5 | - performance 6 | - target_met 7 | -------------------------------------------------------------------------------- /changes/1591.changes: -------------------------------------------------------------------------------- 1 | Update ministers list after change of role by House of Commons website for Hon. Jill McKnight from Minister of Veterans Affairs to 2 | - Minister of Veterans Affairs 3 | - Associate Minister of National Defence. 4 | Update download_ministers script to ignore invalid positions such as "." 5 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/danger.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/form_snippets/ro_fluent_title.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | {{ h.scheming_language_text(data[field.field_name]) }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/filesize.html: -------------------------------------------------------------------------------- 1 |
{{ data[field.field_name]|filesizeformat }}  ({{ '{:,.0f}'.format(data[field.field_name]) }} bytes)
2 | -------------------------------------------------------------------------------- /ckanext/canada/tests/samples/sample_with_bad_ds_headers.csv: -------------------------------------------------------------------------------- 1 | date,_thisisnotallowed,thisheaderisgoingtobewaywaywaywaywaywaywaywaywaywaywaywaywaywaywaywaywaywaywaywaywaywaytolongforthedatastore 2 | 2011-01-01,1,Galway 3 | 2011-01-02,-1,Galway 4 | 2011-01-03,0,Galway 5 | 2011-01-01,6,Berkeley 6 | ,,Berkeley 7 | 2011-01-03,5, 8 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/close-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/data_img/modal-close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/snippets/share_widget.html: -------------------------------------------------------------------------------- 1 | {% block share_widget %} 2 | {% if not h.is_registry_domain() %} 3 |
4 |
5 | {% endif %} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/logout.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block primary_content %} 4 |
5 |
6 |

{% trans %}You are now logged out.{% endtrans %}

7 |
8 |
9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/form_snippets/ro_fluent_markdown.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | {{ h.render_markdown(h.scheming_language_text(data[field.field_name])) }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /ckanext/canada/templates/tabledesigner/view_snippets/province.html: -------------------------------------------------------------------------------- 1 | {% call dictionary_field(_('Reference')) %} 2 | {{ _('Canadian Provinces and Territories') }} 3 | {% endcall %} 4 | 5 | {% include 'tabledesigner/view_snippets/choice.html' %} 6 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/form_snippets/ro_select.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | {{ h.scheming_choices_label(h.scheming_field_choices(field), data[field.field_name]) }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/edit.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block secondary_content %}{% endblock %} 4 | 5 | {% block breadcrumb_content %} 6 |
  • {{ user_dict.display_name }}
  • 7 |
  • {{ _('Manage') }}
  • 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /ckanext/canada/assets/invitation-manager/webassets.yml: -------------------------------------------------------------------------------- 1 | css: 2 | output: invitation_manager/%(version)s_invitation_manager.css 3 | contents: 4 | - vendor/Overlay.css 5 | 6 | js: 7 | output: invitation_manager/%(version)s_invitation_manager.js 8 | contents: 9 | - vendor/Overlay.js 10 | - vendor/InvitationManager.js 11 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/package_list.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block package_list %} 4 | {% if packages %} 5 | 10 | {% endif %} 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /ckanext/canada/tables/choices/level_number.yaml: -------------------------------------------------------------------------------- 1 | "00": "00" 2 | "01": "01" 3 | "02": "02" 4 | "03": "03" 5 | "04": "04" 6 | "05": "05" 7 | "06": "06" 8 | "07": "07" 9 | "08": "08" 10 | "09": "09" 11 | "10": "10" 12 | "11": "11" 13 | "12": "12" 14 | "13": "13" 15 | "14": "14" 16 | "15": "15" 17 | "16": "16" 18 | "17": "17" 19 | "18": "18" 20 | "19": "19" 21 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/form_snippets/ro_date.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 |
    5 |
    6 | {% if data[field.field_name] %} 7 | {{ data[field.field_name].split()[0] }} 8 | {% endif %} 9 |
    10 |
    11 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/share_page.html: -------------------------------------------------------------------------------- 1 | {% block social %} 2 |
    3 |
    4 |

    5 | {% block social_nav %} 6 |

    7 | {% endblock %} 8 |

    9 |
    10 |
    11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /changes/1577.feature: -------------------------------------------------------------------------------- 1 | Improved the display of Resource Validation and XLoader badges to be more clear. Errors/failures will now display in semantic alert areas with a button link to go to the respective report. Successful and Processing badges will display as normal. The Frictionless report items will now be expanded by default, showing the user how to correct the problems in their data. -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/snippets/organization_list.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | {%- block organization_list -%} 3 |
    4 | {%- for organization in organizations -%} 5 | {%- snippet "organization/snippets/organization_item.html", organization=organization, position=loop.index -%} 6 | {%- endfor -%} 7 |
    8 | {%- endblock -%} 9 | -------------------------------------------------------------------------------- /changes/1600.changes: -------------------------------------------------------------------------------- 1 | Ensure the format_type attribute of Recombinant table fields is properly translated and displayed in the following areas for Proactive Disclosures (PD): 2 | - Reference tab on individual PD pages 3 | - Data dictionary for each PD 4 | - Resource page of combined PDs 5 | 6 | This addresses currently missing translations and improves consistency across PD-related interfaces. -------------------------------------------------------------------------------- /ckanext/canada/templates/text_view.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {%- block subtitle -%} 4 | {{- h.resource_view_meta_title(package=package, resource=resource, view=resource_view, is_subtitle=True) -}} 5 | {%- endblock -%} 6 | 7 | {% block adobe_analytics_creator %} 8 | {{ h.adobe_analytics_creator(organization=package.organization, package=package) }} 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /changes/1551.changes: -------------------------------------------------------------------------------- 1 | - Maintain only one ministers list for both Question Period Notes and Use of Administrative Aircraft. 2 | - Update ministers list to include Governor General choice 3 | - Remove aircraft ministers list 4 | - Update Aircraft PD template to use ministers list and add last updated date 5 | - Update QPNotes PD template to filter GG from the choices list and add last updated date 6 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/license.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block license_wrapper %} 4 |

    5 |

    13 |

    14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/edit_base.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% set user = g.userobj %} 4 | 5 | {% block subtitle %} 6 | {% if is_myself %} 7 | {{ _('Edit My Profile') }} 8 | {% else %} 9 | {{ _('Edit Profile') }} 10 | {% endif %} 11 | {% endblock %} 12 | 13 | {% block primary_content %} 14 | {% block primary_content_inner %}{% endblock %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /changes/1499.feature: -------------------------------------------------------------------------------- 1 | Add validation for no commas allowed to proactive publication reference number fields. 2 | The change applies to: 3 | - adminaircraft.yaml 4 | - ati.yaml 5 | - briefingt.yaml 6 | - consultations.yaml 7 | - contracts.yaml 8 | - grants.yaml 9 | - hospitalityq.yaml 10 | - qpnotes.yaml 11 | - reclassification.yaml 12 | - travelq.yaml 13 | - wrongdoing.yaml 14 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/validation_status.html: -------------------------------------------------------------------------------- 1 | {%- set messages = { 2 | 'success': _('Valid data'), 3 | 'failure': _('Invalid data'), 4 | 'error': _('Error during validation'), 5 | } 6 | -%} 7 | {%- if data[field.field_name] not in ['created', 'running'] -%} 8 | {{ messages.get(data[field.field_name], _('Data validation unknown')) }} 9 | {%- endif -%} 10 | -------------------------------------------------------------------------------- /ckanext/canada/tests/fixtures.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from ckan.lib import uploader 3 | 4 | 5 | @pytest.fixture 6 | def mock_uploads(ckan_config, monkeypatch, tmp_path): 7 | def mock_get_storage_path(): 8 | return str(tmp_path) 9 | monkeypatch.setitem(ckan_config, "ckan.storage_path", str(tmp_path)) 10 | monkeypatch.setattr(uploader, "get_storage_path", mock_get_storage_path) 11 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/list_inline.html: -------------------------------------------------------------------------------- 1 | {%- set values = data[field.field_name] -%} 2 | 3 | 10 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/api_tokens.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block page_heading %}{{ user_dict.display_name }} {{ g.template_title_delimiter }} {{ super() }}{% endblock %} 4 | 5 | {% block base_fields %} 6 |
    7 | {{ form.input('name', label=_('Name'), is_required=True, value=data.name, error=errors.name) }} 8 |
    9 | {% endblock base_fields %} 10 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/snippets/resource_view_embed.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {%- block subtitle -%} 4 | {{- h.resource_view_meta_title(package=package, resource=resource, view=resource_view, is_subtitle=True) -}} 5 | {%- endblock -%} 6 | 7 | {% block adobe_analytics_creator %} 8 | {{ h.adobe_analytics_creator(organization=package.organization, package=package) }} 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ckanapi>=2.1 2 | lxml 3 | geojson==2.3.0 4 | geomet==0.2.0.post2 5 | docopt 6 | pyyaml==6.0.1 7 | pytz 8 | babel 9 | rdflib-jsonld 10 | backports.ssl-match-hostname>=3.5.0.1 11 | configparser>=3.5.0 12 | openpyxl==2.6.4 13 | python-dateutil==2.8.2 # 2.9.0 breaks stuff in PY2 (March 1 2024) 14 | beautifulsoup4==4.11.1 15 | cryptography==45.0.7 16 | pydantic==2.10.6 17 | typing_extensions==4.12.2 -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/form_snippets/organization.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block organization_option %} 4 | {% set title = h.split_piped_bilingual_field(organization.title, h.lang())[:70] %} 5 | 6 | {% endblock %} 7 | 8 | {% block package_metadata_fields_visibility %}{% endblock %} 9 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/edit.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block breadcrumb_content_inner %} 4 | {%- set translated_title = h.get_translated(g.group_dict, 'title') -%} 5 |
  • {% link_for translated_title, named_route=group_type + '.read', id=g.group_dict.name %}
  • 6 |
  • {% link_for _('Manage'), named_route=group_type + '.edit', id=g.group_dict.name %}
  • 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /changes/1571.feature: -------------------------------------------------------------------------------- 1 | Upgraded DataTables JS contributed library and extensions to latest (as of 2025.03.27) for Recombinant previews. Added various UX improving features: 2 | 3 | - Bootstrap 5 theme for the DataTables; 4 | - Responsive View; 5 | - Improved i18n; 6 | - Fullscreen; 7 | - Editing in DataTables; 8 | - General improved functional JS code. 9 | 10 | Must use the option `ckanext.canada.enable_pd_datatable_editor` -------------------------------------------------------------------------------- /ckanext/canada/templates/package/new.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block subtitle %} 4 | {% if dataset_type == 'info' %} 5 | {{- _('Create an Open Information Asset') -}} 6 | {% elif dataset_type == 'dataset' %} 7 | {{- _('Create an Open Data Record') -}} 8 | {% else %} 9 | {{- h.humanize_entity_type('package', dataset_type, 'create title') or _('Create Dataset') -}} 10 | {% endif %} 11 | {% endblock %} -------------------------------------------------------------------------------- /changes/1505.changes: -------------------------------------------------------------------------------- 1 | - show title with truncated link text 2 | - show title in breadcrumbs 3 | - increase breadcrumb length to 80 for package and resource 4 | - increase title length from ckan's default 80 to 150 before truncating 5 | - use the breadcrumb trail guidance to not display the current page 6 | at the end of the breadcrumb trail (linked or unlinked) for the Portal only 7 | https://design.canada.ca/common-design-patterns/breadcrumb-trail.html 8 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/form_snippets/ro_org.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 |
    5 |
    6 | {% if data[field.field_name] %} 7 | {% set org = h.get_organization(data[field.field_name]) %} 8 | {{h.split_piped_bilingual_field(org.title or org.name, h.lang())}} 9 | {% endif %} 10 |
    11 |
    12 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/snippets/errors.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block errors_list %} 4 |
    5 |

    {{_('Errors in form')}}

    6 |

    {{ _('The form contains invalid entries:') }}

    7 | 12 |
    13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/manage_members.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block page_primary_action %} 4 | {{ super() }} 5 | {% if h.is_registry_domain() %} 6 | {% if h.check_access('organization_update', {'id': organization.id}) %} 7 | {% link_for _('CSV'), named_route='canada.organization_member_dump', id=organization.id, class_='btn btn-primary', icon='download' %} 8 | {% endif %} 9 | {% endif %} 10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /ckanext/canada/assets/public/i18n.js: -------------------------------------------------------------------------------- 1 | var i18n = { 2 | "OGSCart_empty": { 3 | "en": "Map Cart is Empty", 4 | "fr": "Le panier est vide" 5 | }, 6 | "OGSCart_full": { 7 | "en": "Map Cart is full", 8 | "fr": "Le panier est plein" 9 | }, 10 | "OGSCart_has": { 11 | "en": "Map Cart", 12 | "fr": "Le panier" 13 | }, 14 | "OGSCart_of": { 15 | "en": "of", 16 | "fr": "de" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ckanext/canada/templates/admin/snippets/package_item.html: -------------------------------------------------------------------------------- 1 | {% extends 'snippets/package_item.html' %} 2 | 3 | {% block resources_outer %} 4 | {{ super() }} 5 | {% if h.is_ready_to_publish(package) %} 6 |
    7 | 10 |
    11 | {% endif %} 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/stream.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block activity_stream %} 4 |
    5 |
    6 |
    7 |
    8 |

    {{ _("View the past 60 days of metadata activity and the past 150 days of DataStore activity.") }}

    9 |
    10 |
    11 |
    12 |
    13 | {{ super() }} 14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /changes/1342.changes: -------------------------------------------------------------------------------- 1 | Merge PD records of the following sub-organizations under PCO: 2 | 3 | - Deputy Prime Minister & Minister of Finance (dpm-vpm) 4 | - Intergovernmental Affairs (iga-aig) 5 | - Minister of Intergovernmental Affairs, Infrastructure & Communities (miga-maig) 6 | - Office of the Leader of the Government in the House of Commons (ghl-lgc) 7 | - Office of the Minister of Democratic Institutions (mdi-mid) 8 | - Quebec Lieutenant (ql-lq) 9 | - Special Representative for the Prairies (srp-rsp) 10 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/activity_item.html: -------------------------------------------------------------------------------- 1 |
  • 2 | {% if activity.is_new %} 3 | {{ _('New activity item') }} 4 | {% endif %} 5 | 6 | {{ h.literal(activity.msg.format(**activity.data)) }} 7 | {{ h.time_ago_from_timestamp(activity.timestamp) }} 8 |
  • 9 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | # .coveragerc 2 | [report] 3 | omit = 4 | */__init__.py 5 | ckanext/canada/tests/ 6 | ckanext/canada/migration/ 7 | ckanext/canada/i18n/ 8 | ckanext/canada/assets/ 9 | ckanext/canada/public/ 10 | ckanext/canada/strings.py 11 | ckanext/canada/extract.py 12 | bin/ 13 | build/ 14 | conf/ 15 | links/ 16 | node_modules/ 17 | docs/ 18 | samples/ 19 | ckanext_canada.egg-info/ 20 | changes/ 21 | .github/ 22 | .pytest_cache/ 23 | setup.py -------------------------------------------------------------------------------- /ckanext/canada/templates/xloader/resource_data.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block upload_ds_button %} 4 | {% if h.validation_status(resource_id=res.id) == 'success' %} 5 |
    6 | {{ h.csrf_input() }} 7 | 10 |
    11 | {% endif %} 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/snippets/data_api_button.html: -------------------------------------------------------------------------------- 1 | {% if resource.datastore_active %} 2 | {% set loading_text = _('Loading...') %} 3 | {% set api_info_url = h.url_for('api.snippet', ver=1, snippet_path='api_info.html', resource_id=resource.id, api_version=3) %} 4 |  {{ _('Data API') }} 5 | {% endif %} 6 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - "*/__init__.py" 3 | - "ckanext/canada/tests/" 4 | - "ckanext/canada/migration/" 5 | - "ckanext/canada/i18n/" 6 | - "ckanext/canada/assets/" 7 | - "ckanext/canada/public/" 8 | - "ckanext/canada/strings.py" 9 | - "ckanext/canada/extract.py" 10 | - "bin/" 11 | - "build/" 12 | - "conf/" 13 | - "links/" 14 | - "node_modules/" 15 | - "docs/" 16 | - "samples/" 17 | - "ckanext_canada.egg-info/" 18 | - "changes/" 19 | - ".github/" 20 | - ".pytest_cache/" 21 | - "setup.py" -------------------------------------------------------------------------------- /bin/resource_urls.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import ckanapi 4 | import sys 5 | import time 6 | 7 | retries = 0 8 | while retries < 5: 9 | try: 10 | source = ckanapi.RemoteCKAN(sys.argv[1]) 11 | pkg = source.action.package_show(id=sys.argv[2]) 12 | print(' '.join([r['url'] for r in pkg.get('resources', []) 13 | if r['url'].endswith('.csv')])) 14 | sys.exit(0) 15 | except ckanapi.errors.CKANAPIError: 16 | retries += 1 17 | time.sleep(8) 18 | sys.exit(-1) 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ckanext_canada.egg-info 2 | *.pyc 3 | .project 4 | .pydevproject 5 | build 6 | dist 7 | *.swp 8 | development.ini 9 | .DS_Store 10 | .idea 11 | .eggs/** 12 | 13 | *.prefs 14 | ckan.log 15 | links/ckan 16 | links/ckanext 17 | links/test-core.ini 18 | links/who.ini 19 | ckanext/canada/templates/public/snippets/site_message_* 20 | ckanext/canada/download/*.jsonl 21 | **.mo 22 | *.xcf 23 | node_modules/** 24 | 25 | junit 26 | htmlcov/** 27 | .coverage 28 | .cache 29 | .bash_history 30 | .gitconfig 31 | .npm 32 | .test_durations 33 | .mypy_cache -------------------------------------------------------------------------------- /ckanext/canada/tables/choices/year.yaml: -------------------------------------------------------------------------------- 1 | # years for use in drop-downs on recombinant templates 2 | 3 | 2020: "2020" 4 | 2019: "2019" 5 | 2018: "2018" 6 | 2017: "2017" 7 | 2016: "2016" 8 | 2015: "2015" 9 | 2014: "2014" 10 | 2013: "2013" 11 | 2012: "2012" 12 | 2011: "2011" 13 | 2010: "2010" 14 | 2009: "2009" 15 | 2008: "2008" 16 | 2007: "2007" 17 | 2006: "2006" 18 | 2005: "2005" 19 | 2004: "2004" 20 | 2003: "2003" 21 | 2002: "2002" 22 | 2001: "2001" 23 | 2000: "2000" 24 | 1999: "1999" 25 | 1998: "1998" 26 | 1997: "1997" 27 | 1996: "1996" 28 | 1995: "1995" 29 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/snippets/helper.html: -------------------------------------------------------------------------------- 1 |
    2 |
     {{ _('What are Organizations?') }}
    3 |
    4 | {% trans %} 5 | CKAN Organizations are used to create, manage and publish collections 6 | of datasets. Users can have different roles within an Organization, 7 | depending on their level of authorisation to create, edit and publish. 8 | {% endtrans %} 9 |
    10 |
    11 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/email_with_parameters.html: -------------------------------------------------------------------------------- 1 | {% set page_url = h.url_for('dataset.read', id=data['id'], qualified=True) %} 2 | {{ 3 | h.mail_to_with_params(email_address=data[field.field_name], 4 | name=data[field.display_email_name_field] if field.display_email_name_field and data[field.display_email_name_field] 5 | else data[field.field_name], 6 | subject=h.get_translated(data, 'title'), 7 | body=_('The following is a question related to the record {url} found on {site}').format(url=page_url, site=h.portal_url())) 8 | }} 9 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/view_edit_base.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block content_action %} 4 | {%- link_for _('All views'), named_route=pkg.type ~ '_resource.views', id=pkg.name, resource_id=res.id, class_='btn btn-default', icon='arrow-left' -%} 5 | {% if res %} 6 | {%- set url = h.url_for(pkg.type ~ '_resource.read', id=pkg.name, resource_id=res.id) ~ '?view_id=' ~ resource_view.id -%} 7 | {{ _('View view') }} 8 | {% endif %} 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /ckanext/canada/tables/choices/online_service_yes_no.yaml: -------------------------------------------------------------------------------- 1 | 'NA': 2 | en: N/A (This interaction point is not applicable to the service) 3 | fr: S.O. (Ce point d'interaction ne s'applique pas au service) 4 | 'N': 5 | en: No (This interaction point is applicable to the service but is not currently online) 6 | fr: Non (Ce point d'interaction s'applique au service, mais il n'est pas en ligne présentement) 7 | 'Y': 8 | en: Yes (This interaction point is applicable to the service and is online) 9 | fr: Oui (Ce point d'interaction s'applique au service et est en ligne) 10 | -------------------------------------------------------------------------------- /ckanext/canada/templates/admin/search_rebuild.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block secondary_help %} 4 |
    5 |
    6 |  {{ _('Why re-index?') }} 7 |
    8 |
    9 |

    {{ _('The SOLR index is used for searching datasets and search facets. In the case that some datasets are not showing in the search or a search facet is not working, you can try to re-index the site.') }}

    10 |
    11 |
    12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | group: deprecated-2017Q4 3 | language: python 4 | sudo: required 5 | python: 6 | - "2.7" 7 | env: 8 | global: 9 | - CKAN_POSTGRES_DB=ckan_test 10 | - CKAN_POSTGRES_USER=ckan_default 11 | - CKAN_POSTGRES_PWD=pass 12 | - CKAN_DATASTORE_POSTGRES_DB=datastore_test 13 | - CKAN_DATASTORE_POSTGRES_WRITE_USER=ckan_default 14 | - CKAN_DATASTORE_POSTGRES_READ_USER=datastore_default 15 | - CKAN_DATASTORE_POSTGRES_READ_PWD=pass 16 | matrix: 17 | - PGVERSION=9.6 18 | install: ./bin/travis-install 19 | script: ./bin/travis-script 20 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/activity_stream.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block subtitle %} 4 | {{ user.display_name }} 5 | {% endblock %} 6 | 7 | {% block page_heading %} 8 | {{ super.super() }} 9 | {% endblock %} 10 | 11 | {% block primary_content_inner %} 12 |

    {{ _('Activity Stream') }}

    13 | {% snippet 'snippets/stream.html', activity_stream=activity_stream, id=id, object_type='user' %} 14 | {% snippet 'snippets/pagination.html', newer_activities_url=newer_activities_url, older_activities_url=older_activities_url %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/credit_name.html: -------------------------------------------------------------------------------- 1 | {% set fields = data[field.field_name] %} 2 | 3 | {% block subfield_display %} 4 | 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ckanext-canada", 3 | "version": "1.0.0", 4 | "description": "CKAN Canada Plugin", 5 | "dependencies": {}, 6 | "devDependencies": { 7 | "pyright": "1.1.386" 8 | }, 9 | "scripts": {}, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/open-data/ckanext-canada.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/open-data/ckanext-canada/issues" 19 | }, 20 | "homepage": "https://github.com/open-data/ckanext-canada#readme" 21 | } 22 | -------------------------------------------------------------------------------- /ckanext/canada/tables/choices/gregor_month.yaml: -------------------------------------------------------------------------------- 1 | '01': 2 | en: January 3 | fr: janvier 4 | '02': 5 | en: February 6 | fr: février 7 | '03': 8 | en: March 9 | fr: mars 10 | '04': 11 | en: April 12 | fr: avril 13 | '05': 14 | en: May 15 | fr: mai 16 | '06': 17 | en: June 18 | fr: juin 19 | '07': 20 | en: July 21 | fr: juillet 22 | '08': 23 | en: August 24 | fr: août 25 | '09': 26 | en: September 27 | fr: septembre 28 | '10': 29 | en: October 30 | fr: octobre 31 | '11': 32 | en: November 33 | fr: novembre 34 | '12': 35 | en: December 36 | fr: décembre 37 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/snippets/api_token_list.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block token_cell_actions %} 4 | 5 | {% set action = h.url_for("user.api_token_revoke", id=user['name'], jti=token['id']) %} 6 |
    7 | {{ h.csrf_input() }} 8 | 11 |
    12 | 13 | {% endblock token_cell_actions %} 14 | -------------------------------------------------------------------------------- /ckanext/canada/templates/datastore/snippets/dictionary_view.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block dictionary_field_extras %} 4 | {# we save _en and _fr, not _translated_ #} 5 | {# so get_translated will not work for our data dictionary fields. #} 6 | {{ super() }} 7 | {% call dictionary_field(_('Label')) %} 8 | {{ field.get('info', {}).get('label_' ~ h.lang(), '') }} 9 | {% endcall %} 10 | {% call dictionary_field(_('Description')) %} 11 | {{ h.render_markdown(field.get('info', {}).get('notes_' ~ h.lang(), '')) }} 12 | {% endcall %} 13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/resource_edit.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block subtitle %}{{ _('Edit') }} - 4 | {{ h.get_translated(res, 'name') }} - 5 | {{ h.get_translated(pkg, 'title') }} 6 | {% endblock %} 7 | 8 | {% block primary_content_inner %} 9 |

    10 | 13 |

    14 | {% block form %}{{ super() }}{% endblock %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/request_reset.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block primary_content %} 4 |
    5 |
    6 | {% block primary_content_inner %} 7 | {% block form %} 8 | {{ super() }} 9 | {% endblock %} 10 | {% endblock %} 11 |
    12 |
    13 | {% endblock %} 14 | 15 | {% block secondary_content %}{% endblock %} 16 | 17 | {% block help %} 18 |
    19 | {{ self.help_inner() }} 20 |
    21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/form_snippets/ro_fluent_tags.html: -------------------------------------------------------------------------------- 1 | {# slight abuse of scheming_language_text for selecting the desired language version #} 2 | {%- set value = h.scheming_language_text(data[field.field_name]) -%} 3 |
    4 |
    5 | 6 |
    7 |
    8 | {% block tag_list %} 9 |
      10 | {% for tag in value %} 11 |
    • {{ tag|truncate(22) }}
    • 12 | {% endfor %} 13 |
    14 | {% endblock %} 15 |
    16 |
    17 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/edit.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {%- block subtitle %} 4 | {{ _('Edit') }} {{ pkg.title or pkg.name }} 5 | {% endblock -%} 6 | 7 | {% block page_heading %} 8 | {{ _('Edit') }} {{ pkg.title or pkg.name }} 9 | {% endblock %} 10 | 11 | {% block primary_content %} 12 |
    13 |
    14 | {{ super() }} 15 |
    16 |
    17 | {% endblock %} 18 | 19 | {% block secondary_content %} 20 | {% if pkg_dict and pkg_dict.resources %} 21 | {% snippet "package/snippets/resources.html", pkg=pkg %} 22 | {% endif %} 23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /.github/workflows/flake8.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: [workflow_call, workflow_dispatch] 3 | 4 | permissions: 5 | contents: read 6 | 7 | jobs: 8 | lint: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-python@v2 13 | with: 14 | python-version: '3.9' 15 | - name: Install requirements 16 | run: pip install flake8 pycodestyle 17 | - name: Check syntax 18 | # Stop the build if there are Python syntax errors or undefined names 19 | run: flake8 --show-source 20 | 21 | - name: Warnings 22 | run: flake8 23 | -------------------------------------------------------------------------------- /ckanext/canada/assets/datatables/webassets.yml: -------------------------------------------------------------------------------- 1 | css: 2 | contents: 3 | - canada_datatables.css 4 | output: canada_datatables/%(version)s_canada_datatables.css 5 | 6 | pd_datatable_css: 7 | contents: 8 | - pd_datatable.css 9 | output: canada_datatables/%(version)s_pd_datatable.css 10 | 11 | js: 12 | contents: 13 | - canada_datatables.js 14 | output: canada_datatables/%(version)s_canada_datatables.js 15 | 16 | pd_datatable_js: 17 | contents: 18 | - pd_datatables.js 19 | extra: 20 | preload: 21 | - base/main # need ckan JS and jQuery 22 | output: canada_datatables/%(version)s_pd_datatables.js -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/br_multiple_choice.html: -------------------------------------------------------------------------------- 1 | {%- set values = data[field.field_name] -%} 2 | {%- set labels = [] -%} 3 | 4 | {%- for choice in field.choices -%} 5 | {%- if choice.value in values -%} 6 | {%- do labels.append(h.scheming_language_text(choice.label)) -%} 7 | {%- endif -%} 8 | {%- endfor -%} 9 | 10 | {%- if labels|length == 1 -%} 11 | {{ labels[0] }} 12 | {%- else -%} 13 | {%- if field.get('sorted_choices') -%} 14 | {%- set labels = labels|sort -%} 15 | {%- endif -%} 16 | {%- for label in labels -%} 17 | {{ label }}
    18 | {%- endfor -%} 19 | {%- endif -%} 20 | -------------------------------------------------------------------------------- /ckanext/canada/migration/canada_public/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /ckanext/canada/schemas/validation_placeholder_presets.yaml: -------------------------------------------------------------------------------- 1 | scheming_presets_version: 1 2 | about: Placeholder presets to allow schema to work without ckanext-validation on portal 3 | about_url: '' 4 | presets: 5 | - preset_name: resource_schema 6 | values: 7 | validators: ignore_missing scheming_valid_json_object 8 | output_validators: scheming_load_json 9 | display_snippet: json.html 10 | - preset_name: validation_options 11 | values: 12 | validators: ignore_missing scheming_valid_json_object 13 | output_validators: scheming_load_json 14 | display_snippet: json.html 15 | - preset_name: hidden_in_form 16 | values: {} 17 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/read.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% set client_lang = h.lang() %} 4 | 5 | {% block page_primary_action %} 6 | {% if group_dict.state == "deleted" %} 7 |
    8 |

    {{ _('This organization has been deleted and is no longer accessible') }}.

    9 |
    10 | {% endif %} 11 | {{ super() }} 12 | {% endblock %} 13 | 14 | {% block organization_facets %} 15 | {% snippet 'snippets/dataset_facets.html', extras={'id': group_dict.name}, show_org_facet=false, search_facets=search_facets, facet_titles=facet_titles %} 16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/about.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block subtitle %}{{ super.super() }}{% endblock %} 4 | {% block subtitle_2 %}{{ _('About') }}{% endblock %} 5 | {% block page_heading %}{{ super.super() }}{% endblock %} 6 | 7 | {% block primary_content_inner %} 8 | {% block organization_description %} 9 | {% if g.group_dict.description %} 10 | {{ h.render_markdown(g.group_dict.description) }} 11 | {% endif %} 12 | {% endblock %} 13 | {% block organization_extras %} 14 | {% snippet 'snippets/additional_info.html', extras = h.sorted_extras(g.group_dict.extras) %} 15 | {% endblock %} 16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/search_rebuild.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block secondary_help %} 4 |
    5 |
    6 |  {{ _('Why re-index?') }} 7 |
    8 |
    9 |

    {{ _("If you update an Organization's title or name, it's datasets in the SOLR Index will not have the new title or name.") }}

    10 |

    {{ _("To solve this, you can re-index all of the Organization's records in a background job.") }}

    11 |
    12 |
    13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /ckanext/canada/templates/admin/trash.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block primary_content_inner %} 4 |
    5 | {{ super() }} 6 |
    7 | {% endblock %} 8 | 9 | {% block secondary_content %} 10 |
    11 |
    12 |

    13 |  {{ _('Trash') }} 14 |

    15 |
    16 |
    17 |

    {{ _('Purge deleted datasets, organizations or groups forever and irreversibly.') }}

    18 |
    19 |
    20 | {% endblock %} 21 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/snippets/resource_view.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {%- block title -%} 4 | {{- h.resource_view_meta_title(package=package, resource=resource, view=resource_view) -}} 5 | {%- endblock -%} 6 | 7 | {% block adobe_analytics_creator %} 8 | {{ h.adobe_analytics_creator(organization=package.organization, package=package) }} 9 | {% endblock %} 10 | 11 | {% block description %} 12 |

    13 | {%- if h.lang() == 'fr' -%} 14 | {{ h.render_markdown(resource_view['description_fr']) }} 15 | {%- else -%} 16 | {{ h.render_markdown(resource_view['description']) }} 17 | {%- endif -%} 18 |

    19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /bin/filter/filter_dac.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for dac.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | 14 | def main(): 15 | reader = csv.DictReader(sys.stdin) 16 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 17 | writer = csv.DictWriter(sys.stdout, outnames) 18 | writer.writeheader() 19 | for row in reader: 20 | try: 21 | for rem in REMOVE_COLUMNS: 22 | del row[rem] 23 | writer.writerow(row) 24 | except ValueError: 25 | pass 26 | 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/organization/group_form.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block save_text %} 4 | {%- if action == "edit" -%} 5 | {%- if 'humanize_entity_type' in h -%} 6 | {{ h.humanize_entity_type('organization', group_type, 'update label') or _('Update Organization') }} 7 | {%- else -%} 8 | {{ _('Update Organization') }} 9 | {%- endif -%} 10 | {%- else -%} 11 | {%- if 'humanize_entity_type' in h -%} 12 | {{ h.humanize_entity_type('organization', group_type, 'create label') or _('Create Organization') }} 13 | {%- else -%} 14 | {{ _('Create Organization') }} 15 | {%- endif -%} 16 | {%- endif -%} 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /bin/filter/filter_contracts.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for contracts.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | 14 | def main(): 15 | reader = csv.DictReader(sys.stdin) 16 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 17 | writer = csv.DictWriter(sys.stdout, outnames) 18 | writer.writeheader() 19 | for row in reader: 20 | try: 21 | for rem in REMOVE_COLUMNS: 22 | del row[rem] 23 | writer.writerow(row) 24 | except ValueError: 25 | pass 26 | 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /bin/filter/filter_qpnotes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for qpnotes.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | 14 | def main(): 15 | reader = csv.DictReader(sys.stdin) 16 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 17 | writer = csv.DictWriter(sys.stdout, outnames) 18 | writer.writeheader() 19 | for row in reader: 20 | try: 21 | for rem in REMOVE_COLUMNS: 22 | del row[rem] 23 | writer.writerow(row) 24 | except ValueError: 25 | pass 26 | 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /bin/user_list_filter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | throw away all parts of an user that we don't want to propagate 5 | to another ckan instance. 6 | 7 | Usage: 8 | 9 | ckanapi dump users --all -r http://registry.data.gc.ca | 10 | bin/user_list_filter.py > users.jsonl 11 | """ 12 | 13 | import sys 14 | import json 15 | 16 | for line in sys.stdin.readlines(): 17 | o = json.loads(line) 18 | if o["display_name"] == 'visitor': 19 | continue 20 | print(json.dumps({ 21 | "id": o["id"], 22 | "display_name": o["display_name"], 23 | "fullname": o["fullname"], 24 | "name": o["name"], 25 | "sysadmin": o["sysadmin"], 26 | })) 27 | -------------------------------------------------------------------------------- /bin/filter/filter_contractsa.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for contractsa.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | 14 | def main(): 15 | reader = csv.DictReader(sys.stdin) 16 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 17 | writer = csv.DictWriter(sys.stdout, outnames) 18 | writer.writeheader() 19 | for row in reader: 20 | try: 21 | for rem in REMOVE_COLUMNS: 22 | del row[rem] 23 | writer.writerow(row) 24 | except ValueError: 25 | pass 26 | 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /bin/filter/filter_experiment.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for experiment.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | 14 | def main(): 15 | reader = csv.DictReader(sys.stdin) 16 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 17 | writer = csv.DictWriter(sys.stdout, outnames) 18 | writer.writeheader() 19 | for row in reader: 20 | try: 21 | for rem in REMOVE_COLUMNS: 22 | del row[rem] 23 | writer.writerow(row) 24 | except ValueError: 25 | pass 26 | 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /bin/filter/filter_wrongdoing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for wrongdoing.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | 14 | def main(): 15 | reader = csv.DictReader(sys.stdin) 16 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 17 | writer = csv.DictWriter(sys.stdout, outnames) 18 | writer.writeheader() 19 | for row in reader: 20 | try: 21 | for rem in REMOVE_COLUMNS: 22 | del row[rem] 23 | writer.writerow(row) 24 | except ValueError: 25 | pass 26 | 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/activity_stream.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block subtitle %}{{ super.super() }}{% endblock %} 4 | {% block subtitle_2 %}{{ _('Activity Stream') }}{% endblock %} 5 | {% block page_heading %}{{ super() }}{% endblock %} 6 | 7 | {% block primary_content_inner %} 8 | {% block activity_stream %} 9 |
    10 | 11 |  {{ _('Atom Feed') }} 12 | 13 |
    14 | {% snippet 'snippets/stream.html', activity_stream=activity_stream %} 15 | {% endblock %} 16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/dashboard_datasets.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block page_primary_action %} 4 | {% if not h.is_registry_domain() %} 5 | {{ super() }} 6 | {% endif %} 7 | {% endblock %} 8 | 9 | {% block subtitle %} 10 | {{ _('My Records') }} 11 | {% endblock %} 12 | 13 | {% block breadcrumb_content %} 14 | {{ super() }} 15 |
  • {% link_for _('My Records'), named_route='dashboard.datasets' %}
  • 16 | {% endblock %} 17 | 18 | {% block page_heading %} 19 | {{ _('Dashboard') }} - {{ _('My Records') }} 20 | {% endblock %} 21 | 22 | {% block primary_content_inner %} 23 |
    24 | {{ super() }} 25 |
    26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /bin/filter/filter_contracts_nil.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for contracts-nil.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | 14 | def main(): 15 | reader = csv.DictReader(sys.stdin) 16 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 17 | writer = csv.DictWriter(sys.stdout, outnames) 18 | writer.writeheader() 19 | for row in reader: 20 | try: 21 | for rem in REMOVE_COLUMNS: 22 | del row[rem] 23 | writer.writerow(row) 24 | except ValueError: 25 | pass 26 | 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /bin/filter/filter_current_consultations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Script that takes csv on stdin with Year, Month as the first two columns 5 | and outputs the header row and all rows within the past two years on stdout 6 | """ 7 | 8 | from datetime import datetime, timedelta 9 | import csv 10 | import sys 11 | 12 | 13 | def main(): 14 | current = datetime.today() - timedelta(365 * 2) 15 | 16 | reader = csv.DictReader(sys.stdin) 17 | writer = csv.DictWriter(sys.stdout, reader.fieldnames) 18 | writer.writeheader() 19 | for row in reader: 20 | if datetime.strptime(row['end_date'], '%Y-%m-%d') > current: 21 | writer.writerow(row) 22 | 23 | 24 | main() 25 | -------------------------------------------------------------------------------- /bin/filter/filter_grants.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for grants.csv and grants-nil.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | 14 | def main(): 15 | reader = csv.DictReader(sys.stdin) 16 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 17 | writer = csv.DictWriter(sys.stdout, outnames) 18 | writer.writeheader() 19 | for row in reader: 20 | try: 21 | for rem in REMOVE_COLUMNS: 22 | del row[rem] 23 | writer.writerow(row) 24 | except ValueError: 25 | pass 26 | 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/resource_relationship.html: -------------------------------------------------------------------------------- 1 | {# NOTE: Required for inline white spacing #} 2 | 3 | {% set fields = data[field.field_name] %} 4 | 5 | {% block subfield_display %} 6 |
    7 | {%- for field_data in fields -%} 8 |

      9 | {%- for subfield in field.repeating_subfields -%} 10 | {%- snippet 'scheming/snippets/display_field.html', 11 | field=subfield, 12 | data=field_data, 13 | entity_type=entity_type, 14 | object_type=object_type -%}  15 | {%- endfor -%} 16 |

    17 | {%- endfor -%} 18 |
    19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/snippets/socialmedia.html: -------------------------------------------------------------------------------- 1 | {% block ds_socialmedia %} 2 | {% if not h.is_registry_domain() %} 3 |
    4 | {% set pkg = pkg_dict %} 5 |
    {{ _('Have your say') }}
    6 | 13 |
    14 | {% endif %} 15 | {% endblock ds_socialmedia %} 16 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/dataset_relationship.html: -------------------------------------------------------------------------------- 1 | {# NOTE: Required for inline white spacing #} 2 | 3 | {% set fields = data[field.field_name] %} 4 | 5 | {% block subfield_display %} 6 |
    7 | {%- for field_data in fields -%} 8 |

      9 | {%- for subfield in field.repeating_subfields -%} 10 | {%- snippet 'scheming/snippets/display_field.html', 11 | field=subfield, 12 | data=field_data, 13 | entity_type=entity_type, 14 | object_type=object_type -%}  15 | {%- endfor -%} 16 |

    17 | {%- endfor -%} 18 |
    19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /ckanext/canada/assets/internal/recombinant_webform.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('load', function(){ 2 | $(document).ready(function() { 3 | 4 | let select2Fields = $('.recombinant-select2'); 5 | 6 | if( select2Fields.length > 0 ){ 7 | 8 | $(select2Fields).each(function(_index, _field){ 9 | 10 | // initialize select2 for recombinant-select2 11 | let idSuffix = $(_field).attr('id'); 12 | $(_field).select2({}); 13 | $(_field).parent() 14 | .children('#s2id_' + idSuffix) 15 | .addClass('conrtol-medium') 16 | .removeClass('form-control') 17 | .css({'display': 'block'}); 18 | 19 | }); 20 | 21 | } 22 | 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/display_snippets/fluent_tags.html: -------------------------------------------------------------------------------- 1 | {# slight abuse of scheming_language_text for selecting the desired language version #} 2 | {%- set value, machine_translated = h.language_text_t(data[field.field_name]) -%} 3 |
      4 | {%- for tag in value -%} 5 |
    • {{ tag }}
    • 6 | {%- endfor -%} 7 | {%- if machine_translated -%} 8 |
    • 9 | {%- endif -%} 10 |
    11 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/resources.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block subtitle %} 4 | {% if pkg.type != 'prop' %} 5 | {{ _('Resources') }} - {{ h.get_translated(pkg, 'title') }} 6 | {% endif %} 7 | {% endblock %} 8 | 9 | {% block primary_content_inner %} 10 | {% if pkg.type != 'prop' %} 11 |
    {{ super() }}
    12 | {% endif %} 13 | {% endblock %} 14 | 15 | {% block scripts %} 16 | 17 | {{ super() }} 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /ckanext/canada/templates/recombinant/snippets/service_delete_fk_error.html: -------------------------------------------------------------------------------- 1 | {% if ref_dataset['type'] in h.recombinant_get_types() %} 2 | {% set ref_table_link = h.url_for('recombinant.preview_table', resource_name=ref_resource['name'], owner_org=ref_dataset['organization']['name'], dt_query=dt_query) %} 3 | {% else %} 4 | {% set ref_table_link = h.url_for('resource.read', id=ref_dataset['id'], resource_id=ref_resource['id']) %} 5 | {% endif %} 6 | {% trans %} 7 | Cannot delete record(s) because the Fiscal Year, Service ID Number ({{ ref_values }}) is referenced in at least one Service Standards & Performance Results record. 8 | {% endtrans %} 9 | -------------------------------------------------------------------------------- /bin/filter/filter_reclassification.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for reclassification.csv and reclassification-nil.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | 14 | def main(): 15 | reader = csv.DictReader(sys.stdin) 16 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 17 | writer = csv.DictWriter(sys.stdout, outnames) 18 | writer.writeheader() 19 | for row in reader: 20 | try: 21 | for rem in REMOVE_COLUMNS: 22 | del row[rem] 23 | writer.writerow(row) 24 | except ValueError: 25 | pass 26 | 27 | 28 | main() 29 | -------------------------------------------------------------------------------- /ckanext/canada/templates/recombinant/snippets/service_std_upsert_fk_error.html: -------------------------------------------------------------------------------- 1 | {% if ref_dataset['type'] in h.recombinant_get_types() %} 2 | {% set ref_table_link = h.url_for('recombinant.preview_table', resource_name=ref_resource['name'], owner_org=ref_dataset['organization']['name'], dt_query=dt_query) %} 3 | {% else %} 4 | {% set ref_table_link = h.url_for('resource.read', id=ref_dataset['id'], resource_id=ref_resource['id']) %} 5 | {% endif %} 6 | {% trans %} 7 | Cannot create record ({{ ref_values }}) because the Service ID Number does not exist in the Service Identification Information & Metrics resource for that fiscal year. 8 | {% endtrans %} 9 | -------------------------------------------------------------------------------- /bin/filter/filter_aistrategy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for aistrategy.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | 'owner_org', 12 | 'owner_org_title', 13 | ] 14 | 15 | 16 | def main(): 17 | reader = csv.DictReader(sys.stdin) 18 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 19 | writer = csv.DictWriter(sys.stdout, outnames) 20 | writer.writeheader() 21 | for row in reader: 22 | try: 23 | for rem in REMOVE_COLUMNS: 24 | del row[rem] 25 | writer.writerow(row) 26 | except ValueError: 27 | pass 28 | 29 | 30 | main() 31 | -------------------------------------------------------------------------------- /bin/filter/filter_adminaircraft.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for adminaircraft.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | 'owner_org', 12 | 'owner_org_title' 13 | ] 14 | 15 | 16 | def main(): 17 | reader = csv.DictReader(sys.stdin) 18 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 19 | writer = csv.DictWriter(sys.stdout, outnames) 20 | writer.writeheader() 21 | for row in reader: 22 | try: 23 | for rem in REMOVE_COLUMNS: 24 | del row[rem] 25 | writer.writerow(row) 26 | except ValueError: 27 | pass 28 | 29 | 30 | main() 31 | -------------------------------------------------------------------------------- /ckanext/canada/tables/choices/fiscal_year.yaml: -------------------------------------------------------------------------------- 1 | # fiscal-year drop down 2 | 3 | 2029-2030: "2029-2030" 4 | 2028-2029: "2028-2029" 5 | 2027-2028: "2027-2028" 6 | 2026-2027: "2026-2027" 7 | 2025-2026: "2025-2026" 8 | 2024-2025: "2024-2025" 9 | 2023-2024: "2023-2024" 10 | 2022-2023: "2022-2023" 11 | 2021-2022: "2021-2022" 12 | 2020-2021: "2020-2021" 13 | 2019-2020: "2019-2020" 14 | 2018-2019: "2018-2019" 15 | 2017-2018: "2017-2018" 16 | 2016-2017: "2016-2017" 17 | 2015-2016: "2015-2016" 18 | 2014-2015: "2014-2015" 19 | 2013-2014: "2013-2014" 20 | 2012-2013: "2012-2013" 21 | 2011-2012: "2011-2012" 22 | 2010-2011: "2010-2011" 23 | 2009-2010: "2009-2010" 24 | 2008-2009: "2008-2009" 25 | 2007-2008: "2007-2008" 26 | 2006-2007: "2006-2007" 27 | 2005-2006: "2005-2006" 28 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/new_user_email.html: -------------------------------------------------------------------------------- 1 | A new account has been created in the Open Government registry. The account information is as follows: 2 | Username: {{ username }} 3 | Email: {{ email }} 4 | Phone: {{ phoneno }} 5 | Department: {{ dept }} 6 | 7 | To complete the registration, access the registry and link the account to their department. 8 | 9 | Un nouveau compte a été créé dans le registre de Gouvernement ouvert. Les renseignements concernant le compte sont les suivants : 10 | Nom d’utilisateur : {{ username }} 11 | Adresse électronique : {{ email }} 12 | Téléphone : {{ phoneno }} 13 | Ministère : {{ dept }} 14 | 15 | Pour compléter l’inscription, veuillez accéder au registre et relier le compte à son ministère. 16 | -------------------------------------------------------------------------------- /bin/filter/filter_disclosure_group.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Script that takes csv on stdin with an disclosure_group column 5 | and outputs the header row and all rows with disclosure_group 6 | != "MPSES" (Minister/Parliamentary Secretaries/Exempt Staff) 7 | """ 8 | 9 | import csv 10 | import sys 11 | 12 | FILTER_COLUMN = "disclosure_group" 13 | 14 | 15 | def main(): 16 | reader = csv.DictReader(sys.stdin) 17 | writer = csv.DictWriter(sys.stdout, reader.fieldnames) 18 | writer.writerow(dict(zip(reader.fieldnames, reader.fieldnames))) 19 | for row in reader: 20 | try: 21 | if row[FILTER_COLUMN] != 'MPSES': 22 | writer.writerow(row) 23 | except ValueError: 24 | pass 25 | 26 | 27 | main() 28 | -------------------------------------------------------------------------------- /ckanext/canada/templates/home/robots.txt: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block all_user_agents -%} 4 | {%- if h.is_registry_domain() -%} 5 | Disallow: / 6 | Crawl-Delay: 20 7 | {%- else -%} 8 | Disallow: /dataset/*/history 9 | Disallow: /en/dataset/*/history 10 | Disallow: /fr/dataset/*/history 11 | Disallow: /dataset/activity 12 | Disallow: /en/dataset/activity 13 | Disallow: /fr/dataset/activity 14 | Disallow: /organization/activity 15 | Disallow: /en/organization/activity 16 | Disallow: /fr/organization/activity 17 | Disallow: /user 18 | Disallow: /en/user 19 | Disallow: /fr/user 20 | Disallow: /feeds 21 | Disallow: /en/feeds 22 | Disallow: /fr/feeds 23 | Disallow: /api 24 | Disallow: /en/api 25 | Disallow: /fr/api 26 | Crawl-Delay: 20 27 | {%- endif -%} 28 | {%- endblock %} -------------------------------------------------------------------------------- /bin/user_import_filter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | throw away all parts of an user that we don't want to propagate 5 | to another ckan instance. 6 | 7 | Usage: 8 | 9 | ckanapi dump users --all | ./user_import_filter.py > users.jsonl 10 | """ 11 | 12 | import sys 13 | import json 14 | 15 | for line in sys.stdin.readlines(): 16 | o = json.loads(line) 17 | if o["display_name"] == 'visitor': 18 | continue 19 | print(json.dumps({ 20 | "id": o["id"], 21 | "apikey": o["apikey"], 22 | "display_name": o["display_name"], 23 | "email": o["email"], 24 | "fullname": o["fullname"], 25 | "name": o["name"], 26 | "password_hash": o["password_hash"], 27 | "sysadmin": o["sysadmin"], 28 | })) 29 | -------------------------------------------------------------------------------- /ckanext/canada/plugin/__init__.py: -------------------------------------------------------------------------------- 1 | from .dataset_plugin import CanadaDatasetsPlugin 2 | from .form_plugin import CanadaFormsPlugin 3 | from .internal_plugin import CanadaInternalPlugin 4 | from .public_plugin import CanadaPublicPlugin 5 | from .security_plugin import CanadaSecurityPlugin 6 | from .theme_plugin import CanadaThemePlugin 7 | 8 | # XXX Monkey patch to work around libcloud/azure 400 error on get_container 9 | try: 10 | import libcloud.common.azure 11 | libcloud.common.azure.API_VERSION = '2014-02-14' # type: ignore 12 | except ImportError: 13 | pass 14 | 15 | __all__ = [ 16 | 'CanadaDatasetsPlugin', 17 | 'CanadaFormsPlugin', 18 | 'CanadaInternalPlugin', 19 | 'CanadaPublicPlugin', 20 | 'CanadaSecurityPlugin', 21 | 'CanadaThemePlugin' 22 | ] 23 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/social.html: -------------------------------------------------------------------------------- 1 | {% set current_url = h.full_current_url() %} 2 | {% set pkg = pkg_dict %} 3 | 4 |
    5 | 13 |
    14 | -------------------------------------------------------------------------------- /ckanext/canada/assets/internal/registry_package_edit.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('load', function(){ 2 | $(document).ready(function() { 3 | // late init for date polyfill on scheming subforms 4 | $('fieldset[name=scheming-repeating-subfields]').on('scheming.subfield-group-init', function() { 5 | $(this).find('div.scheming-subfield-group').last() 6 | .find('span.wb-date-wrap.input-group').each(function(i, obj) { 7 | // discard broken polyfill 8 | var $clean = $(obj).clone().find('input').first() 9 | .removeClass('wb-init wb-date-inited picker-field'); 10 | $(obj).replaceWith($clean); 11 | }); 12 | // reapply polyfills, make sure to use wet's jQuery object 13 | $wetjq('input[type=date]').trigger('wb-init.wb-date'); 14 | }); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "page.html" %} 2 | 3 | {% block subtitle %}{{ _("Confirm Delete") }}{% endblock %} 4 | 5 | {% block primary_content_inner %} 6 |
    7 | {% block form %} 8 |

    {{ _('Are you sure you want to delete dataset - {name}?').format(name=pkg_dict.name) }}

    9 |

    10 |

    11 | {{ h.csrf_input() }} 12 | 13 | 14 |
    15 |

    16 | {% endblock %} 17 |
    18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /ckanext/canada/templates/security/emails/lockout_mail.txt: -------------------------------------------------------------------------------- 1 | Dear {{ user_name }}, 2 | 3 | We have detected an unusually large amount of login attempts for your account. 4 | As a security precaution, we have temporarily blocked logins with your credentials. 5 | If you have any questions please contact PortalSupport-Soutienportail@tbs.sct.gc.ca 6 | 7 | 8 | Message sent by {{ site_title }} ({{ site_url }}) 9 | 10 | 11 | 12 | {{ user_name }}, 13 | 14 | Nous avons détecté un nombre inhabituellement important de tentatives de connexion pour votre compte. 15 | Par mesure de sécurité, nous avons temporairement suspendu les connexions pour vos identifiants. 16 | Si vous avez des questions, veuillez vous adresser à PortalSupport-Soutienportail@tbs.sct.gc.ca 17 | 18 | 19 | Message envoyé par {{ site_title }} ({{ site_url }}) 20 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [extract_messages] 2 | keywords = translate isPlural 3 | add_comments = TRANSLATORS: 4 | output_file = ckanext/canada/i18n/ckanext-canada.pot 5 | width = 80 6 | 7 | [init_catalog] 8 | domain = ckanext-canada 9 | input_file = ckanext/canada/i18n/ckanext-canada.pot 10 | output_dir = ckanext/canada/i18n 11 | 12 | [update_catalog] 13 | domain = ckanext-canada 14 | input_file = ckanext/canada/i18n/ckanext-canada.pot 15 | output_dir = ckanext/canada/i18n 16 | 17 | [compile_catalog] 18 | domain = ckanext-canada 19 | directory = ckanext/canada/i18n 20 | statistics = true 21 | 22 | [flake8] 23 | max-complexity = 100 24 | max-line-length = 88 25 | count = true 26 | exit-zero = true 27 | statistics = true 28 | per-file-ignores = 29 | ckanext/canada/strings.py:E501 30 | ckanext/canada/tests/*:E501 31 | ckanext/canada/triggers.py:W605 32 | -------------------------------------------------------------------------------- /ckanext/canada/templates/admin/index.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block secondary_content %} 4 |
    5 |
    6 |

    7 |  {{ _('Administer CKAN') }} 8 |

    9 |
    10 |
    11 | {% set docs_url = "http://docs.ckan.org/en/{0}/sysadmin-guide.html".format(g.ckan_doc_version) %} 12 | {% trans %} 13 |

    As a sysadmin user you have full control over this CKAN instance. Proceed with care!

    14 |

    For guidance on using sysadmin features, see the CKAN sysadmin guide

    15 | {% endtrans %} 16 |
    17 |
    18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/base.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% set pkg = pkg_dict %} 4 | {% set client_lang = h.lang() %} 5 | 6 | {% block breadcrumb_content %} 7 | {% set pkg_url = h.url_for(pkg.type ~ '.read', id=pkg.id if is_activity_archive else pkg.name, **({'activity_id': request.args['activity_id']} if 'activity_id' in request.args else {})) %} 8 | {% if action != 'new' and pkg %} 9 | {% set dataset = h.get_translated(pkg, 'title') %} 10 | {% if h.is_registry_domain() and pkg.type in h.recombinant_get_types() %} 11 | {% set dataset = dataset ~ ' - ' ~ h.split_piped_bilingual_field(pkg.organization.title, h.lang()) %} 12 | {% endif %} 13 | {{ dataset|truncate(80) }} 14 | {% endif %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/form_snippets/repeating_subfields.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block repeating_panel_header %} 4 |
    5 | {{ h.scheming_language_text(field.repeating_label or field.label) }} {{ index1 }} 6 | {% block field_removal_button %} 7 | 8 | {% block delete_button_text %}{{ _('Remove') }}{% endblock %} 9 | 10 | {% endblock %} 11 |
    12 | {% endblock %} 13 | 14 | {% block add_button %} 15 | 16 | {% block add_button_text %} 17 |  {{ _('Add') }} 18 | {% endblock %} 19 | 20 | {% endblock %} 21 | 22 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "page.html" %} 2 | 3 | {% block subtitle %}{{ _("Confirm Delete") }}{% endblock %} 4 | 5 | {% block primary_content_inner %} 6 |
    7 | {% block form %} 8 |

    {{ _('Are you sure you want to delete user - {name}?').format(name=user_dict.name) }}

    9 |

    10 |

    11 | {{ h.csrf_input() }} 12 | 13 | 14 | 15 |
    16 |

    17 | {% endblock %} 18 |
    19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /ckanext/canada/tests/test_helpers.py: -------------------------------------------------------------------------------- 1 | from ckanext.canada.tests import CanadaTestBase 2 | 3 | from ckan.plugins.toolkit import h 4 | 5 | 6 | class TestCanadaLogic(CanadaTestBase): 7 | @classmethod 8 | def setup_class(self): 9 | """Method is called at class level once the class is instatiated. 10 | Setup any state specific to the execution of the given class. 11 | """ 12 | super(TestCanadaLogic, self).setup_class() 13 | 14 | def test_obfuscate_to_code_points(self): 15 | """ 16 | Obfuscating emails should return code point strings. 17 | """ 18 | email = 'example@example.com' 19 | expected_result = 'example@example.com' 20 | 21 | assert h.obfuscate_to_code_points(email) == expected_result 22 | -------------------------------------------------------------------------------- /ckanext/canada/strings.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copies of strings that need translations 3 | * in CKAN translation js building 4 | * 5 | * NOTE: CKAN builds JS i18n files off of .js file occurances 6 | * from the POT files. So they need to exist in JS extractions. 7 | **/ 8 | 9 | const _ = function(x){ return x; } 10 | 11 | _('Requesting Download...') // promise-download js module 12 | _('Downloads') // promise-download js module 13 | _('You have unfinished downloads in this page. Do you want to stop these downloads and leave the page?') // promise-download js module 14 | _('Downloading file...') // promise-download js module 15 | _('Successfully downloaded file') // promise-download js module 16 | _('Error downloading file, trying again through your browser') // promise-download js module 17 | _('Searching...') // autocomplete js module // TODO: remove after upstream contrib 18 | -------------------------------------------------------------------------------- /ckanext/canada/templates/macros/canada_activity.html: -------------------------------------------------------------------------------- 1 | {% macro resource_view_activity(activity_data, h) %} 2 | 3 | {{ h.link_to( 4 | activity_data.title if activity_data.title else h.resource_view_type(activity_data), 5 | h.url_for('dataset_resource.read', 6 | id=activity_data.package_id, 7 | resource_id=activity_data.resource_id) ~ '?view_id=' ~ activity_data.id) 8 | }} 9 | 10 | {% endmacro %} 11 | 12 | 13 | {% macro resource_data_dictionary_activity(activity, h) %} 14 | 15 | {{ h.link_to( 16 | h.get_translated(activity.data, 'name'), 17 | h.url_for('dataset_resource.read', 18 | id=activity.data.package_id, 19 | resource_id=activity.data.id) ~ '#data-dictionary') 20 | }} 21 | 22 | {% endmacro %} 23 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/confirm_delete_member.html: -------------------------------------------------------------------------------- 1 | {% extends "page.html" %} 2 | 3 | {% block subtitle %}{{ _("Confirm Delete") }}{% endblock %} 4 | 5 | {% block primary_content_inner %} 6 |
    7 | {% block form %} 8 |

    {{ _('Are you sure you want to delete member - {name}?').format(name=user_dict.name) }}

    9 |

    10 |

    11 | {{ h.csrf_input() }} 12 | 13 | 14 | 15 |
    16 |

    17 | {% endblock %} 18 |
    19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/deleted.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block primary_content_inner %} 4 |
    5 |

    6 | {{ _('This record has been removed from %s.') % _('Open.canada.ca') }} 7 |

    8 |
    9 |
    {{ _('Created On') }}
    10 |
    {{ h.date_str_to_datetime(created).strftime('%Y-%m-%d') }}
    11 |
    {{ _('Last Modified') }}
    12 |
    {{ h.date_str_to_datetime(modified).strftime('%Y-%m-%d') }}
    13 | {% if organization %} 14 |
    {{ _('Organization') }}
    15 |
    {{ h.split_piped_bilingual_field(organization, h.lang()) }}
    16 | {% endif %} 17 |
    18 |

    19 | 20 | {{ _('Return to Index') }} 21 | 22 |

    23 |
    24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/form_snippets/ro_multiple_choice.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 |
    5 |
    6 | {%- set values = data[field.field_name] -%} 7 | {%- set labels = [] -%} 8 | {%- for choice in h.scheming_field_choices(field) -%} 9 | {%- if choice.value in values -%} 10 | {%- do labels.append(h.scheming_language_text(choice.label)) -%} 11 | {%- endif -%} 12 | {%- endfor -%} 13 | {%- if labels|length == 1 -%} 14 | {{ labels[0] }} 15 | {%- else -%} 16 | {%- if field.get('sorted_choices') -%} 17 | {%- set labels = labels|sort -%} 18 | {%- endif -%} 19 |
      20 | {%- for label in labels -%} 21 |
    • {{ label }}
    • 22 | {%- endfor -%} 23 |
    24 | {%- endif -%} 25 |
    26 |
    27 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/snippets/user_search.html: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ _('Search Users') }}

    3 |
    4 |
    5 |
    6 | 7 | 8 | {% block search_input_button %} 9 | 12 | {% endblock %} 13 | 14 |
    15 |
    16 |
    17 |
    18 | -------------------------------------------------------------------------------- /ckanext/canada/assets/datatables/canada_datatables.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('load', function(){ 2 | 3 | $(document).on('preInit.dt', function(_event, _settings){ 4 | 5 | $('body.dt-view').css('visibility', 'visible'); 6 | $('#dtprv_processing').css({ 7 | 'background-color': 'rgba(255, 255, 255, 1)', 8 | 'display': 'block', 9 | 'pointer-events': 'all', 10 | }); 11 | $('#dtprv_processing > div').css('top', '15%'); 12 | 13 | }); 14 | 15 | $(document).on('init.dt', function(){ 16 | 17 | $('#dtprv_processing').css({ 18 | 'background-color': 'rgba(255, 255, 255, 0.65)', 19 | 'pointer-events': 'none', 20 | }); 21 | $('#dtprv_processing > div').css('top', '50%'); 22 | 23 | }); 24 | 25 | $(document).on('processing.dt', function(_event, _settings, _processing){ 26 | 27 | $('#dtprv_processing').css('display', _processing ? 'block' : 'none'); 28 | 29 | }); 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /conf/who.ini: -------------------------------------------------------------------------------- 1 | [plugin:auth_tkt] 2 | use = ckan.lib.auth_tkt:make_plugin 3 | # If no secret key is defined here, beaker.session.secret will be used 4 | #secret = somesecret 5 | 6 | [plugin:friendlyform] 7 | use = repoze.who.plugins.friendlyform:FriendlyFormPlugin 8 | login_form_url= /user/login 9 | login_handler_path = /login_generic 10 | logout_handler_path = /user/logout 11 | rememberer_name = auth_tkt 12 | post_login_url = /user/logged_in 13 | post_logout_url = /user/logged_out 14 | charset = utf-8 15 | 16 | [general] 17 | request_classifier = repoze.who.classifiers:default_request_classifier 18 | challenge_decider = repoze.who.classifiers:default_challenge_decider 19 | 20 | [identifiers] 21 | plugins = 22 | friendlyform;browser 23 | auth_tkt 24 | 25 | [authenticators] 26 | plugins = 27 | auth_tkt 28 | ckan.lib.authenticator:UsernamePasswordAuthenticator 29 | 30 | [challengers] 31 | plugins = 32 | friendlyform;browser 33 | 34 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | pull_request: 4 | workflow_dispatch: 5 | workflow_call: 6 | push: 7 | branches: 8 | - master 9 | - staging 10 | - dev 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} # workflow limits it to this workflow, ref includes a pushed branch or on pull request merge branch 14 | cancel-in-progress: true 15 | 16 | permissions: 17 | contents: read 18 | 19 | jobs: 20 | 21 | flake8: 22 | name: Lint (Flake8) 23 | uses: ./.github/workflows/flake8.yml # Call the reusable workflow 24 | secrets: inherit 25 | 26 | pyright: 27 | name: Lint (PyRight) 28 | uses: ./.github/workflows/pyright.yml # Call the reusable workflow 29 | secrets: inherit 30 | 31 | pytest: 32 | name: Test (Pytest) 33 | uses: ./.github/workflows/pytest.yml # Call the reusable workflow 34 | with: 35 | splits: 12 36 | secrets: inherit 37 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/perform_reset.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block primary_content %} 4 | {% if h.is_registry_domain() %} 5 |
    6 |
    7 |
    8 |

    {% trans %}password reset requirements{% endtrans %}

    9 |
    10 |
    11 | {% block primary_content_inner %} 12 |
    13 | {% block form %} 14 | {{ super() }} 15 | {% endblock %} 16 |
    17 | {% endblock %} 18 |
    19 |
    20 |
    21 | {% endif %} 22 | {% endblock %} 23 | 24 | {% block help %} 25 |
    26 | {{ self.help_inner() }} 27 |
    28 | {% endblock %} 29 | 30 | {% block secondary_content %} 31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/snippets/resources_list.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block resource_list_title %} 4 |

    {{ _('Data and Resources') }} 5 | {% set fgp_url = h.fgp_viewer_url(pkg) %} 6 | {% if fgp_url %} 7 | 12 | {% endif %} 13 | {% if h.is_registry_domain() and h.check_access('package_update', {'id': pkg.id}) %} 14 | 19 | {% endif %} 20 |

    21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /ckanext/canada/templates/admin/snippets/portal_sync_package_item.html: -------------------------------------------------------------------------------- 1 | {% extends 'snippets/package_item.html' %} 2 | 3 | {% block resources_outer %} 4 | {{ super() }} 5 |
    6 |
    7 |
    8 | 9 |   10 | {{ _('Last Successful Sync:') }}  11 | {% if sync_info['last_successful_sync'] %} 12 | {{ h.render_datetime(sync_info['last_successful_sync'], '%Y-%m-%d %H:%M:%S %Z') }} 13 | {% else %} 14 | {{ _('N/A') }} 15 | {% endif %} 16 | 17 |
    18 |
    19 |
    20 |
    21 | 22 |   23 | {{ _('Failure Reason:') }}  24 | {{ sync_info['error_on'] }} 25 | 26 |
    27 |
    28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /ckanext/canada/assets/public/webassets.yml: -------------------------------------------------------------------------------- 1 | css: 2 | contents: 3 | - canada_public.css 4 | output: canada_public/%(version)s_canada_public.css 5 | 6 | analytics: 7 | contents: 8 | - canada_public_analytics.js 9 | output: canada_public/%(version)s_canada_public_analytics.js 10 | 11 | adobe_analytics_fix: 12 | contents: 13 | - adobe_analytics_fix.js 14 | output: canada_public/%(version)s_adobe_analytics_fix.js 15 | 16 | check_all: 17 | contents: 18 | - check_all.js 19 | output: canada_public/%(version)s_check_all.js 20 | 21 | geomap_zoom: 22 | contents: 23 | - geomapzoom.js 24 | output: canada_public/%(version)s_geomapzoom.js 25 | 26 | i18n: 27 | contents: 28 | - i18n.js 29 | output: canada_public/%(version)s_i18n.js 30 | 31 | more_like_this: 32 | contents: 33 | - more_like_this.js 34 | output: canada_public/%(version)s_more_like_this.js 35 | 36 | voting_fix: 37 | contents: 38 | - voting_fix.js 39 | output: canada_public/%(version)s_voting_fix.js 40 | 41 | -------------------------------------------------------------------------------- /ckanext/canada/plugin/validation_plugin.py: -------------------------------------------------------------------------------- 1 | from typing import Optional, Any, List, Dict 2 | 3 | from frictionless import Plugin as FrictionlessPlugin 4 | 5 | from ckan.plugins.toolkit import config, asbool 6 | from ckanext.canada import checks 7 | 8 | 9 | class CanadaValidationPlugin(FrictionlessPlugin): 10 | def select_check_class(self, 11 | type: Optional[str] = None) -> \ 12 | Optional['checks.DatastoreHeadersCheck']: 13 | """ 14 | Load custom check classes. 15 | """ 16 | if type == 'ds-headers': 17 | return checks.DatastoreHeadersCheck() 18 | 19 | def detect_field_candidates(self, field_candidates: List[Dict[str, Any]]): 20 | """ 21 | Set list of available types for Resource table fields. 22 | """ 23 | if asbool(config.get('ckanext.validation.use_type_guessing', False)): 24 | return 25 | field_candidates.clear() 26 | field_candidates.append({'type': 'string'}) 27 | -------------------------------------------------------------------------------- /ckanext/canada/templates/datastore/snippets/dictionary_form.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% import 'macros/form.html' as form %} 4 | 5 | {% block standard_fields %} 6 | {{ form.input('info__' ~ position ~ '__label_en', 7 | label=_('English Label'), id='field-f' ~ position ~ 'label_en', 8 | value=field.get('info', {}).get('label_en', ''), classes=['control-full']) }} 9 | 10 | {{ form.input('info__' ~ position ~ '__label_fr', 11 | label=_('French Label'), id='field-f' ~ position ~ 'label_fr', 12 | value=field.get('info', {}).get('label_fr', ''), classes=['control-full']) }} 13 | 14 | {{ form.markdown('info__' ~ position ~ '__notes_en', 15 | label=_('English Description'), id='field-d' ~ position ~ 'notes_en', 16 | value=field.get('info', {}).get('notes_en', '')) }} 17 | 18 | {{ form.markdown('info__' ~ position ~ '__notes_fr', 19 | label=_('French Description'), id='field-d' ~ position ~ 'notes_fr', 20 | value=field.get('info', {}).get('notes_fr', '')) }} 21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/index.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block primary_content_inner %} 4 |
    5 | {% block organizations_search_form %} 6 | {% snippet 'organization/snippets/organization_search.html', q=q, count=page.item_count %} 7 | {% endblock %} 8 | {% block organizations_list %} 9 | {% if page.items or request.args %} 10 | {% snippet "organization/snippets/organization_list.html", organizations=page.items %} 11 | {% else %} 12 |

    13 | {{ _('There are currently no organizations for this site') }}. 14 | {% if h.check_access('organization_create') %} 15 | {% link_for _('How about creating one?'), 'organization.new' %}. 16 | {% endif %} 17 |

    18 | {% endif %} 19 | {% endblock %} 20 | {% block page_pagination %} 21 | {{ super() }} 22 | {% endblock %} 23 |
    24 | {% endblock %} 25 | 26 | {% block page_heading %}{{ _('Organizations') }}{% endblock %} 27 | -------------------------------------------------------------------------------- /ckanext/canada/templates/snippets/activity_type_selector.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {%- block activity_form_classes -%}form-inline{%- endblock -%} 4 | 5 | {%- block activity_label_classes %}control-label{% endblock -%} 6 | 7 | {%- block activity_select_classes %}form-control input-sm form-select{% endblock -%} 8 | 9 | {% block activity_options %} 10 | {{ super() }} 11 | 14 | 17 | 20 | {% endblock %} 21 | -------------------------------------------------------------------------------- /bin/filter/filter_modified_created.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "generic filter for removing record modified, created fields" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | 14 | def main(): 15 | reader = csv.DictReader(sys.stdin) 16 | if not reader.fieldnames: 17 | # empty file -> empty file for filtering files that did not exist 18 | return 19 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 20 | writer = csv.DictWriter(sys.stdout, outnames) 21 | writer.writeheader() 22 | for row in reader: 23 | try: 24 | for rem in REMOVE_COLUMNS: 25 | try: 26 | del row[rem] 27 | except KeyError: 28 | # may be filtering old records that were missing these cols 29 | pass 30 | writer.writerow(row) 31 | except ValueError: 32 | pass 33 | 34 | 35 | main() 36 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/snippets/organization_item.html: -------------------------------------------------------------------------------- 1 | {% set url = h.url_for(organization.type + '.read', id=organization.name) %} 2 | {% set html_title = _('This organization has no description') %} 3 | {% if organization.description %} 4 | {% set html_title = organization.description|truncate(80, true) %} 5 | {% endif %} 6 |
    7 | {{ h.split_piped_bilingual_field(organization.display_name, h.lang())|truncate(80, true) }} 8 |
    9 |
    10 | {%- if organization.package_count -%} 11 | {{ ungettext('{num} Dataset', '{num} Datasets', organization.package_count).format(num=organization.package_count) }} 12 | {%- else -%} 13 | {{ _('0 Datasets') }} 14 | {%- endif -%} 15 | {% if h.check_access('group_update', {'id': organization.id}) %} 16 | {{ _('Edit') }} 17 | {% endif %} 18 |
    19 | -------------------------------------------------------------------------------- /ckanext/canada/templates/admin/base.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block breadcrumb_content %} 4 | {% if h.is_registry_domain() %} 5 | {{ h.build_nav('admin.index', _('Admin')) }} 6 | {% else %} 7 | {{ super() }} 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block content_primary_nav %} 12 | {% if h.is_registry_domain() %} 13 | {{ h.build_nav_icon('canada.ckan_admin_index', _('Admins'), icon='user-plus') }} 14 | {{ h.build_nav_icon('user.index', _('Users'), icon='user') }} 15 | {# {{ h.build_nav_icon('admin.trash', _('Trash'), icon='trash') }} #} 16 | {{ h.build_nav_icon('canada.ckanadmin_publish', _('Publish Records'), icon='cloud-upload') }} 17 | {{ h.build_nav_icon('canada.ckanadmin_job_queue', _('Job Queue'), icon='tasks') }} 18 | {{ h.build_nav_icon('canada.ckan_admin_portal_sync', _('Out of Sync Packages'), icon='exclamation-triangle') }} 19 | {{ h.build_nav_icon('admin.search_rebuild', _('Rebuild Search Index'), icon='database') }} 20 | {{ h.build_extra_admin_nav() }} 21 | {% else %} 22 | {{ super() }} 23 | {% endif %} 24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # Starter pipeline 2 | # Start with a minimal pipeline that you can customize to build and deploy your code. 3 | # Add steps that build, run tests, deploy, and more: 4 | # https://aka.ms/yaml 5 | 6 | # Run manually for now 7 | trigger: none 8 | 9 | pr: none 10 | 11 | pool: 12 | vmImage: ubuntu-latest 13 | 14 | steps: 15 | 16 | - script: | 17 | pip download -d $(Build.ArtifactStagingDirectory)/Dependencies -r requirements.txt 18 | displayName: 'Download Dependencies for Offline Install' 19 | 20 | - task: ArchiveFiles@2 21 | inputs: 22 | rootFolderOrFile: '$(Build.SourcesDirectory)' 23 | includeRootFolder: true 24 | archiveType: 'tar' 25 | archiveFile: '$(Build.ArtifactStagingDirectory)/ckanext_canada_package.tgz' 26 | replaceExistingArchive: true 27 | displayName: 'Create a tar file of the source and python packages' 28 | 29 | - task: PublishBuildArtifacts@1 30 | inputs: 31 | PathtoPublish: '$(Build.ArtifactStagingDirectory)' 32 | ArtifactName: 'SourceOfflinePackage' 33 | publishLocation: 'Container' 34 | displayName: 'Publish ckan artifact' -------------------------------------------------------------------------------- /ckanext/canada/templates/package/snippets/resource_views_list_item.html: -------------------------------------------------------------------------------- 1 | {% set action = 'resource.edit_view' if is_edit and h.check_access('resource_view_update', view) else 'resource.read' %} 2 | 3 | {% if current_filters %} 4 | {% set url = h.url_for(action, id=pkg.name, 5 | resource_id=view.resource_id, view_id=view.id, 6 | filters=current_filters) %} 7 | {% else %} 8 | {% set url = h.url_for(action, id=pkg.name, 9 | resource_id=view.resource_id, view_id=view.id) %} 10 | {% endif %} 11 | 12 |
  • 13 | 14 | 15 | {% if h.lang() == 'fr' %}{{ view.title_fr }}{% else %}{{ view.title }}{% endif %} 16 | {% if view.get('canada_disabled_view') %} 17 | {{ _('Disabled') }} 18 | {% endif %} 19 | 20 |
  • 21 | 22 | -------------------------------------------------------------------------------- /samples/upload_file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source $HOME/.bashrc 3 | CONFIG=$1 4 | set -e 5 | 6 | ckanapi action resource_patch -c $CONFIG \ 7 | id=12b79506-4d48-484a-9ed2-6e6ea13a08af upload@"./dq170529b-eng.pdf" 8 | ckanapi action resource_patch -c $CONFIG \ 9 | id=0b7d08d3-a6b2-4800-bd15-4b1cac4e4233 upload@"./dq170529a-eng.pdf" 10 | ckanapi action resource_patch -c $CONFIG \ 11 | id=ff58ac0f-f95f-4fb0-8674-f19fa21847ad upload@"./dq170529c-eng.pdf" 12 | ckanapi action resource_patch -c $CONFIG \ 13 | id=758bff28-84fd-4ea7-9b70-5323aec7f61f upload@"./dq170529d-eng.pdf" 14 | 15 | ckanapi action resource_patch -c $CONFIG \ 16 | id=66013730-a9c3-48f0-86b9-caea70422f06 upload@"./dq170529b-fra.pdf" 17 | ckanapi action resource_patch -c $CONFIG \ 18 | id=9c53224a-d7a3-4053-9ddc-c454e5eac135 upload@"./dq170529a-fra.pdf" 19 | ckanapi action resource_patch -c $CONFIG \ 20 | id=c069a353-50d4-42f3-90bf-b5bcf4501aeb upload@"./dq170529c-fra.pdf" 21 | ckanapi action resource_patch -c $CONFIG \ 22 | id=77a51f91-6503-449e-9bc5-281b1ea924f8 upload@"./dq170529d-fra.pdf" 23 | -------------------------------------------------------------------------------- /ckanext/canada/templates/organization/snippets/organization_search.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | 5 | 6 | {% block search_input_button %} 7 | 10 | {% endblock %} 11 | 12 |
    13 |
    14 |
    15 | 16 |
    17 |
    18 | {% snippet 'snippets/search_result_text.html', query=q, count=count, type="organization" %} 19 |
    20 |
    21 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/edit_base.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block content_primary_nav %} 4 | {% if pkg.type != 'prop' %} {# suggested datasets have no resources #} 5 | {{ super() }} 6 | {% endif %} 7 | {% endblock %} 8 | 9 | {% block secondary_content %} 10 | {% if pkg_dict and not pkg_dict.resources %} 11 |
    12 | {{ super() }} 13 |
    14 | {% else %} 15 | {{ super() }} 16 | {% endif %} 17 | {% endblock %} 18 | 19 | {% block scripts %} 20 | {% asset 'canada_internal/package_edit' %} 21 | {% asset 'canada_internal/resource_edit' %} 22 | {{ super() }} 23 | 35 | {% endblock %} 36 | -------------------------------------------------------------------------------- /conf/who-security.ini: -------------------------------------------------------------------------------- 1 | [plugin:auth_tkt] 2 | use = ckan.lib.auth_tkt:make_plugin 3 | # If no secret key is defined here, beaker.session.secret will be used 4 | #secret = somesecret 5 | 6 | [plugin:use_beaker] 7 | use = repoze.who.plugins.use_beaker:make_plugin 8 | key_name = ckan_session 9 | delete_on_logout = True 10 | 11 | [plugin:friendlyform] 12 | use = repoze.who.plugins.friendlyform:FriendlyFormPlugin 13 | login_form_url= /user/login 14 | login_handler_path = /login_generic 15 | logout_handler_path = /user/logout 16 | rememberer_name = use_beaker 17 | post_login_url = /user/logged_in 18 | post_logout_url = /user/logged_out 19 | charset = utf-8 20 | 21 | [general] 22 | request_classifier = repoze.who.classifiers:default_request_classifier 23 | challenge_decider = repoze.who.classifiers:default_challenge_decider 24 | 25 | [identifiers] 26 | plugins = 27 | friendlyform;browser 28 | use_beaker 29 | 30 | [authenticators] 31 | plugins = 32 | ckanext.security.authenticator:CKANLoginThrottle 33 | ckanext.security.authenticator:BeakerRedisAuth 34 | 35 | [challengers] 36 | plugins = 37 | friendlyform;browser 38 | -------------------------------------------------------------------------------- /ckanext/canada/assets/internal/registry_resource_edit.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('load', function(){ 2 | 3 | $(document).ready(function() { 4 | 5 | let editToolbar = $('header.page-header ul.nav-tabs'); 6 | 7 | if ( editToolbar.length > 0 ){ 8 | 9 | let activeElement = $(editToolbar).find('li.active'); 10 | 11 | if ( activeElement.length === 0 ){ 12 | 13 | // if there is no active element, assume that we are editing the metadata 14 | $(editToolbar).find('li').first().addClass('active'); 15 | 16 | } 17 | 18 | } 19 | 20 | let resourceDataFieldWrapper = $('.resource-upload-field'); 21 | 22 | if ( resourceDataFieldWrapper.length > 0 ){ 23 | 24 | let errorBlocks = $(resourceDataFieldWrapper).find('.error-block'); 25 | 26 | if ( errorBlocks.length > 0 ){ 27 | 28 | $(errorBlocks).each(function(_index, _element){ 29 | 30 | if ( _index === 0 ){ 31 | $(_element).appendTo(resourceDataFieldWrapper); 32 | }else{ 33 | $(_element).remove(); 34 | } 35 | 36 | }); 37 | 38 | } 39 | 40 | } 41 | 42 | }); 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/resource_edit_base.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block breadcrumb_content %} 4 | {{ super.super() }} 5 | {% if res %} 6 |
  • {{ h.link_to(h.truncate(h.resource_display_name(res), 80), h.url_for(pkg.type + '_resource.read', id=pkg.name, resource_id=res.id), title=h.resource_display_name(res)) }}
  • 7 |
  • {{ _('Edit') }}
  • 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block content_action %} 12 | {%- link_for _('All resources'), named_route=pkg.type ~ '.resources', id=pkg.name, class_='btn btn-default', icon='arrow-left' -%} 13 | {% if res %} 14 | {%- link_for _('View resource'), named_route=pkg.type ~ '_resource.read', id=pkg.name, resource_id=res.id, class_='btn btn-default', icon='eye' -%} 15 | {% endif %} 16 | {% endblock %} 17 | 18 | {% block scripts %} 19 | {% asset 'canada_internal/resource_edit' %} 20 | {% asset 'canada_internal/guess_mimetype' %} 21 | {{ super() }} 22 | {% endblock %} 23 | 24 | {% block custom_styles %} 25 | {{ super() }} 26 | {% asset 'vendor/select2-css' %} 27 | {% endblock %} 28 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/base_form_page.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block breadcrumb_content %} 4 | {% if h.is_registry_domain() %} 5 | {{ h.build_nav('dataset.new', _('Create Dataset')) }} 6 | {% endif %} 7 | {% endblock %} 8 | 9 | {% block secondary_content %} 10 | {% if not h.is_registry_domain() %} 11 | {{ super() }} 12 | {% endif %} 13 | {% endblock %} 14 | 15 | {% block page_header %} 16 | {% if not h.is_registry_domain() %} 17 | {{ super() }} 18 | {% endif %} 19 | {% endblock %} 20 | 21 | {% block info_module %} 22 | {% block what_are_datasets %} 23 |
    24 |
    25 |
     {{ _('What are datasets?') }}
    26 |
    27 |
    28 | {% trans %} 29 | Datasets are simply used to group related pieces of data. These 30 | can then be found under a single url with a description and 31 | licensing information. 32 | {% endtrans %} 33 |
    34 |
    35 | {% endblock %} 36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /ckanext/canada/tests/helpers.py: -------------------------------------------------------------------------------- 1 | import os 2 | from cgi import FieldStorage 3 | 4 | 5 | def get_sample_filepath(filename): 6 | return os.path.abspath(os.path.join(os.path.dirname(__file__), "samples", filename)) 7 | 8 | 9 | class MockFieldStorage(FieldStorage): 10 | def __init__(self, fp, filename): 11 | self.file = fp 12 | self.filename = filename 13 | self.name = 'upload' 14 | self.list = None 15 | 16 | def __bool__(self): 17 | if self.file: 18 | return True 19 | return False 20 | 21 | 22 | class MockFlashMessages(object): 23 | 24 | __flashes = [] 25 | 26 | def mock_flash(self, message: str, category: str = "message") -> None: 27 | self.__flashes.append((category, message)) 28 | 29 | def mock_get_flashed_messages(self, with_categories: bool = False, category_filter: set = ()): 30 | flashes = self.__flashes 31 | if category_filter: 32 | flashes = list(filter(lambda f: f[0] in category_filter, flashes)) 33 | if not with_categories: 34 | return [x[1] for x in flashes] 35 | self.__flashes = [] 36 | return flashes 37 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/en/datastore-error.svg: -------------------------------------------------------------------------------- 1 | datastore: errordatastoreerror -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/en/datastore-active.svg: -------------------------------------------------------------------------------- 1 | datastore: activedatastoreactive -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/fr/datastore-active.svg: -------------------------------------------------------------------------------- 1 | datastore: activedatastoreactive -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/fr/datastore-error.svg: -------------------------------------------------------------------------------- 1 | datastore: erreurdatastoreerreur -------------------------------------------------------------------------------- /ckanext/canada/assets/public/adobe_analytics_fix.js: -------------------------------------------------------------------------------- 1 | // NOTE: Adobe Analytics sets a cookie called clickURL. 2 | // This can have javascript inside of it, we need to sanitize that! 3 | function canada_fix_adobe_analytics_cookies(){ 4 | const maxTries = 20; 5 | let currentTry = 0; 6 | let interval = false; 7 | 8 | function _fix_adobe_analytics_cookies(){ 9 | if( currentTry > maxTries ){ 10 | clearInterval(interval); 11 | interval = false; 12 | return; 13 | } 14 | 15 | currentTry++; 16 | 17 | if( typeof _satellite == 'undefined' || typeof _satellite.cookie == 'undefined' || typeof _satellite.cookie.set == 'undefined' ){ 18 | return; 19 | } 20 | 21 | clearInterval(interval); 22 | interval = false; 23 | 24 | const superFunc = _satellite.cookie.set; 25 | _satellite.cookie.set = function(_t, _n, _i){ 26 | if( _t != 'clickURL' || ! _n.toString().includes('javascript') ){ 27 | return superFunc(_t, _n, _i); 28 | } 29 | return superFunc(_t, '', _i); 30 | } 31 | } 32 | 33 | interval = setInterval(_fix_adobe_analytics_cookies, 100); 34 | } 35 | 36 | canada_fix_adobe_analytics_cookies(); 37 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/en/datastore-pending.svg: -------------------------------------------------------------------------------- 1 | datastore: pendingdatastorepending -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/en/datastore-running.svg: -------------------------------------------------------------------------------- 1 | datastore: runningdatastorerunning -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/en/datastore-unknown.svg: -------------------------------------------------------------------------------- 1 | datastore: unknowndatastoreunknown -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/en/datastore-complete.svg: -------------------------------------------------------------------------------- 1 | datastore: completedatastorecomplete -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/en/datastore-inactive.svg: -------------------------------------------------------------------------------- 1 | datastore: inactivedatastoreinactive -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/fr/datastore-complete.svg: -------------------------------------------------------------------------------- 1 | datastore: complètedatastorecomplète -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/fr/datastore-inactive.svg: -------------------------------------------------------------------------------- 1 | datastore: inactivedatastoreinactive -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/fr/datastore-unknown.svg: -------------------------------------------------------------------------------- 1 | datastore: inconnuedatastoreinconnue -------------------------------------------------------------------------------- /.github/workflows/dac.yml: -------------------------------------------------------------------------------- 1 | name: Download DAC members list 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | - uses: actions/setup-python@v3 12 | with: 13 | python-version: '2.7' 14 | 15 | - name: Install dependencies 16 | run: pip install pyyaml 17 | 18 | - name: download DAC members list 19 | run: | 20 | python bin/download_dac.py -o ckanext/canada/tables/choices/dac_members.yaml -v 0 21 | cat ckanext/canada/tables/choices/dac_members.yaml 22 | 23 | - name: set git config 24 | run: | 25 | git config user.name 'github-actions[bot]' 26 | git config user.email 'github-actions[bot]@users.noreply.github.com' 27 | git status 28 | 29 | - name: Create Pull Request 30 | uses: peter-evans/create-pull-request@v4 31 | with: 32 | commit-message: "Update DAC members list" 33 | title: "Update DAC members list" 34 | branch: create-pull-request/patch 35 | branch-suffix: timestamp 36 | reviewers: rabiasajjad 37 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/fr/datastore-pending.svg: -------------------------------------------------------------------------------- 1 | datastore: en attentedatastoreen attente -------------------------------------------------------------------------------- /bin/resource_management/update_resource_size.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Updates Resources based on incorrect_file_size_report.csv 4 | 'source.action.resource_patch(id=resource_id,size=new_size)' 5 | 6 | Input: 7 | argv[1]: site URL 8 | argv[2]: API Key 9 | argv[3]: CSV Report ('incorrect_file_sizes_report.csv') 10 | 11 | """ 12 | import sys 13 | import csv 14 | import ckanapi 15 | import ckan 16 | 17 | source = ckanapi.RemoteCKAN(sys.argv[1], apikey=sys.argv[2]) 18 | file_report = sys.argv[3] 19 | print("Updating resource file sizes") 20 | with open(file_report) as csvfile: 21 | reader = csv.DictReader(csvfile) 22 | for row in reader: 23 | uuid = row["uuid"] 24 | resource_id = row["resource_id"] 25 | new_size = str(row["found_file_size"]) 26 | try: 27 | if (new_size == 'N/A'): 28 | continue 29 | s = source.action.resource_show(id=resource_id) 30 | s = source.action.resource_patch(id=resource_id, size=new_size) 31 | print("Updated: ", [uuid, resource_id, s.get("size")]) 32 | except ckan.logic.NotFound: 33 | print("{0} dataset not found".format(uuid)) 34 | print("done") 35 | -------------------------------------------------------------------------------- /ckanext/canada/assets/internal/registry_organization_edit.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('load', function(){ 2 | $(function () { 3 | let $field_url = $('#field-name'); 4 | 5 | function format_url(en,fr) { 6 | // return URL in the form en-fr 7 | let $value_en = (en) ? $.url.slugify(en, true) : '', 8 | $value_fr = (fr) ? $.url.slugify(fr, true) : ''; 9 | 10 | if ($value_en && !$value_fr) 11 | return $value_en; 12 | if (!$value_en && $value_fr) 13 | return $value_fr; 14 | if ($value_en == $value_fr) 15 | return $value_en; 16 | 17 | return ($value_en + '-' + $value_fr); 18 | } 19 | 20 | if (!$field_url.val()) { 21 | $('#field-shortform-en').on('input', function () { 22 | $field_url.val(format_url($('#field-shortform-en').val(), $('#field-shortform-fr').val())); 23 | }); 24 | $('#field-shortform-fr').on('input', function () { 25 | $field_url.val(format_url($('#field-shortform-en').val(), $('#field-shortform-fr').val())); 26 | }); 27 | } 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/snippets/view_form.html: -------------------------------------------------------------------------------- 1 | {% import 'macros/form.html' as form %} 2 | 3 | {% set data = data or {} %} 4 | {% set errors = errors or {} %} 5 | 6 | {{ form.errors(error_summary) }} 7 | 8 | {{ form.input('title', id='field-title', label=_('Title (English)'), value=data.title, error=errors.title, classes=['control-full', 'control-large'], is_required=true) }} 9 | {{ form.input('title_fr', id='field-title_fr', label=_('Title (French)'), value=data.title_fr, error=errors.title_fr, classes=['control-full', 'control-large'], is_required=true) }} 10 | {{ form.markdown('description', id='field-description', label=_('Description (English)'), value=data.description, error=errors.description) }} 11 | {{ form.markdown('description_fr', id='field-description_fr', label=_('Description (French)'), value=data.description_fr, error=errors.description_fr) }} 12 | 13 | {% block view_form_filters %} 14 | {% snippet 'package/snippets/view_form_filters.html', resource=resource, resource_view=resource_view %} 15 | {% endblock %} 16 | 17 | {# form template is defined in ResouceView extention point #} 18 | 19 | {% if form_template %} 20 | {% include form_template %} 21 | {% endif %} 22 | 23 | -------------------------------------------------------------------------------- /ckanext/canada/templates/package/new_resource_not_draft.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block form %} 4 | {% set max_resource_count = h.max_resources_per_dataset() %} 5 | {% if h.is_registry_domain() and max_resource_count and pkg_dict.resources|length >= max_resource_count %} 6 |
    7 |
    8 |
    9 |
    10 | {{ _("Resource Limit Reached") }} 11 |

    {{ _("You can only add up to {max_resource_count} resources to a dataset. " 12 | "You can segment your resources across multiple datasets or merge your " 13 | "data to limit the number of resources. Please contact " 14 | "{support} if you need further assistance.").format(max_resource_count=max_resource_count, support=h.support_email_address()) }}

    15 |
    16 |
    17 |
    18 |
    19 | {% else %} 20 | {{ super() }} 21 | {% endif %} 22 | {% endblock %} 23 | 24 | {% block secondary_content %} 25 | {% snippet 'package/snippets/resources.html', pkg=pkg %} 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /bin/filter/filter_ati.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Script that takes csv on stdin with Year, Month as the first two columns 5 | and outputs the header row and all rows within the past two years on stdout 6 | """ 7 | 8 | import csv 9 | import sys 10 | 11 | start_year_month = 2020, 1 # publicly accessible records 12 | 13 | REMOVE_COLUMNS = [ 14 | 'record_created', 15 | 'record_modified', 16 | 'user_modified', 17 | ] 18 | 19 | BOM = "\N{bom}" 20 | 21 | 22 | def main(): 23 | bom = sys.stdin.read(1) # first code point 24 | if not bom: 25 | # empty file -> empty file 26 | return 27 | assert bom == BOM 28 | sys.stdout.write(BOM) 29 | 30 | reader = csv.DictReader(sys.stdin) 31 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 32 | writer = csv.DictWriter(sys.stdout, outnames) 33 | writer.writeheader() 34 | for row in reader: 35 | try: 36 | for rem in REMOVE_COLUMNS: 37 | del row[rem] 38 | 39 | if (int(row['year']), int(row['month'])) >= start_year_month: 40 | writer.writerow(row) 41 | except ValueError: 42 | pass 43 | 44 | 45 | main() 46 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/snippets/form_field.html: -------------------------------------------------------------------------------- 1 | {% ckan_extends %} 2 | 3 | {% block removal_popup%} 4 | {% set locale = h.dump_json({'content': _('Are you sure you want to delete this status?') }) %} 5 | {% set template = [ 6 | '' 20 | ]|join('\n') %} 21 | {% block delete_button_text %}{{ _('Delete') }}{% endblock %} 22 | {% endblock %} 23 | 24 | -------------------------------------------------------------------------------- /ckanext/canada/templates/scheming/package/read.html: -------------------------------------------------------------------------------- 1 | {% extends "package/read.html" %} 2 | 3 | {%- set schema = h.scheming_get_dataset_schema(dataset_type) -%} 4 | 5 | {% block package_notes %} 6 | {%- if not dataset_type -%} 7 |

    dataset_type not passed to template. your version of CKAN might not be compatible with ckanext-scheming

    8 | {%- endif -%} 9 | {% if h.scheming_field_by_name(schema.dataset_fields, 'notes') and pkg.notes %} 10 |
    11 | {{ h.render_markdown(pkg.notes) }} 12 |
    13 | {% endif %} 14 | {% endblock %} 15 | 16 | {% block package_additional_info %}{% endblock %} 17 | 18 | {% block actions_content %} 19 | 31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /ckanext/canada/public/static/img/badges/fr/datastore-running.svg: -------------------------------------------------------------------------------- 1 | datastore: en cours d'exécutiondatastoreen cours d'exécution -------------------------------------------------------------------------------- /bin/restore_trade_agreement_exceptions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import unicodecsv 4 | import sys 5 | import codecs 6 | 7 | good = open(sys.argv[1], 'rb') 8 | now = open(sys.argv[2], 'rb') 9 | 10 | assert good.read(3) == codecs.BOM_UTF8 11 | assert now.read(3) == codecs.BOM_UTF8 12 | sys.stdout.write(codecs.BOM_UTF8) 13 | 14 | good_csv = unicodecsv.DictReader(good, encoding='utf-8') 15 | now_csv = unicodecsv.DictReader(now, encoding='utf-8') 16 | assert good_csv.fieldnames == now_csv.fieldnames 17 | 18 | ltr = {} 19 | 20 | for row in good_csv: 21 | ltr[row['owner_org'], row['reference_number']] = row['trade_agreement_exceptions'] 22 | 23 | fix_csv = unicodecsv.DictWriter(sys.stdout, fieldnames=good_csv.fieldnames, 24 | encoding='utf-8') 25 | fix_csv.writeheader() 26 | 27 | for row in now_csv: 28 | try: 29 | tae = ltr[row['owner_org'], row['reference_number']] 30 | except KeyError: 31 | sys.stderr.write('missing: ' + 32 | repr((row['owner_org'], 33 | row['reference_number'])) + '\n') 34 | continue 35 | if tae == row['trade_agreement_exceptions']: 36 | continue 37 | row['trade_agreement_exceptions'] = tae 38 | fix_csv.writerow(row) 39 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/recover_username.html: -------------------------------------------------------------------------------- 1 | {% extends "page.html" %} 2 | 3 | {% block subtitle %}{{ _('Recover your username') }}{% endblock %} 4 | 5 | {% block breadcrumb_content %} 6 |
  • {% link_for _('Username Recovery'), named_route='canada.recover_username' %}
  • 7 | {% endblock %} 8 | 9 | {% block primary_content %} 10 |
    11 |
    12 | {% block primary_content_inner %} 13 | {% block form %} 14 |
    15 | {{ h.csrf_input() }} 16 |
    17 | 18 | 19 |
    20 |
    21 | {% block form_button %} 22 | 23 | {% endblock %} 24 |
    25 |
    26 | {% endblock %} 27 | {% endblock %} 28 |
    29 |
    30 | {% endblock %} 31 | 32 | {% block secondary_content %}{% endblock %} 33 | -------------------------------------------------------------------------------- /bin/filter/filter_travela.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | "filter for travela.csv" 3 | 4 | import csv 5 | import sys 6 | 7 | REMOVE_COLUMNS = [ 8 | 'record_created', 9 | 'record_modified', 10 | 'user_modified', 11 | ] 12 | 13 | # these fields need some kind of value 14 | # or drupal search won't work at all 15 | DRUPAL_SEARCH_HACK = [ 16 | 'operational_activities_kdollars', 17 | 'key_stakeholders_kdollars', 18 | 'training_kdollars', 19 | 'other_kdollars', 20 | 'internal_governance_kdollars', 21 | ] 22 | 23 | 24 | def main(): 25 | reader = csv.DictReader(sys.stdin) 26 | outnames = [f for f in reader.fieldnames if f not in REMOVE_COLUMNS] 27 | writer = csv.DictWriter(sys.stdout, outnames) 28 | writer.writeheader() 29 | for row in reader: 30 | try: 31 | for rem in REMOVE_COLUMNS: 32 | try: 33 | del row[rem] 34 | except KeyError: 35 | # may be filtering old records that were missing these cols 36 | pass 37 | for hack in DRUPAL_SEARCH_HACK: 38 | if hack in row and not row[hack]: 39 | row[hack] = '.' 40 | writer.writerow(row) 41 | except ValueError: 42 | pass 43 | 44 | 45 | main() 46 | -------------------------------------------------------------------------------- /bin/transitional_orgs_filter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | """ 5 | throw away all parts of an organization that we don't want to propagate 6 | to another ckan instance. 7 | 8 | Usage: 9 | 10 | ckanapi dump organizations --all -r http://registry.data.gc.ca | 11 | bin/transitional_orgs_filter.py > transitional_orgs.jsonl 12 | """ 13 | 14 | import sys 15 | import json 16 | from logging import getLogger 17 | 18 | 19 | log = getLogger(__name__) 20 | 21 | filtered_fields = {'id', 'name', 'title', 'title_translated', 22 | 'department_number', 'umd_number', 'shortform', 23 | 'ati_email', 'opengov_email', 'faa_schedule', 24 | 'registry_access'} 25 | 26 | users = '--users' in sys.argv 27 | 28 | for stdline in sys.stdin: 29 | o = json.loads(stdline) 30 | line = {} 31 | for key in o: 32 | if key in filtered_fields: 33 | line[key] = o[key] 34 | 35 | if users: 36 | line["users"] = [ 37 | {"name": u["name"], "capacity": u["capacity"]} 38 | for u in o["users"]] 39 | 40 | try: 41 | print(json.dumps(line, ensure_ascii=False)) 42 | except Exception as e: 43 | log.error("Failed on Organization:") 44 | log.error(line) 45 | raise Exception(e) 46 | -------------------------------------------------------------------------------- /ckanext/canada/tests/__init__.py: -------------------------------------------------------------------------------- 1 | from ckan import model 2 | 3 | 4 | def mock_is_registry_domain() -> bool: 5 | return True 6 | 7 | 8 | class CanadaTestBase(object): 9 | @classmethod 10 | def setup_method(self, method): 11 | """Method is called at class level before EACH test methods of the class are called. 12 | Setup any state specific to the execution of the given class methods. 13 | """ 14 | return 15 | 16 | @classmethod 17 | def teardown_method(self, method): 18 | """Method is called at class level after EACH test methods of the class are called. 19 | Remove any state specific to the execution of the given class methods. 20 | """ 21 | model.Session.rollback() 22 | return 23 | 24 | @classmethod 25 | def setup_class(self): 26 | """Method is called at class level once the class is instatiated. 27 | Setup any state specific to the execution of the given class. 28 | """ 29 | return 30 | 31 | @classmethod 32 | def teardown_class(self): 33 | """Method is called at class level after ALL test methods of the class are called. 34 | Remove any state specific to the execution of the given class. 35 | """ 36 | model.Session.rollback() 37 | return 38 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/dashboard.html: -------------------------------------------------------------------------------- 1 | {% extends "user/edit_base.html" %} 2 | 3 | {% set user = current_user %} 4 | {% set org_type = h.default_group_type('organization') %} 5 | {% set group_type = h.default_group_type('group') %} 6 | {% set dataset_type = h.default_package_type() %} 7 | 8 | {% block page_heading %} 9 | {{ _('Dashboard') }} - {{ _('My Activity') }} 10 | {% endblock %} 11 | 12 | {% block subtitle %} 13 | {{ _('My Activity') }} 14 | {% endblock %} 15 | 16 | {% block breadcrumb_content %} 17 | {{ super() }} 18 |
  • {% link_for _('My Activity'), named_route='activity.dashboard' %}
  • 19 | {% endblock %} 20 | 21 | {% block content_primary_nav %} 22 | {{ h.build_nav_icon('activity.dashboard', _('My Activity'), icon='clock') }} 23 | {{ h.build_nav_icon('dashboard.datasets', _('My Datasets'), icon='sitemap') }} 24 | {% endblock %} 25 | 26 | {% block primary_content_inner %} 27 |
    28 | {% block activity_stream %} 29 | {% snippet 'snippets/stream.html', activity_stream=dashboard_activity_stream %} 30 | {% endblock %} 31 | {% snippet 'snippets/pagination.html', newer_activities_url=newer_activities_url, older_activities_url=older_activities_url %} 32 |
    33 | {% endblock %} 34 | 35 | {% block secondary_content %}{% endblock %} 36 | -------------------------------------------------------------------------------- /ckanext/canada/templates/user/user_welcome_email.html: -------------------------------------------------------------------------------- 1 | (Le français suit) 2 | Hello {{ fullname }} 3 | 4 | Thank you for registering with the Open Government Registry. Your account has been successfully created. 5 | Although your account is active, it has not yet been linked to your department. Until the account is linked to your department you will not be able to create or modify datasets in the registry. 6 | For information on how to use the Open Government Registry, visit our [GCconnex] page for information resources. 7 | 8 | The Open Government Registry Team 9 | 10 | [GCconnex]: https://gcconnex.gc.ca/file/group/24670219/all#33289464 11 | 12 | …………………………………………………………………………………………………………………………………………………… 13 | 14 | Bonjour {{ fullname }}, 15 | 16 | Merci de vous être inscrit au Registre du gouvernement ouvert. Votre compte a été créé avec succès. 17 | Même si votre compte est actif, il n’est pas encore relié à votre ministère. Vous ne pourrez créer ou modifier de jeux de données dans le registre tant que votre compte n’aura pas été relié à votre ministère. 18 | Pour savoir comment utiliser le Registre du gouvernement ouvert, visitez notre page [GCconnex] pour obtenir des ressources documentaires. 19 | 20 | L'équipe de la Registre de Gouvernement Ouvert 21 | 22 | [GCconnex]: https://gcconnex.gc.ca/file/group/24670219/all#33289464 23 | --------------------------------------------------------------------------------