├── .github └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── data ├── agreements │ └── sendersampleid.txt ├── mdv │ ├── DA1 │ ├── PHE1 │ └── PHE1-FAST ├── orgs.txt └── qc │ ├── elan-minimal-test │ ├── testelan3-20220203-ill.qc │ ├── testelan3-20220203-ion.qc │ └── testelan3-20220203-ont.qc │ ├── elan-minimal │ ├── elan2-20200421-ill.qc │ ├── elan2-20200421-ion.qc │ └── elan2-20200421-ont.qc │ └── high-quality │ ├── gisaid1-20200421-ill.qc │ ├── gisaid1-20200421-ion.qc │ └── gisaid1-20200421-ont.qc ├── deku ├── __init__.py ├── apps.py ├── migrations │ └── __init__.py ├── models.py ├── templates │ ├── list_all_profiles.html │ └── list_site_profiles.html ├── test │ ├── __init__.py │ └── test_profiles.py ├── urls.py └── views.py ├── inbound-ops-patch.png ├── majora2 ├── __init__.py ├── account_views.py ├── admin.py ├── api_views.py ├── authentication.py ├── bot_views.py ├── context_processors.py ├── fixed_data.py ├── form_handlers.py ├── forms.py ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ ├── load_agreement.py │ │ ├── load_dataview.py │ │ ├── load_orgs.py │ │ ├── load_qctest.py │ │ ├── mknode.py │ │ └── shard_bigfdir.py ├── mdv_tasks.py ├── migrations │ ├── 0001_20200317_squashed.py │ ├── 0002_institution.py │ ├── 0003_auto_20200318_1058.py │ ├── 0004_make_ins.py │ ├── 0005_auto_20200318_1116.py │ ├── 0006_auto_20200318_1535.py │ ├── 0007_auto_20200318_1535.py │ ├── 0008_profile_api_key.py │ ├── 0009_api_keys.py │ ├── 0010_auto_20200318_1739.py │ ├── 0011_auto_20200319_1234.py │ ├── 0012_auto_20200319_1235.py │ ├── 0013_biosampleartifact_sample_site.py │ ├── 0014_biosourcesamplingprocess_submission_user.py │ ├── 0015_remove_biosampleartifact_collection.py │ ├── 0016_biosampleartifact_collection.py │ ├── 0017_auto_20200319_1503.py │ ├── 0018_auto_20200319_1712.py │ ├── 0019_auto_20200319_1928.py │ ├── 0020_auto_20200322_1545.py │ ├── 0021_auto_20200322_1611.py │ ├── 0022_auto_20200322_1616.py │ ├── 0023_biosampleartifact_secondary_accession.py │ ├── 0024_biosamplesource_secondary_id.py │ ├── 0025_county.py │ ├── 0026_auto_20200323_1149.py │ ├── 0027_auto_20200323_1635.py │ ├── 0028_auto_20200324_2219.py │ ├── 0029_auto_20200324_2231.py │ ├── 0030_auto_20200324_2358.py │ ├── 0031_auto_20200325_1834.py │ ├── 0032_auto_20200325_1835.py │ ├── 0033_auto_20200326_1516.py │ ├── 0034_abstractbioinformaticsprocess.py │ ├── 0035_dnasequencingprocess_run_name.py │ ├── 0036_auto_20200327_1000.py │ ├── 0037_auto_20200327_1005.py │ ├── 0038_auto_20200327_1658.py │ ├── 0039_biosourcesamplingprocess_received_date.py │ ├── 0040_auto_20200329_1814.py │ ├── 0041_majoraartifact_created.py │ ├── 0042_auto_20200331_1727.py │ ├── 0043_remove_libraryartifact_pooling.py │ ├── 0044_auto_20200331_1735.py │ ├── 0045_remove_biosampleartifact_collection.py │ ├── 0046_auto_20200405_1232.py │ ├── 0047_auto_20200405_1232.py │ ├── 0048_auto_20200405_1624.py │ ├── 0049_auto_20200406_0853.py │ ├── 0050_auto_20200406_0855.py │ ├── 0051_majoraartifactprocess_hook_name.py │ ├── 0052_pipehook.py │ ├── 0053_auto_20200411_0952.py │ ├── 0054_auto_20200411_1013.py │ ├── 0055_auto_20200419_1308.py │ ├── 0056_temporaryaccessionrecord.py │ ├── 0057_publishedartifactgroup_is_public.py │ ├── 0058_auto_20200425_1258.py │ ├── 0059_digitalresourceartifact_current_path.py │ ├── 0060_dar_current_path.py │ ├── 0061_auto_20200425_1601.py │ ├── 0062_auto_20200425_2235.py │ ├── 0063_auto_20200425_2323.py │ ├── 0064_auto_20200426_0137.py │ ├── 0065_auto_20200426_0232.py │ ├── 0066_auto_20200427_2327.py │ ├── 0067_auto_20200428_0134.py │ ├── 0068_auto_20200503_1145.py │ ├── 0069_pagqualityreportequivalencegroup_last_updated.py │ ├── 0070_publishedartifactgroup_public_timestamp.py │ ├── 0071_auto_20200504_1706.py │ ├── 0072_auto_20200504_1710.py │ ├── 0073_institute_gisaid_opted.py │ ├── 0074_temporarymajoraartifactmetric_thresholdcycle_temporarymajoraartifactmetricrecord_temporarymajoraarti.py │ ├── 0075_auto_20200505_1806.py │ ├── 0076_auto_20200507_1513.py │ ├── 0076_profileapikey_profileapikeydefinition.py │ ├── 0077_auto_20200506_1807.py │ ├── 0077_auto_20200508_1015.py │ ├── 0078_auto_20200506_1817.py │ ├── 0078_auto_20200513_1703.py │ ├── 0079_auto_20200515_1529.py │ ├── 0080_institute_ena_opted.py │ ├── 0081_merge_20200520_0825.py │ ├── 0082_coguk_biosourcesamplingprocesssupplement.py │ ├── 0083_auto_20200520_1000.py │ ├── 0084_auto_20200520_1004.py │ ├── 0085_add_supp_to_collections.py │ ├── 0086_migrate_s_strategy_to_supp.py │ ├── 0087_auto_20200520_1340.py │ ├── 0088_majoraartifactprocess_majora_timestamp.py │ ├── 0089_auto_20200521_1232.py │ ├── 0090_auto_20200526_1307.py │ ├── 0091_auto_20200527_1150.py │ ├── 0092_auto_20200527_1227.py │ ├── 0093_profile_is_site_approved.py │ ├── 0094_approve_already_approved.py │ ├── 0095_auto_20200527_1623.py │ ├── 0096_auto_20200527_2034.py │ ├── 0097_coguk_biosourcesamplingprocesssupplement_is_icu_patient.py │ ├── 0098_auto_20200606_1646.py │ ├── 0099_profileapikeydefinition_permission.py │ ├── 0100_auto_20200606_1700.py │ ├── 0101_profileagreement_profileagreementdefinition.py │ ├── 0102_auto_20200713_1651.py │ ├── 0103_auto_20200713_1717.py │ ├── 0104_institutecredit.py │ ├── 0105_auto_20200715_0933.py │ ├── 0106_profileagreementdefinition_is_terminable.py │ ├── 0107_majoradataview_majoradataviewserializerfield.py │ ├── 0108_auto_20200716_2203.py │ ├── 0109_majoradataviewuserpermission.py │ ├── 0110_auto_20200717_1811.py │ ├── 0111_auto_20200717_1814.py │ ├── 0112_auto_20200729_1253.py │ ├── 0113_auto_20200729_1316.py │ ├── 0114_temporaryaccessionrecord_requested_by.py │ ├── 0115_majoraartifactgroup_group_path.py │ ├── 0116_majoraartifactgrouplink.py │ ├── 0117_auto_20200808_1302.py │ ├── 0118_majoraartifactgroup_temp_kind.py │ ├── 0119_majoradataview_entry_point.py │ ├── 0120_auto_20200814_1819.py │ ├── 0121_majoradataview_permission.py │ ├── 0122_auto_20200820_2020.py │ ├── 0123_profileapppassword.py │ ├── 0124_majoradataviewfilterfield.py │ ├── 0125_auto_20200908_1617.py │ ├── 0126_auto_20200928_1751.py │ ├── 0127_auto_20201009_1518.py │ ├── 0128_auto_20201017_1334.py │ ├── 0129_coguk_biosourcesamplingprocesssupplement_collection_pillar.py │ ├── 0130_auto_20201029_1040.py │ ├── 0131_biosamplesource_root_biosample_source_id.py │ ├── 0132_auto_20201103_1223.py │ ├── 0133_auto_20201105_1507.py │ ├── 0134_auto_20201110_1629.py │ ├── 0135_majorametarecord_restricted.py │ ├── 0136_institute_ena_assembly_opted.py │ ├── 0137_auto_20210113_1258.py │ ├── 0138_librarypoolingprocessrecord_sequencing_org_received_date.py │ ├── 0139_auto_20210305_1036.py │ ├── 0140_auto_20210427_1746.py │ ├── 0141_auto_20210525_2153.py │ ├── 0142_auto_20211213_1312.py │ ├── 0143_auto_20220105_1256.py │ ├── 0144_auto_20220111_1620.py │ ├── 0145_auto_20220111_1736.py │ ├── 0146_majora_fact.py │ ├── 0147_majora_fact_counter.py │ ├── 0148_majora_fact_restricted.py │ ├── 0149_institute_credit_code_only.py │ ├── 0150_majoraartifactprocessrecord_unique_name.py │ ├── 0151_auto_20220226_1624.py │ ├── 0152_backfill_dnasequencingprocessrecord_uniquename.py │ └── __init__.py ├── models.py ├── public_util.py ├── public_views.py ├── receivers.py ├── renderers.py ├── resty_serializers.py ├── resty_views.py ├── serializers.py ├── signals.py ├── submodels │ ├── __init__.py │ └── supplemental.py ├── tables.py ├── tasks.py ├── templates │ ├── accounts │ │ ├── institute_success.html │ │ └── register_success.html │ ├── admin │ │ └── base_site.html │ ├── agreements.html │ ├── api_keys.html │ ├── artifact_layouts │ │ ├── biosample.html │ │ ├── digital.html │ │ ├── library.html │ │ ├── supplements │ │ │ └── coguk_collection.html │ │ └── tube.html │ ├── breadcrumbs.html │ ├── dataviews.html │ ├── detail_artifact.html │ ├── detail_process.html │ ├── detail_process.html.bak │ ├── footer.html │ ├── forms │ │ ├── account.html │ │ ├── credit.html │ │ ├── institute.html │ │ └── register.html │ ├── header.html │ ├── list_artifact.html │ ├── list_process.html │ ├── private │ │ ├── footer.html │ │ ├── header.html │ │ └── special │ │ │ └── dataview_list.html │ ├── profile.html │ ├── public │ │ ├── footer.html │ │ ├── header.html │ │ └── special │ │ │ └── pag_list.html │ ├── redoc.html │ ├── search.html │ ├── slack │ │ └── blank │ ├── tables │ │ ├── artifact-badges.html │ │ ├── biosample.html │ │ ├── checkin.html │ │ ├── command.html │ │ ├── default.html │ │ ├── digitalresource-profile.html │ │ ├── digitalresource.html │ │ ├── dt_biosample.html │ │ ├── dt_pag.html │ │ ├── extract.html │ │ ├── librarybiosample.html │ │ ├── metadata-badges.html │ │ ├── metadata.html │ │ ├── metric-badges.html │ │ ├── recurse_process.html │ │ ├── row_small.html │ │ └── tube.html │ ├── two_factor │ │ ├── _base.html │ │ ├── _base_focus.html │ │ ├── _header.html │ │ ├── _wizard_forms.html │ │ ├── core │ │ │ ├── setup.html │ │ │ └── setup_complete.html │ │ └── profile │ │ │ └── profile.html │ └── view_agreement.html ├── templatetags │ ├── __init__.py │ ├── instance.py │ └── pag.py ├── test │ ├── __init__.py │ ├── test_basic_api.py │ ├── test_biosampleartifact.py │ ├── test_libraryartifact.py │ ├── test_majoraartifact.py │ ├── test_mdv.py │ ├── test_pag.py │ ├── test_profiles.py │ ├── test_sequencingprocess.py │ ├── test_task.py │ └── util.py ├── urls.py ├── util.py └── views.py ├── manage.py ├── mylims ├── __init__.py ├── celery.py ├── settings.py.example ├── urls.py └── wsgi.py ├── requirements.txt ├── scripts ├── cleanup_celery.sh ├── kill.sh └── restart.sh ├── static ├── climb-covid-patch.png ├── inbound-ops-patch.png └── mask_50.png ├── tatl ├── __init__.py ├── apps.py ├── management │ └── commands │ │ ├── __init__.py │ │ ├── extend_dataview.py │ │ ├── grant_dataview.py │ │ ├── grant_group.py │ │ ├── grant_permission.py │ │ ├── list_dataviews.py │ │ ├── list_permissions.py │ │ ├── list_users.py │ │ ├── load_keydefs.py │ │ ├── mkgroup.py │ │ ├── two_factor_disable.py │ │ ├── useradd.py │ │ ├── userapprove.py │ │ ├── userdel.py │ │ └── usermv.py ├── middleware.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_tatlrequest_substitute_user.py │ ├── 0003_tatlrequest_remote_addr.py │ ├── 0004_tatlpermflex.py │ ├── 0005_auto_20200527_1328.py │ ├── 0006_tatlrequest_response_time.py │ ├── 0007_tatlrequest_response_uuid.py │ ├── 0008_tatltask.py │ ├── 0009_auto_20200807_1339.py │ ├── 0010_auto_20200814_1803.py │ ├── 0011_tatlpagerequest.py │ ├── 0012_tatlpagerequest_view_name.py │ ├── 0013_tatlpagerequest_view_path.py │ ├── 0014_auto_20200822_1554.py │ ├── 0015_auto_20200822_1557.py │ ├── 0016_auto_20200822_1647.py │ ├── 0017_auto_20200822_1709.py │ ├── 0018_auto_20200822_1710.py │ ├── 0019_tatlrequest_status_code.py │ ├── 0020_delete_tatlpagerequest.py │ ├── 0021_auto_20200822_1730.py │ ├── 0022_tatlrequest_is_api.py │ ├── 0023_auto_20200822_1820.py │ ├── 0024_oauth2codeonlyapplication.py │ ├── 0025_auto_20200828_1351.py │ ├── 0026_tatlverb_extra_context.py │ ├── 0027_auto_20210305_1034.py │ └── __init__.py ├── models.py ├── oauth2.py ├── receivers.py ├── templates │ ├── oauth2_provider │ │ ├── application_detail.html │ │ ├── application_form.html │ │ ├── authorize.html │ │ ├── authorized-oob.html │ │ └── base.html │ └── slack │ │ └── permflex ├── util.py └── views.py ├── version.py └── wsgi.ini.example /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.swp 3 | */settings.py 4 | static/* 5 | *.db 6 | *.sqlite3 7 | *.orig 8 | ignore/* 9 | venv*/ 10 | wsgi.ini 11 | restart.sh 12 | private/* 13 | majora_version_file 14 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | repos: 4 | - repo: https://github.com/pre-commit/pre-commit-hooks 5 | rev: v3.2.0 6 | hooks: 7 | - id: trailing-whitespace 8 | - id: end-of-file-fixer 9 | - id: check-yaml 10 | - id: check-added-large-files 11 | - repo: https://github.com/SamStudio8/pre-commit-django-uncommitted-migrations 12 | rev: 4efbca5e609c2e198037e434bd73afc9fc4b0985 13 | hooks: 14 | - id: django-uncommitted-migrations 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.6" # current default Python on Travis CI 4 | 5 | install: 6 | - pip install -r requirements.txt 7 | - cp mylims/settings.py.example mylims/settings.py 8 | - export SECRET=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1` 9 | - echo "SECRET_KEY='$SECRET'" >> mylims/settings.py 10 | - pip install coverage==6.1.1 11 | 12 | script: 13 | - coverage run --source='.' manage.py test 14 | 15 | after_success: 16 | - bash <(curl -s https://codecov.io/bash) 17 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## 12.9.9 2022-03-07 8 | ### Fixed 9 | * After two years of solid development, 1300 commits, 33 million API requests and over 2.5 million sequences, it's probably about time to give this thing a version number and CHANGELOG. 10 | * To whom it may concern, take care of this application. She might have saved lives. 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Samuel M. Nicholls 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /data/agreements/sendersampleid.txt: -------------------------------------------------------------------------------- 1 | eng-sendersampleid-phe-1 2 | Share UK-ENG sender_sample_id with Public Health England 3 | Shares central_sample_id and sender_sample_id for UK-ENG samples with PHE 4 | 2 2020-07-13 2020-04-06 5 | * 6 | I confirm that the following fields of metadata uploaded to Majora from my account can be provided to Public Health England to allow linkage to wider datasets: 7 | 8 | * sender_sample_id (Sample ID assigned by the sending laboratory and communnicated to SGSS) 9 | * central_sample_id (COG-UK sample ID) 10 | 11 | On 2021-05-17 this agreement was unilaterally updated to additionally provide the following fields to assist in sender_sample_id disambiguation, effective 2021-05-24: 12 | 13 | * collection_date (Date sample was collected) 14 | * received_date (Date sample was received) 15 | 16 | ## Criteria 17 | 18 | * Biosamples I have uploaded where adm1 is set to UK-ENG. 19 | * Existing biosamples uploaded since 2020-04-06 20 | * Future biosamples uploaded by my account where adm1 is set to UK-ENG. 21 | 22 | ## Termination 23 | 24 | This agreement can be terminated through this interface at any time. 25 | Terminating this agreement will stop these fields from being shared with PHE as part of future data sets. 26 | Terminating this agreement will not 'unshare' previously shared identifiers with PHE. 27 | 28 | -------------------------------------------------------------------------------- /data/mdv/DA1: -------------------------------------------------------------------------------- 1 | DA1 2 | National orphaned identifiers 3 | National orphaned identifiers 4 | BiosampleArtifact 5 | MF BiosampleArtifact central_sample_id 6 | MF BiosampleArtifact sender_sample_id 7 | MF BiosourceSamplingProcess adm1 8 | MF BiosourceSamplingProcess collection_date 9 | MF BiosourceSamplingProcess received_date 10 | FF created__biosourcesamplingprocess__collection_location_adm1 isnull bool 1 11 | -------------------------------------------------------------------------------- /data/mdv/PHE1: -------------------------------------------------------------------------------- 1 | PHE1 2 | Sample ID lookup for PHE 3 | Sample ID lookup for PHE as per Agreement eng-sendersampleid-phe-1 4 | BiosampleArtifact 5 | MF BiosampleArtifact central_sample_id 6 | MF BiosampleArtifact sender_sample_id 7 | MF BiosourceSamplingProcess collection_date 8 | MF BiosourceSamplingProcess received_date 9 | FF created__biosourcesamplingprocess__collection_location_adm1 exact str UK-ENG 10 | FF created__who__profile__agreements__agreement__slug exact str eng-sendersampleid-phe-1 11 | FF created__who__profile__agreements__is_terminated exact bool 0 12 | -------------------------------------------------------------------------------- /data/mdv/PHE1-FAST: -------------------------------------------------------------------------------- 1 | PHE1-FAST 2 | Faster sample ID lookup for PHE 3 | Faster sample ID lookup for PHE as per Agreement eng-sendersampleid-phe-1 4 | MajoraFact 5 | # MDV defines no ModelField (MF) or FilterField (FF) lines as 6 | # the PHE1-FAST dataview is hardcoded as a subtask in majora2/mdv_tasks.py 7 | # and is not configured dynamically from the database like the PHE1 view. 8 | # 9 | # The MDV entrypoint definition is mandatory and used to generate a 10 | # queryset as part of the init for an MDV, but the queryset is ignored. 11 | # As the queryset is ignored it is a waste of time to generate a long list 12 | # of IDs of objects that is immediately discarded! 13 | # We use MajoraFact as the entrypoint as it is the smallest queryset. 14 | -------------------------------------------------------------------------------- /data/orgs.txt: -------------------------------------------------------------------------------- 1 | Hypothetical University of Hooting HOOT 2 | Department of Hooting, Screeching and Cheeping DHSC 3 | -------------------------------------------------------------------------------- /data/qc/elan-minimal-test/testelan3-20220203-ill.qc: -------------------------------------------------------------------------------- 1 | COG-UK Elan Minimal QC 2 | Minimal ILL 3 | 3 2022-02-03 4 | R mean_depth - mapping mean_cov - - 0 - 5 | D mean_depth 6 | F technology - sequencing platform ILLUMINA EQ 7 | -------------------------------------------------------------------------------- /data/qc/elan-minimal-test/testelan3-20220203-ion.qc: -------------------------------------------------------------------------------- 1 | COG-UK Elan Minimal QC 2 | Minimal ION 3 | 3 2022-02-03 4 | R mean_depth - mapping mean_cov - - 0 - 5 | D mean_depth 6 | F technology - sequencing platform ION_TORRENT EQ 7 | -------------------------------------------------------------------------------- /data/qc/elan-minimal-test/testelan3-20220203-ont.qc: -------------------------------------------------------------------------------- 1 | COG-UK Elan Minimal QC 2 | Minimal ONT 3 | 3 2022-02-03 4 | R mean_depth - mapping mean_cov - - 0 - 5 | D mean_depth 6 | F technology - sequencing platform OXFORD_NANOPORE EQ 7 | -------------------------------------------------------------------------------- /data/qc/elan-minimal/elan2-20200421-ill.qc: -------------------------------------------------------------------------------- 1 | COG-UK Elan Minimal QC 2 | Minimal ILL 3 | 2 2020-04-21 4 | R breadth_confidence - sequence pc_masked - - - 50 5 | R contiguity_confidence - sequence longest_ungap - - 10000 - 6 | R mean_depth - mapping mean_cov - - 10 - 7 | R depth_confidence - mapping pc_pos_cov_gte10 - - 50 - 8 | D breadth_confidence AND contiguity_confidence 9 | D mean_depth 10 | D depth_confidence 11 | F technology - sequencing platform ILLUMINA EQ 12 | -------------------------------------------------------------------------------- /data/qc/elan-minimal/elan2-20200421-ion.qc: -------------------------------------------------------------------------------- 1 | COG-UK Elan Minimal QC 2 | Minimal ION 3 | 2 2021-04-16 4 | R breadth_confidence - sequence pc_masked - - - 50 5 | R contiguity_confidence - sequence longest_ungap - - 10000 - 6 | R mean_depth - mapping mean_cov - - 30 - 7 | R depth_confidence - mapping pc_pos_cov_gte20 - - 50 - 8 | D breadth_confidence AND contiguity_confidence 9 | D mean_depth 10 | D depth_confidence 11 | F technology - sequencing platform ION_TORRENT EQ 12 | -------------------------------------------------------------------------------- /data/qc/elan-minimal/elan2-20200421-ont.qc: -------------------------------------------------------------------------------- 1 | COG-UK Elan Minimal QC 2 | Minimal ONT 3 | 2 2020-04-21 4 | R breadth_confidence - sequence pc_masked - - - 50 5 | R contiguity_confidence - sequence longest_ungap - - 10000 - 6 | R mean_depth - mapping mean_cov - - 20 - 7 | R depth_confidence - mapping pc_pos_cov_gte20 - - 50 - 8 | D breadth_confidence AND contiguity_confidence 9 | D mean_depth 10 | D depth_confidence 11 | F technology - sequencing platform OXFORD_NANOPORE EQ 12 | -------------------------------------------------------------------------------- /data/qc/high-quality/gisaid1-20200421-ill.qc: -------------------------------------------------------------------------------- 1 | COG-UK High Quality Public 2 | High Quality Sequence ILL 3 | 1 2020-04-21 4 | R breadth_confidence - sequence pc_masked - - - 10 5 | R mean_depth - mapping mean_cov - - 10 - 6 | R depth_confidence - mapping pc_pos_cov_gte10 - - 90 - 7 | D breadth_confidence 8 | D mean_depth 9 | D depth_confidence 10 | F technology - sequencing platform ILLUMINA EQ 11 | -------------------------------------------------------------------------------- /data/qc/high-quality/gisaid1-20200421-ion.qc: -------------------------------------------------------------------------------- 1 | COG-UK High Quality Public 2 | High Quality Sequence ION 3 | 2 2021-04-16 4 | R breadth_confidence - sequence pc_masked - - - 10 5 | R mean_depth - mapping mean_cov - - 30 - 6 | R depth_confidence - mapping pc_pos_cov_gte20 - - 90 - 7 | D breadth_confidence 8 | D mean_depth 9 | D depth_confidence 10 | F technology - sequencing platform ION_TORRENT EQ 11 | -------------------------------------------------------------------------------- /data/qc/high-quality/gisaid1-20200421-ont.qc: -------------------------------------------------------------------------------- 1 | COG-UK High Quality Public 2 | High Quality Sequence ONT 3 | 1 2020-04-21 4 | R breadth_confidence - sequence pc_masked - - - 10 5 | R mean_depth - mapping mean_cov - - 20 - 6 | R depth_confidence - mapping pc_pos_cov_gte20 - - 90 - 7 | D breadth_confidence 8 | D mean_depth 9 | D depth_confidence 10 | F technology - sequencing platform OXFORD_NANOPORE EQ 11 | -------------------------------------------------------------------------------- /deku/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/deku/__init__.py -------------------------------------------------------------------------------- /deku/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | class DekuConfig(AppConfig): 4 | name = 'deku' 5 | -------------------------------------------------------------------------------- /deku/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/deku/migrations/__init__.py -------------------------------------------------------------------------------- /deku/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /deku/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/deku/test/__init__.py -------------------------------------------------------------------------------- /deku/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, re_path, include 2 | from django.views.generic import TemplateView 3 | from django.views.decorators.csrf import csrf_exempt 4 | 5 | from . import views 6 | 7 | urlpatterns = [ 8 | path('accounts/list/', views.list_all_profiles, name='list_all_profiles'), 9 | 10 | path('institute/profiles/', views.list_site_profiles, name='list_site_profiles'), 11 | ] 12 | -------------------------------------------------------------------------------- /inbound-ops-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/inbound-ops-patch.png -------------------------------------------------------------------------------- /majora2/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/majora2/__init__.py -------------------------------------------------------------------------------- /majora2/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.db import models 3 | 4 | from . import models as m 5 | 6 | admin.site.register(m.DigitalResourceArtifact) 7 | admin.site.register(m.DigitalResourceGroup) 8 | admin.site.register(m.DigitalResourceNode) 9 | admin.site.register(m.TubeArtifact) 10 | admin.site.register(m.TubeContainerGroup) 11 | admin.site.register(m.MajoraArtifactProcessGroup) 12 | admin.site.register(m.MajoraArtifactProcessTest) 13 | admin.site.register(m.MajoraArtifactProcessRecordTest) 14 | admin.site.register(m.MajoraArtifactGroup) 15 | admin.site.register(m.BiosampleArtifact) 16 | admin.site.register(m.BiosourceSamplingProcess) 17 | admin.site.register(m.BiosampleSource) 18 | admin.site.register(m.LabCheckinProcess) 19 | admin.site.register(m.LabCheckinProcessRecord) 20 | 21 | 22 | admin.site.register(m.DigitalResourceCommand) 23 | admin.site.register(m.DigitalResourceCommandGroup) 24 | admin.site.register(m.DigitalResourceCommandPipelineGroup) 25 | admin.site.register(m.DigitalResourceCommandRecord) 26 | 27 | admin.site.register(m.MajoraMetaRecord) 28 | admin.site.register(m.Favourite) 29 | admin.site.register(m.Institute) 30 | -------------------------------------------------------------------------------- /majora2/authentication.py: -------------------------------------------------------------------------------- 1 | from rest_framework.authentication import TokenAuthentication 2 | from rest_framework import exceptions, permissions 3 | from tatl.models import TatlRequest, TatlPermFlex 4 | 5 | from django.utils import timezone 6 | 7 | from majora2 import models 8 | import json 9 | import uuid 10 | 11 | class TaskOwnerReadPermission(permissions.BasePermission): 12 | def has_object_permission(self, request, view, obj): 13 | return request.user == obj.user 14 | 15 | class DataviewReadPermission(permissions.BasePermission): 16 | def has_permission(self, request, view): 17 | mdv_code = request.query_params.get("mdv") 18 | if not mdv_code: 19 | return False 20 | else: 21 | try: 22 | mdv = models.MajoraDataview.objects.get(code_name=mdv_code) 23 | except models.MajoraDataview.DoesNotExist: 24 | return False 25 | 26 | p = models.MajoraDataviewUserPermission.objects.filter( 27 | profile__user=request.user, 28 | dataview__code_name=mdv_code, 29 | is_revoked=False, 30 | validity_start__lt=timezone.now(), 31 | validity_end__gt=timezone.now() 32 | ).first() 33 | if p: 34 | tflex = TatlPermFlex( 35 | user = request.user, 36 | substitute_user = None, 37 | used_permission = "majora2.v3.DataviewReadPermission", 38 | timestamp = timezone.now(), 39 | request=request.treq, 40 | content_object=mdv, 41 | #extra_context = json.dumps({ 42 | #}), 43 | ) 44 | tflex.save() 45 | return True 46 | return False #TODO logthis 47 | 48 | -------------------------------------------------------------------------------- /majora2/context_processors.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | # Some people access the file system or us processes to read git 4 | # I think that is a bit creepy so lets just read the ENV 5 | def majora_version(request): 6 | return { 7 | "majora_version": os.getenv("CURRENT_MAJORA_VERSION"), 8 | "majora_commit": os.getenv("CURRENT_MAJORA_HASH"), 9 | "majora_name": os.getenv("CURRENT_MAJORA_NAME"), 10 | } 11 | -------------------------------------------------------------------------------- /majora2/fixed_data.py: -------------------------------------------------------------------------------- 1 | def api_biosample_add(user): 2 | return { 3 | 'source_type': "human", 4 | 'source_taxon': '2697049', 5 | 'country': "United Kingdom", 6 | 'submitting_user': user.username, 7 | 'submission_org': user.profile.institute.id if hasattr(user, "profile") and not user.profile.institute.code.startswith("?") else None 8 | } 9 | 10 | FIXED_DATA = { 11 | "api.artifact.biosample.add": api_biosample_add, 12 | } 13 | 14 | def fill_fixed_data(k, user=None): 15 | if k in FIXED_DATA: 16 | return FIXED_DATA[k](user) 17 | else: 18 | return {} 19 | 20 | RESTRICTED_METADATA = [ 21 | "investigation" 22 | ] 23 | -------------------------------------------------------------------------------- /majora2/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/majora2/management/__init__.py -------------------------------------------------------------------------------- /majora2/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/majora2/management/commands/__init__.py -------------------------------------------------------------------------------- /majora2/management/commands/load_orgs.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand, CommandError 2 | from django.contrib.auth.models import User, Permission 3 | 4 | from majora2 import models 5 | from tatl import models as tmodels 6 | from django.utils import timezone 7 | 8 | class Command(BaseCommand): 9 | help = "Load a list of organisations" 10 | def add_arguments(self, parser): 11 | parser.add_argument('filename') 12 | 13 | def handle(self, *args, **options): 14 | su = User.objects.get(is_superuser=True) 15 | fh = open(options["filename"]) 16 | for line in fh: 17 | fields = line.strip().split('\t') 18 | code = fields[1] 19 | name = fields[0] 20 | org, created = models.Institute.objects.get_or_create(code=code, name=name) 21 | org.save() 22 | if created: 23 | treq = tmodels.TatlPermFlex( 24 | user = su, 25 | substitute_user = None, 26 | used_permission = "majora2.management.commands.load_orgs", 27 | timestamp = timezone.now(), 28 | content_object = org, 29 | ) 30 | treq.save() 31 | -------------------------------------------------------------------------------- /majora2/management/commands/mknode.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand, CommandError 2 | from django.contrib.auth.models import User, Permission 3 | 4 | from majora2 import models 5 | from majora2 import util 6 | from tatl import models as tmodels 7 | from django.utils import timezone 8 | 9 | class Command(BaseCommand): 10 | help = "Add a DigitalResourceNode" 11 | def add_arguments(self, parser): 12 | parser.add_argument('name') 13 | 14 | def handle(self, *args, **options): 15 | su = User.objects.get(is_superuser=True) 16 | 17 | node, created = util.mkroot(options["name"]) 18 | if created: 19 | print("Node %s created" % node.unique_name) 20 | treq = tmodels.TatlPermFlex( 21 | user = su, 22 | substitute_user = None, 23 | used_permission = "majora2.management.commands.mkroot", 24 | timestamp = timezone.now(), 25 | content_object = node, 26 | ) 27 | treq.save() 28 | else: 29 | print("Node %s already exists" % node.unique_name) 30 | -------------------------------------------------------------------------------- /majora2/mdv_tasks.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from django.db.models import F 4 | 5 | from majora2 import models 6 | 7 | def subtask_get_mdv_v3_phe1_faster(): 8 | ret = [] 9 | for sample in models.BiosampleArtifact.objects.filter( 10 | created__biosourcesamplingprocess__collection_location_adm1="UK-ENG", 11 | created__who__profile__agreements__agreement__slug="eng-sendersampleid-phe-1", 12 | created__who__profile__agreements__is_terminated=False 13 | ).values( 14 | "central_sample_id", 15 | "sender_sample_id", 16 | adm1=F("created__biosourcesamplingprocess__collection_location_adm1"), 17 | collection_date=F("created__biosourcesamplingprocess__collection_date"), 18 | received_date=F("created__biosourcesamplingprocess__received_date"), 19 | ): 20 | ret.append({ 21 | "central_sample_id": sample["central_sample_id"], 22 | "created": { 23 | "adm1": sample["adm1"], 24 | "collection_date": datetime.strftime(sample["collection_date"], "%Y-%m-%d") if sample["collection_date"] else None, 25 | "process_model": "BiosourceSamplingProcess", # backward compat 26 | "received_date": datetime.strftime(sample["received_date"], "%Y-%m-%d") if sample["received_date"] else None, 27 | }, 28 | "sender_sample_id": sample["sender_sample_id"], 29 | }) 30 | return ret 31 | -------------------------------------------------------------------------------- /majora2/migrations/0002_institution.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-18 10:47 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0001_20200317_squashed'), 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='Institution', 15 | fields=[ 16 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 17 | ('code', models.CharField(max_length=10)), 18 | ('name', models.CharField(max_length=100)), 19 | ], 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /majora2/migrations/0003_auto_20200318_1058.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-18 10:58 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0002_institution'), 11 | ] 12 | 13 | operations = [ 14 | migrations.RenameModel( 15 | old_name='Institution', 16 | new_name='Institute', 17 | ), 18 | migrations.AddField( 19 | model_name='profile', 20 | name='institute', 21 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='majora2.Institute'), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0004_make_ins.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-18 10:51 2 | 3 | from django.db import migrations 4 | 5 | def make_institute(apps, schema_editor): 6 | Profile = apps.get_model("majora2", "Profile") 7 | Institute = apps.get_model("majora2", "Institute") 8 | for profile in Profile.objects.all(): 9 | institute, created = Institute.objects.get_or_create(code="?", name=profile.organisation) 10 | institute.save() 11 | profile.institute = institute 12 | profile.save() 13 | 14 | class Migration(migrations.Migration): 15 | 16 | dependencies = [ 17 | ('majora2', '0003_auto_20200318_1058'), 18 | ] 19 | 20 | operations = [ 21 | migrations.RunPython(make_institute), 22 | ] 23 | -------------------------------------------------------------------------------- /majora2/migrations/0005_auto_20200318_1116.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-18 11:16 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0004_make_ins'), 11 | ] 12 | 13 | operations = [ 14 | migrations.RemoveField( 15 | model_name='profile', 16 | name='organisation', 17 | ), 18 | migrations.AddField( 19 | model_name='biosourcesamplingprocess', 20 | name='collection_org', 21 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='majora2.Institute'), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0006_auto_20200318_1535.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-18 15:35 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0005_auto_20200318_1116'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='biosourcesamplingprocess', 15 | old_name='collection_location_adm1', 16 | new_name='collection_location_adm2', 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0007_auto_20200318_1535.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-18 15:35 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0006_auto_20200318_1535'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='biosourcesamplingprocess', 15 | old_name='collection_location_adm0', 16 | new_name='collection_location_adm1', 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0008_profile_api_key.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-18 17:34 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0007_auto_20200318_1535'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='profile', 15 | name='api_key', 16 | field=models.CharField(blank=True, max_length=128, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0009_api_keys.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-18 17:37 2 | 3 | from django.db import migrations 4 | import uuid 5 | 6 | def make_keys(apps, schema_editor): 7 | Profile = apps.get_model("majora2", "Profile") 8 | for profile in Profile.objects.all(): 9 | profile.api_key = uuid.uuid4() 10 | profile.save() 11 | 12 | class Migration(migrations.Migration): 13 | 14 | dependencies = [ 15 | ('majora2', '0008_profile_api_key'), 16 | ] 17 | 18 | operations = [ 19 | migrations.RunPython(make_keys), 20 | ] 21 | -------------------------------------------------------------------------------- /majora2/migrations/0010_auto_20200318_1739.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-18 17:39 2 | 3 | from django.db import migrations, models 4 | import uuid 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0009_api_keys'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='profile', 16 | name='api_key', 17 | field=models.CharField(default=uuid.uuid4, max_length=128), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0011_auto_20200319_1234.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-19 12:34 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0010_auto_20200318_1739'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='biosourcesamplingprocess', 15 | old_name='collection_org', 16 | new_name='submission_org', 17 | ), 18 | migrations.RenameField( 19 | model_name='biosourcesamplingprocess', 20 | old_name='collection_by', 21 | new_name='submitted_by', 22 | ), 23 | migrations.AddField( 24 | model_name='biosamplesource', 25 | name='source_age', 26 | field=models.PositiveIntegerField(blank=True, null=True), 27 | ), 28 | migrations.AddField( 29 | model_name='biosourcesamplingprocess', 30 | name='private_collection_location_adm2', 31 | field=models.CharField(blank=True, max_length=100, null=True), 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /majora2/migrations/0012_auto_20200319_1235.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-19 12:35 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0011_auto_20200319_1234'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='biosourcesamplingprocess', 16 | name='collected_by', 17 | field=models.CharField(blank=True, max_length=100, null=True), 18 | ), 19 | migrations.AddField( 20 | model_name='biosourcesamplingprocess', 21 | name='collection_org', 22 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='collected_sample_records', to='majora2.Institute'), 23 | ), 24 | migrations.AlterField( 25 | model_name='biosourcesamplingprocess', 26 | name='submission_org', 27 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_sample_records', to='majora2.Institute'), 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /majora2/migrations/0013_biosampleartifact_sample_site.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-19 12:42 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0012_auto_20200319_1235'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='biosampleartifact', 15 | name='sample_site', 16 | field=models.CharField(blank=True, max_length=24, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0014_biosourcesamplingprocess_submission_user.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-19 13:00 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('majora2', '0013_biosampleartifact_sample_site'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='biosourcesamplingprocess', 18 | name='submission_user', 19 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='submitted_sample_records', to=settings.AUTH_USER_MODEL), 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /majora2/migrations/0015_remove_biosampleartifact_collection.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-19 14:25 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0014_biosourcesamplingprocess_submission_user'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='biosampleartifact', 15 | name='collection', 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0016_biosampleartifact_collection.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-19 14:25 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0015_remove_biosampleartifact_collection'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='biosampleartifact', 16 | name='collection', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='biosamples', to='majora2.BiosourceSamplingProcessRecord'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0017_auto_20200319_1503.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-19 15:03 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0016_biosampleartifact_collection'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='biosamplesource', 15 | name='source_age', 16 | ), 17 | migrations.AddField( 18 | model_name='biosourcesamplingprocess', 19 | name='source_age', 20 | field=models.PositiveIntegerField(blank=True, null=True), 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /majora2/migrations/0018_auto_20200319_1712.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-19 17:12 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0017_auto_20200319_1503'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='biosampleartifact', 15 | name='secondary_identifier', 16 | field=models.CharField(blank=True, max_length=256, null=True), 17 | ), 18 | migrations.AddField( 19 | model_name='biosourcesamplingprocess', 20 | name='source_sex', 21 | field=models.CharField(blank=True, max_length=10, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0020_auto_20200322_1545.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-22 15:45 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0019_auto_20200319_1928'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='biosampleartifact', 15 | old_name='sample_site', 16 | new_name='swab_site', 17 | ), 18 | migrations.RemoveField( 19 | model_name='majoraartifact', 20 | name='unique_name', 21 | ), 22 | migrations.AddField( 23 | model_name='biosampleartifact', 24 | name='central_sample_id', 25 | field=models.CharField(blank=True, max_length=48, null=True, unique=True), 26 | ), 27 | migrations.AddField( 28 | model_name='biosampleartifact', 29 | name='root_sample_id', 30 | field=models.CharField(blank=True, max_length=48, null=True, unique=True), 31 | ), 32 | migrations.AddField( 33 | model_name='biosampleartifact', 34 | name='sender_sample_id', 35 | field=models.CharField(blank=True, max_length=48, null=True, unique=True), 36 | ), 37 | ] 38 | -------------------------------------------------------------------------------- /majora2/migrations/0021_auto_20200322_1611.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-22 16:11 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0020_auto_20200322_1545'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='biosampleartifact', 15 | old_name='swab_site', 16 | new_name='sample_site', 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0022_auto_20200322_1616.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-22 16:16 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0021_auto_20200322_1611'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='biosampleartifact', 15 | name='root_sample_id', 16 | field=models.CharField(blank=True, max_length=48, null=True), 17 | ), 18 | migrations.AlterField( 19 | model_name='biosampleartifact', 20 | name='sender_sample_id', 21 | field=models.CharField(blank=True, max_length=48, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0023_biosampleartifact_secondary_accession.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-22 16:34 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0022_auto_20200322_1616'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='biosampleartifact', 15 | name='secondary_accession', 16 | field=models.CharField(blank=True, max_length=256, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0024_biosamplesource_secondary_id.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-23 09:37 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0023_biosampleartifact_secondary_accession'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='biosamplesource', 15 | name='secondary_id', 16 | field=models.CharField(blank=True, max_length=48, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0025_county.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-23 10:30 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0024_biosamplesource_secondary_id'), 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='County', 15 | fields=[ 16 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 17 | ('code', models.CharField(max_length=10)), 18 | ('name', models.CharField(max_length=100)), 19 | ], 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /majora2/migrations/0026_auto_20200323_1149.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-23 11:49 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0025_county'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='county', 15 | name='country_code', 16 | field=models.CharField(default='?', max_length=10), 17 | preserve_default=False, 18 | ), 19 | migrations.AlterField( 20 | model_name='county', 21 | name='code', 22 | field=models.CharField(blank=True, max_length=10, null=True), 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /majora2/migrations/0027_auto_20200323_1635.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-23 16:35 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0026_auto_20200323_1149'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='majoraartifactprocessrecord', 16 | name='bridge_artifact', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='bridge_process', to='majora2.MajoraArtifact'), 18 | ), 19 | migrations.AddField( 20 | model_name='majoraartifactprocessrecord', 21 | name='bridge_group', 22 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='bridge_process', to='majora2.MajoraArtifactGroup'), 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /majora2/migrations/0028_auto_20200324_2219.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-24 22:19 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0027_auto_20200323_1635'), 11 | ] 12 | 13 | operations = [ 14 | migrations.RemoveField( 15 | model_name='libraryartifact', 16 | name='design_description', 17 | ), 18 | migrations.RemoveField( 19 | model_name='libraryartifact', 20 | name='library_selection', 21 | ), 22 | migrations.RemoveField( 23 | model_name='libraryartifact', 24 | name='library_source', 25 | ), 26 | migrations.RemoveField( 27 | model_name='libraryartifact', 28 | name='library_strategy', 29 | ), 30 | migrations.AddField( 31 | model_name='libraryartifact', 32 | name='pooling', 33 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='library', to='majora2.LibraryPoolingProcess'), 34 | ), 35 | migrations.AddField( 36 | model_name='librarypoolingprocessrecord', 37 | name='library_selection', 38 | field=models.CharField(blank=True, max_length=24, null=True), 39 | ), 40 | migrations.AddField( 41 | model_name='librarypoolingprocessrecord', 42 | name='library_source', 43 | field=models.CharField(blank=True, max_length=24, null=True), 44 | ), 45 | migrations.AddField( 46 | model_name='librarypoolingprocessrecord', 47 | name='library_strategy', 48 | field=models.CharField(blank=True, max_length=24, null=True), 49 | ), 50 | ] 51 | -------------------------------------------------------------------------------- /majora2/migrations/0029_auto_20200324_2231.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-24 22:31 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0028_auto_20200324_2219'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='libraryartifact', 15 | old_name='library_layout_config', 16 | new_name='layout_config', 17 | ), 18 | migrations.RenameField( 19 | model_name='libraryartifact', 20 | old_name='library_layout_length', 21 | new_name='layout_read_length', 22 | ), 23 | migrations.AddField( 24 | model_name='libraryartifact', 25 | name='layout_insert_length', 26 | field=models.PositiveIntegerField(blank=True, null=True), 27 | ), 28 | migrations.AddField( 29 | model_name='libraryartifact', 30 | name='seq_kit', 31 | field=models.CharField(blank=True, max_length=48, null=True), 32 | ), 33 | migrations.AddField( 34 | model_name='libraryartifact', 35 | name='seq_protocol', 36 | field=models.CharField(blank=True, max_length=48, null=True), 37 | ), 38 | ] 39 | -------------------------------------------------------------------------------- /majora2/migrations/0030_auto_20200324_2358.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-24 23:58 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0029_auto_20200324_2231'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='dnasequencingprocess', 15 | name='end_time', 16 | field=models.DateTimeField(blank=True, null=True), 17 | ), 18 | migrations.AlterField( 19 | model_name='dnasequencingprocess', 20 | name='instrument_model', 21 | field=models.CharField(max_length=48), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0031_auto_20200325_1834.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-25 18:34 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0030_auto_20200324_2358'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='biosampleartifact', 15 | old_name='sample_type', 16 | new_name='sample_type_collected', 17 | ), 18 | migrations.AlterField( 19 | model_name='majoraartifactgroup', 20 | name='unique_name', 21 | field=models.CharField(blank=True, max_length=128, null=True, unique=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0032_auto_20200325_1835.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-25 18:35 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0031_auto_20200325_1834'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='biosampleartifact', 15 | old_name='specimen_type', 16 | new_name='sample_type_curent', 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0033_auto_20200326_1516.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-26 15:16 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0032_auto_20200325_1835'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='majorametarecord', 15 | name='timestamp', 16 | field=models.DateTimeField(blank=True, null=True), 17 | ), 18 | migrations.AlterField( 19 | model_name='majorametarecord', 20 | name='value', 21 | field=models.CharField(blank=True, max_length=128, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0034_abstractbioinformaticsprocess.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-26 15:54 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0033_auto_20200326_1516'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='AbstractBioinformaticsProcess', 16 | fields=[ 17 | ('majoraartifactprocess_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='majora2.MajoraArtifactProcess')), 18 | ], 19 | options={ 20 | 'abstract': False, 21 | 'base_manager_name': 'objects', 22 | }, 23 | bases=('majora2.majoraartifactprocess',), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /majora2/migrations/0035_dnasequencingprocess_run_name.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-27 09:59 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0034_abstractbioinformaticsprocess'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='dnasequencingprocess', 15 | name='run_name', 16 | field=models.CharField(blank=True, max_length=128, null=True, unique=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0036_auto_20200327_1000.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-27 10:00 2 | 3 | from django.db import migrations 4 | 5 | def copy_dna_id(apps, schema_editor): 6 | DNASequencingProcess = apps.get_model("majora2", "DNASequencingProcess") 7 | for d in DNASequencingProcess.objects.all(): 8 | d.run_name = str(d.id) 9 | d.save() 10 | 11 | class Migration(migrations.Migration): 12 | 13 | dependencies = [ 14 | ('majora2', '0035_dnasequencingprocess_run_name'), 15 | ] 16 | 17 | operations = [ 18 | migrations.RunPython(copy_dna_id), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0037_auto_20200327_1005.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-27 10:05 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0036_auto_20200327_1000'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='dnasequencingprocess', 15 | name='run_name', 16 | field=models.CharField(max_length=128, unique=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0038_auto_20200327_1658.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-27 16:58 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0037_auto_20200327_1005'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='abstractbioinformaticsprocess', 15 | name='pipe_kind', 16 | field=models.CharField(blank=True, max_length=64, null=True), 17 | ), 18 | migrations.AddField( 19 | model_name='abstractbioinformaticsprocess', 20 | name='pipe_name', 21 | field=models.CharField(blank=True, max_length=48, null=True), 22 | ), 23 | migrations.AddField( 24 | model_name='abstractbioinformaticsprocess', 25 | name='pipe_version', 26 | field=models.CharField(blank=True, max_length=48, null=True), 27 | ), 28 | migrations.DeleteModel( 29 | name='BasecallingProcess', 30 | ), 31 | migrations.DeleteModel( 32 | name='BasecallingProcessRecord', 33 | ), 34 | ] 35 | -------------------------------------------------------------------------------- /majora2/migrations/0039_biosourcesamplingprocess_received_date.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-29 17:00 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0038_auto_20200327_1658'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='biosourcesamplingprocess', 15 | name='received_date', 16 | field=models.DateField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0040_auto_20200329_1814.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-29 18:14 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0039_biosourcesamplingprocess_received_date'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='biosampleartifact', 15 | old_name='sample_type_curent', 16 | new_name='sample_type_current', 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0041_majoraartifact_created.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-31 17:05 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0040_auto_20200329_1814'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='majoraartifact', 16 | name='created', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='artifacts_created', to='majora2.MajoraArtifactProcess'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0042_auto_20200331_1727.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-31 17:27 2 | 3 | from django.db import migrations 4 | 5 | def copy_pool(apps, schema_editor): 6 | LibraryArtifact = apps.get_model("majora2", "LibraryArtifact") 7 | for l in LibraryArtifact.objects.all(): 8 | if l.pooling: 9 | l.created = l.pooling 10 | l.save() 11 | 12 | class Migration(migrations.Migration): 13 | 14 | dependencies = [ 15 | ('majora2', '0041_majoraartifact_created'), 16 | ] 17 | 18 | operations = [ 19 | migrations.RunPython(copy_pool), 20 | ] 21 | -------------------------------------------------------------------------------- /majora2/migrations/0043_remove_libraryartifact_pooling.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-31 17:31 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0042_auto_20200331_1727'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='libraryartifact', 15 | name='pooling', 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0044_auto_20200331_1735.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-31 17:35 2 | 3 | from django.db import migrations 4 | 5 | def copy_collection(apps, schema_editor): 6 | BiosampleArtifact = apps.get_model("majora2", "BiosampleArtifact") 7 | for b in BiosampleArtifact.objects.all(): 8 | if b.collection: 9 | b.created = b.collection.process 10 | b.save() 11 | 12 | class Migration(migrations.Migration): 13 | 14 | dependencies = [ 15 | ('majora2', '0043_remove_libraryartifact_pooling'), 16 | ] 17 | 18 | operations = [ 19 | migrations.RunPython(copy_collection), 20 | ] 21 | -------------------------------------------------------------------------------- /majora2/migrations/0045_remove_biosampleartifact_collection.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-03-31 17:44 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0044_auto_20200331_1735'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='biosampleartifact', 15 | name='collection', 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0046_auto_20200405_1232.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-05 12:32 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0045_remove_biosampleartifact_collection'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='dnasequencingprocess', 15 | name='run_group', 16 | field=models.CharField(blank=True, max_length=128, null=True), 17 | ), 18 | migrations.AlterField( 19 | model_name='abstractbioinformaticsprocess', 20 | name='pipe_name', 21 | field=models.CharField(blank=True, max_length=96, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0047_auto_20200405_1232.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-05 12:32 2 | 3 | from django.db import migrations 4 | 5 | def copy_run_name(apps, schema_editor): 6 | DNASequencingProcess = apps.get_model("majora2", "DNASequencingProcess") 7 | for p in DNASequencingProcess.objects.all(): 8 | if not p.run_group: 9 | p.run_group = p.run_name 10 | p.save() 11 | 12 | class Migration(migrations.Migration): 13 | 14 | dependencies = [ 15 | ('majora2', '0046_auto_20200405_1232'), 16 | ] 17 | 18 | operations = [ 19 | migrations.RunPython(copy_run_name), 20 | ] 21 | -------------------------------------------------------------------------------- /majora2/migrations/0048_auto_20200405_1624.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-05 16:24 2 | 3 | from django.db import migrations 4 | 5 | def copy_dar_dicename(apps, schema_editor): 6 | DigitalResourceGroup = apps.get_model("majora2", "DigitalResourceGroup") 7 | for g in DigitalResourceGroup.objects.all(): 8 | if g.unique_name and g.unique_name.startswith("sequencing-dummy-tree") and not g.dice_name: 9 | g.dice_name = g.unique_name 10 | g.save() 11 | 12 | class Migration(migrations.Migration): 13 | 14 | dependencies = [ 15 | ('majora2', '0047_auto_20200405_1232'), 16 | ] 17 | 18 | operations = [ 19 | migrations.RunPython(copy_dar_dicename), 20 | ] 21 | -------------------------------------------------------------------------------- /majora2/migrations/0049_auto_20200406_0853.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-06 08:53 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0048_auto_20200405_1624'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='majoraartifact', 15 | name='dice_name', 16 | field=models.CharField(blank=True, max_length=96, null=True, unique=True), 17 | ), 18 | migrations.AlterField( 19 | model_name='majoraartifact', 20 | name='meta_name', 21 | field=models.CharField(blank=True, max_length=96, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0050_auto_20200406_0855.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-06 08:55 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0049_auto_20200406_0853'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='majoraartifactgroup', 15 | name='dice_name', 16 | field=models.CharField(blank=True, max_length=96, null=True, unique=True), 17 | ), 18 | migrations.AlterField( 19 | model_name='majoraartifactgroup', 20 | name='meta_name', 21 | field=models.CharField(blank=True, max_length=96, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0051_majoraartifactprocess_hook_name.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-09 12:33 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0050_auto_20200406_0855'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='majoraartifactprocess', 15 | name='hook_name', 16 | field=models.CharField(blank=True, max_length=256, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0052_pipehook.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-10 09:30 2 | 3 | from django.db import migrations 4 | 5 | def bioinfo_process_hook_names(apps, schema_editor): 6 | DigitalResourceArtifact = apps.get_model("majora2", "DigitalResourceArtifact") 7 | for dra in DigitalResourceArtifact.objects.filter(current_kind="consensus"): 8 | if dra.created: 9 | p = dra.created 10 | 11 | current_name = None 12 | for record in p.records.all(): 13 | if record.in_artifact: 14 | try: 15 | if record.in_artifact.dice_name: 16 | current_name = record.in_artifact.dice_name 17 | break 18 | except: 19 | pass 20 | 21 | if not p.hook_name and current_name: 22 | p.hook_name = "bioinfo-%s" % current_name.replace("sequencing-dummy-reads-", "") 23 | p.save() 24 | 25 | class Migration(migrations.Migration): 26 | 27 | dependencies = [ 28 | ('majora2', '0051_majoraartifactprocess_hook_name'), 29 | ] 30 | 31 | operations = [ 32 | migrations.RunPython(bioinfo_process_hook_names), 33 | ] 34 | -------------------------------------------------------------------------------- /majora2/migrations/0053_auto_20200411_0952.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-11 09:52 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0052_pipehook'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='majorametarecord', 16 | name='artifact', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='metadata', to='majora2.MajoraArtifact'), 18 | ), 19 | migrations.AlterField( 20 | model_name='majorametarecord', 21 | name='group', 22 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='metadata', to='majora2.MajoraArtifactGroup'), 23 | ), 24 | migrations.AlterField( 25 | model_name='majorametarecord', 26 | name='pgroup', 27 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='metadata', to='majora2.MajoraArtifactProcessGroup'), 28 | ), 29 | migrations.AlterField( 30 | model_name='majorametarecord', 31 | name='process', 32 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='metadata', to='majora2.MajoraArtifactProcess'), 33 | ), 34 | ] 35 | -------------------------------------------------------------------------------- /majora2/migrations/0055_auto_20200419_1308.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-19 13:08 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('majora2', '0054_auto_20200411_1013'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='PublishedArtifactGroup', 18 | fields=[ 19 | ('majoraartifactgroup_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='majora2.MajoraArtifactGroup')), 20 | ('published_name', models.CharField(max_length=128)), 21 | ('published_version', models.PositiveIntegerField()), 22 | ('published_date', models.DateField()), 23 | ('is_draft', models.BooleanField(default=False)), 24 | ('is_latest', models.BooleanField(default=False)), 25 | ('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), 26 | ], 27 | bases=('majora2.majoraartifactgroup',), 28 | ), 29 | migrations.AddConstraint( 30 | model_name='publishedartifactgroup', 31 | constraint=models.UniqueConstraint(fields=('published_name', 'is_latest'), name='is_only_published'), 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /majora2/migrations/0056_temporaryaccessionrecord.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-19 14:50 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0055_auto_20200419_1308'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='TemporaryAccessionRecord', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('service', models.CharField(max_length=64)), 19 | ('primary_accession', models.CharField(max_length=64)), 20 | ('secondary_accesison', models.CharField(blank=True, max_length=64, null=True)), 21 | ('tertiary_accession', models.CharField(blank=True, max_length=64, null=True)), 22 | ('pag', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='accessions', to='majora2.PublishedArtifactGroup')), 23 | ], 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /majora2/migrations/0057_publishedartifactgroup_is_public.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-22 16:46 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0056_temporaryaccessionrecord'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='publishedartifactgroup', 15 | name='is_public', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0059_digitalresourceartifact_current_path.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-25 14:38 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0058_auto_20200425_1258'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='digitalresourceartifact', 15 | name='current_path', 16 | field=models.CharField(blank=True, max_length=1024, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0060_dar_current_path.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-25 14:44 2 | 3 | from django.db import migrations 4 | 5 | def dra_path(apps, schema_editor): 6 | DigitalResourceArtifact = apps.get_model("majora2", "DigitalResourceArtifact") 7 | for dra in DigitalResourceArtifact.objects.all(): 8 | if dra.primary_group: 9 | s = dra.primary_group.path + '/' + dra.current_name 10 | try: 11 | return s.split(":/")[1] 12 | except: 13 | return s 14 | else: 15 | return dra.current_name 16 | dra.current_path = s 17 | dra.save() 18 | 19 | class Migration(migrations.Migration): 20 | 21 | dependencies = [ 22 | ('majora2', '0059_digitalresourceartifact_current_path'), 23 | ] 24 | 25 | operations = [ 26 | migrations.RunPython(dra_path), 27 | ] 28 | -------------------------------------------------------------------------------- /majora2/migrations/0063_auto_20200425_2323.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-25 23:23 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0062_auto_20200425_2235'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='pagqualitybasictestdecision', 15 | name='op', 16 | field=models.CharField(blank=True, max_length=3, null=True), 17 | ), 18 | migrations.AlterField( 19 | model_name='pagqualitytest', 20 | name='name', 21 | field=models.CharField(max_length=64, unique=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0064_auto_20200426_0137.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-26 01:37 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0063_auto_20200425_2323'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='pagqualityreportdecisionrecord', 15 | name='is_fail', 16 | field=models.BooleanField(default=False), 17 | ), 18 | migrations.AddField( 19 | model_name='pagqualityreportrulerecord', 20 | name='is_fail', 21 | field=models.BooleanField(default=False), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0067_auto_20200428_0134.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-04-28 01:34 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0066_auto_20200427_2327'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='temporarymajoraartifactmetric_sequence', 15 | name='pc_acgt', 16 | field=models.FloatField(), 17 | ), 18 | migrations.AlterField( 19 | model_name='temporarymajoraartifactmetric_sequence', 20 | name='pc_invalid', 21 | field=models.FloatField(), 22 | ), 23 | migrations.AlterField( 24 | model_name='temporarymajoraartifactmetric_sequence', 25 | name='pc_masked', 26 | field=models.FloatField(), 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /majora2/migrations/0068_auto_20200503_1145.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-03 11:45 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0067_auto_20200428_0134'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='biosourcesamplingprocess', 15 | name='sampling_strategy', 16 | field=models.CharField(blank=True, max_length=64, null=True), 17 | ), 18 | migrations.AddField( 19 | model_name='biosourcesamplingprocess', 20 | name='source_category', 21 | field=models.CharField(blank=True, max_length=64, null=True), 22 | ), 23 | migrations.AddField( 24 | model_name='biosourcesamplingprocess', 25 | name='source_setting', 26 | field=models.CharField(blank=True, max_length=64, null=True), 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /majora2/migrations/0069_pagqualityreportequivalencegroup_last_updated.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-03 13:38 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0068_auto_20200503_1145'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='pagqualityreportequivalencegroup', 15 | name='last_updated', 16 | field=models.DateTimeField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0070_publishedartifactgroup_public_timestamp.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-04 15:01 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0069_pagqualityreportequivalencegroup_last_updated'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='publishedartifactgroup', 15 | name='public_timestamp', 16 | field=models.DateTimeField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0071_auto_20200504_1706.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-04 17:06 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0070_publishedartifactgroup_public_timestamp'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='institute', 15 | name='gisaid_addr', 16 | field=models.CharField(blank=True, max_length=512, null=True), 17 | ), 18 | migrations.AddField( 19 | model_name='institute', 20 | name='gisaid_list', 21 | field=models.CharField(blank=True, max_length=2048, null=True), 22 | ), 23 | migrations.AddField( 24 | model_name='institute', 25 | name='gisaid_mail', 26 | field=models.EmailField(blank=True, max_length=254, null=True), 27 | ), 28 | migrations.AddField( 29 | model_name='institute', 30 | name='gisaid_user', 31 | field=models.CharField(blank=True, max_length=100, null=True), 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /majora2/migrations/0072_auto_20200504_1710.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-04 17:10 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0071_auto_20200504_1706'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='institute', 15 | old_name='gisaid_addr', 16 | new_name='gisaid_lab_addr', 17 | ), 18 | migrations.AddField( 19 | model_name='institute', 20 | name='gisaid_lab_name', 21 | field=models.CharField(blank=True, max_length=512, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0073_institute_gisaid_opted.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-04 17:41 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0072_auto_20200504_1710'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='institute', 15 | name='gisaid_opted', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0075_auto_20200505_1806.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-05 18:06 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0074_temporarymajoraartifactmetric_thresholdcycle_temporarymajoraartifactmetricrecord_temporarymajoraarti'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='temporarymajoraartifactmetricrecord_thresholdcycle', 15 | name='ct_value', 16 | field=models.FloatField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0076_auto_20200507_1513.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-07 15:13 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0075_auto_20200505_1806'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='librarypoolingprocessrecord', 15 | name='library_primers', 16 | field=models.CharField(blank=True, max_length=48, null=True), 17 | ), 18 | migrations.AddField( 19 | model_name='librarypoolingprocessrecord', 20 | name='library_protocol', 21 | field=models.CharField(blank=True, max_length=48, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0076_profileapikey_profileapikeydefinition.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-06 17:44 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | import uuid 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('majora2', '0075_auto_20200505_1806'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='ProfileAPIKeyDefinition', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('key_name', models.CharField(max_length=48)), 20 | ('is_service_key', models.BooleanField()), 21 | ('is_read_key', models.BooleanField()), 22 | ('is_write_key', models.BooleanField()), 23 | ('lifespan', models.DurationField()), 24 | ], 25 | ), 26 | migrations.CreateModel( 27 | name='ProfileAPIKey', 28 | fields=[ 29 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 30 | ('key', models.CharField(default=uuid.uuid4, max_length=128)), 31 | ('validity_start', models.DateTimeField()), 32 | ('validity_end', models.DateTimeField()), 33 | ('key_definition', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='majora2.ProfileAPIKeyDefinition')), 34 | ('profile', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='majora2.Profile')), 35 | ], 36 | ), 37 | ] 38 | -------------------------------------------------------------------------------- /majora2/migrations/0077_auto_20200506_1807.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-06 18:07 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0076_profileapikey_profileapikeydefinition'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='profileapikey', 15 | name='validity_end', 16 | field=models.DateTimeField(blank=True, null=True), 17 | ), 18 | migrations.AlterField( 19 | model_name='profileapikey', 20 | name='validity_start', 21 | field=models.DateTimeField(blank=True, null=True), 22 | ), 23 | migrations.AlterField( 24 | model_name='profileapikeydefinition', 25 | name='key_name', 26 | field=models.CharField(max_length=48, unique=True), 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /majora2/migrations/0077_auto_20200508_1015.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-08 10:15 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0076_auto_20200507_1513'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='publishedartifactgroup', 15 | name='is_suppressed', 16 | field=models.BooleanField(default=False), 17 | ), 18 | migrations.AddField( 19 | model_name='publishedartifactgroup', 20 | name='suppressed_date', 21 | field=models.DateTimeField(blank=True, null=True), 22 | ), 23 | migrations.AddField( 24 | model_name='publishedartifactgroup', 25 | name='suppressed_reason', 26 | field=models.CharField(blank=True, max_length=128, null=True), 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /majora2/migrations/0078_auto_20200506_1817.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-06 18:17 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0077_auto_20200506_1807'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='profileapikey', 15 | name='revoked_reason', 16 | field=models.CharField(blank=True, max_length=24, null=True), 17 | ), 18 | migrations.AddField( 19 | model_name='profileapikey', 20 | name='was_revoked', 21 | field=models.BooleanField(default=False), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0078_auto_20200513_1703.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-13 17:03 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0077_auto_20200508_1015'), 11 | ] 12 | 13 | operations = [ 14 | migrations.RenameField( 15 | model_name='temporaryaccessionrecord', 16 | old_name='secondary_accesison', 17 | new_name='secondary_accession', 18 | ), 19 | migrations.AlterField( 20 | model_name='pagqualityreportequivalencegroup', 21 | name='pag', 22 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quality_groups', to='majora2.PublishedArtifactGroup'), 23 | ), 24 | migrations.AlterField( 25 | model_name='pagqualityreportgroup', 26 | name='group', 27 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='quality_tests', to='majora2.PAGQualityReportEquivalenceGroup'), 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /majora2/migrations/0079_auto_20200515_1529.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-15 15:29 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0078_auto_20200513_1703'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='publishedartifactgroup', 15 | name='published_date', 16 | field=models.DateField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0080_institute_ena_opted.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-18 16:14 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0079_auto_20200515_1529'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='institute', 15 | name='ena_opted', 16 | field=models.BooleanField(default=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0081_merge_20200520_0825.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-20 08:25 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0080_institute_ena_opted'), 10 | ('majora2', '0078_auto_20200506_1817'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /majora2/migrations/0082_coguk_biosourcesamplingprocesssupplement.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-20 09:45 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0081_merge_20200520_0825'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='COGUK_BiosourceSamplingProcessSupplement', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('is_surveillance', models.BooleanField()), 19 | ('is_hcw', models.BooleanField(null=True)), 20 | ('employing_hospital_name', models.CharField(blank=True, max_length=100, null=True)), 21 | ('employing_hospital_trust_or_board', models.CharField(blank=True, max_length=100, null=True)), 22 | ('is_hospital_patient', models.BooleanField(null=True)), 23 | ('admission_date', models.DateField(blank=True, null=True)), 24 | ('admitted_hospital_name', models.CharField(blank=True, max_length=100, null=True)), 25 | ('admitted_hospital_trust_or_board', models.CharField(blank=True, max_length=100, null=True)), 26 | ('is_care_home_worker', models.BooleanField(null=True)), 27 | ('is_care_home_resident', models.BooleanField(null=True)), 28 | ('anonymised_care_home_code', models.CharField(blank=True, max_length=3, null=True)), 29 | ('admitted_with_covid_diagnosis', models.BooleanField(null=True)), 30 | ('sampling', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='coguk_supp', to='majora2.BiosourceSamplingProcess')), 31 | ], 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /majora2/migrations/0083_auto_20200520_1000.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-20 10:00 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0082_coguk_biosourcesamplingprocesssupplement'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='coguk_biosourcesamplingprocesssupplement', 16 | name='sampling', 17 | field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='coguk_supp', to='majora2.BiosourceSamplingProcess'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0084_auto_20200520_1004.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-20 10:04 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0083_auto_20200520_1000'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='coguk_biosourcesamplingprocesssupplement', 15 | name='is_surveillance', 16 | field=models.BooleanField(null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0085_add_supp_to_collections.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-20 10:04 2 | 3 | from django.db import migrations 4 | 5 | def add_collection_supp(apps, schema_editor): 6 | BiosourceSamplingProcess = apps.get_model("majora2", "BiosourceSamplingProcess") 7 | COGUK_BiosourceSamplingProcessSupplement = apps.get_model("majora2", "COGUK_BiosourceSamplingProcessSupplement") 8 | for collection in BiosourceSamplingProcess.objects.all(): 9 | if not hasattr(collection, "coguk_supp"): 10 | c = COGUK_BiosourceSamplingProcessSupplement(sampling=collection) 11 | c.save() 12 | 13 | class Migration(migrations.Migration): 14 | 15 | dependencies = [ 16 | ('majora2', '0084_auto_20200520_1004'), 17 | ] 18 | 19 | operations = [ 20 | migrations.RunPython(add_collection_supp), 21 | ] 22 | -------------------------------------------------------------------------------- /majora2/migrations/0086_migrate_s_strategy_to_supp.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-20 13:10 2 | 3 | from django.db import migrations 4 | 5 | def migrate_s_to_supp(apps, schema_editor): 6 | BiosourceSamplingProcess = apps.get_model("majora2", "BiosourceSamplingProcess") 7 | COGUK_BiosourceSamplingProcessSupplement = apps.get_model("majora2", "COGUK_BiosourceSamplingProcessSupplement") 8 | for collection in BiosourceSamplingProcess.objects.all(): 9 | if not hasattr(collection, "coguk_supp"): 10 | # This shouldnt happen but w/e 11 | c = COGUK_BiosourceSamplingProcessSupplement(sampling=collection) 12 | c.save() 13 | else: 14 | c = collection.coguk_supp 15 | if collection.sampling_strategy == "SURVEILLANCE": 16 | c.is_surveillance = True 17 | c.save() 18 | 19 | class Migration(migrations.Migration): 20 | 21 | dependencies = [ 22 | ('majora2', '0085_add_supp_to_collections'), 23 | ] 24 | 25 | operations = [ 26 | migrations.RunPython(migrate_s_to_supp), 27 | ] 28 | -------------------------------------------------------------------------------- /majora2/migrations/0087_auto_20200520_1340.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-20 13:40 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0086_migrate_s_strategy_to_supp'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='biosourcesamplingprocess', 15 | name='sampling_strategy', 16 | ), 17 | migrations.RemoveField( 18 | model_name='biosourcesamplingprocess', 19 | name='source_category', 20 | ), 21 | migrations.RemoveField( 22 | model_name='biosourcesamplingprocess', 23 | name='source_setting', 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /majora2/migrations/0088_majoraartifactprocess_majora_timestamp.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-21 12:30 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0087_auto_20200520_1340'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='majoraartifactprocess', 15 | name='majora_timestamp', 16 | field=models.DateTimeField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0089_auto_20200521_1232.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-21 12:32 2 | 3 | from django.db import migrations, models 4 | import django.utils.timezone 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0088_majoraartifactprocess_majora_timestamp'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='majoraartifactprocess', 16 | name='majora_timestamp', 17 | field=models.DateTimeField(blank=True, default=django.utils.timezone.now, null=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0090_auto_20200526_1307.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-26 13:07 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0089_auto_20200521_1232'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='coguk_biosourcesamplingprocesssupplement', 15 | name='anonymised_care_home_code', 16 | field=models.CharField(blank=True, max_length=10, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0091_auto_20200527_1150.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-27 11:50 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0090_auto_20200526_1307'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='profile', 15 | options={'permissions': [('can_approve_profiles', 'Can approve new user profiles for their organisation')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0092_auto_20200527_1227.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-27 12:27 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0091_auto_20200527_1150'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='profile', 15 | options={'permissions': [('can_approve_profiles', 'Can approve new user profiles for their organisation'), ('can_grant_profile_permissions', 'Can grant other users permissions that change the Profile system')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0093_profile_is_site_approved.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-27 13:09 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0092_auto_20200527_1227'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='profile', 15 | name='is_site_approved', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0094_approve_already_approved.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-27 13:10 2 | 3 | from django.db import migrations 4 | 5 | def approve_approved(apps, schema_editor): 6 | Profile = apps.get_model("majora2", "Profile") 7 | for profile in Profile.objects.all(): 8 | if profile.user.is_active: 9 | profile.is_site_approved = True 10 | profile.save() 11 | 12 | class Migration(migrations.Migration): 13 | 14 | dependencies = [ 15 | ('majora2', '0093_profile_is_site_approved'), 16 | ] 17 | 18 | operations = [ 19 | migrations.RunPython(approve_approved), 20 | ] 21 | -------------------------------------------------------------------------------- /majora2/migrations/0095_auto_20200527_1623.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-27 16:23 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0094_approve_already_approved'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='institute', 15 | options={'permissions': [('can_register_institute', 'Can register a new institute in Majora')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0096_auto_20200527_2034.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-27 20:34 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0095_auto_20200527_1623'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='profile', 15 | options={'permissions': [('can_approve_profiles', 'Can approve new user profiles for their organisation'), ('can_approve_profiles_via_bot', 'Can approve new user profiles for any organisation via the bot system'), ('can_grant_profile_permissions', 'Can grant other users permissions that change the Profile system')]}, 16 | ), 17 | migrations.AddField( 18 | model_name='profile', 19 | name='slack_id', 20 | field=models.CharField(blank=True, max_length=24, null=True), 21 | ), 22 | migrations.AddField( 23 | model_name='profile', 24 | name='slack_verified', 25 | field=models.BooleanField(default=False), 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /majora2/migrations/0097_coguk_biosourcesamplingprocesssupplement_is_icu_patient.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-06-03 10:50 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0096_auto_20200527_2034'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='coguk_biosourcesamplingprocesssupplement', 15 | name='is_icu_patient', 16 | field=models.BooleanField(null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0098_auto_20200606_1646.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-06-06 16:46 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0097_coguk_biosourcesamplingprocesssupplement_is_icu_patient'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='publishedartifactgroup', 15 | options={'permissions': [('temp_can_read_pags_via_api', 'Can read published artifact groups via the API')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0099_profileapikeydefinition_permission.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-06-06 16:52 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0098_auto_20200606_1646'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='profileapikeydefinition', 15 | name='permission', 16 | field=models.CharField(blank=True, max_length=96, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0100_auto_20200606_1700.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-06-06 17:00 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0099_profileapikeydefinition_permission'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='profileapikeydefinition', 16 | name='permission', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='auth.Permission'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0102_auto_20200713_1651.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-07-13 16:51 2 | 3 | from django.db import migrations, models 4 | import uuid 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0101_profileagreement_profileagreementdefinition'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='profileagreement', 16 | name='id', 17 | field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), 18 | ), 19 | migrations.AlterField( 20 | model_name='profileagreementdefinition', 21 | name='description', 22 | field=models.CharField(max_length=256), 23 | ), 24 | migrations.AlterField( 25 | model_name='profileagreementdefinition', 26 | name='name', 27 | field=models.CharField(max_length=96), 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /majora2/migrations/0103_auto_20200713_1717.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-07-13 17:17 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0102_auto_20200713_1651'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='profileagreement', 15 | name='terminated_timestamp', 16 | field=models.DateTimeField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0104_institutecredit.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-07-15 02:05 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0103_auto_20200713_1717'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='InstituteCredit', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('credit_code', models.CharField(max_length=10, unique=True)), 19 | ('lab_name', models.CharField(blank=True, max_length=512, null=True)), 20 | ('lab_addr', models.CharField(blank=True, max_length=512, null=True)), 21 | ('lab_list', models.CharField(blank=True, max_length=2048, null=True)), 22 | ('institute', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='credits', to='majora2.Institute')), 23 | ], 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /majora2/migrations/0105_auto_20200715_0933.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-07-15 09:33 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0104_institutecredit'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='institutecredit', 15 | name='credit_code', 16 | field=models.CharField(max_length=24, unique=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0106_profileagreementdefinition_is_terminable.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-07-16 20:49 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0105_auto_20200715_0933'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='profileagreementdefinition', 15 | name='is_terminable', 16 | field=models.BooleanField(default=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0107_majoradataview_majoradataviewserializerfield.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-07-16 21:46 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0106_profileagreementdefinition_is_terminable'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='MajoraDataview', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('code_name', models.CharField(max_length=10, unique=True)), 19 | ('name', models.CharField(max_length=128)), 20 | ('description', models.CharField(max_length=256)), 21 | ], 22 | ), 23 | migrations.CreateModel( 24 | name='MajoraDataviewSerializerField', 25 | fields=[ 26 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 27 | ('model_name', models.CharField(max_length=64)), 28 | ('model_field', models.CharField(max_length=64)), 29 | ('dataview', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='majora2.MajoraDataview')), 30 | ], 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /majora2/migrations/0108_auto_20200716_2203.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-07-16 22:03 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0107_majoradataview_majoradataviewserializerfield'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='majoradataviewserializerfield', 16 | name='dataview', 17 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fields', to='majora2.MajoraDataview'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0109_majoradataviewuserpermission.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-07-17 17:42 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0108_auto_20200716_2203'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='MajoraDataviewUserPermission', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('validity_start', models.DateTimeField(blank=True, null=True)), 19 | ('validity_end', models.DateTimeField(blank=True, null=True)), 20 | ('is_revoked', models.BooleanField(default=False)), 21 | ('revoked_reason', models.CharField(blank=True, max_length=24, null=True)), 22 | ('revoked_timestamp', models.DateTimeField(blank=True, null=True)), 23 | ('dataview', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='viewers', to='majora2.MajoraDataview')), 24 | ('profile', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='majora2.Profile')), 25 | ], 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /majora2/migrations/0110_auto_20200717_1811.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-07-17 18:11 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0109_majoradataviewuserpermission'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='majoradataview', 15 | options={'permissions': [('can_read_dataview', 'Can read the contents of data views via the API')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0111_auto_20200717_1814.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-07-17 18:14 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0110_auto_20200717_1811'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='majoradataview', 15 | options={'permissions': [('can_read_dataview_via_api', 'Can read the contents of data views via the API')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0112_auto_20200729_1253.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-07-29 12:53 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0111_auto_20200717_1814'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='temporaryaccessionrecord', 15 | name='is_public', 16 | field=models.BooleanField(default=True), 17 | ), 18 | migrations.AddField( 19 | model_name='temporaryaccessionrecord', 20 | name='is_rejected', 21 | field=models.BooleanField(default=False), 22 | ), 23 | migrations.AddField( 24 | model_name='temporaryaccessionrecord', 25 | name='public_timestamp', 26 | field=models.DateTimeField(blank=True, null=True), 27 | ), 28 | migrations.AddField( 29 | model_name='temporaryaccessionrecord', 30 | name='rejected_timestamp', 31 | field=models.DateTimeField(blank=True, null=True), 32 | ), 33 | migrations.AddField( 34 | model_name='temporaryaccessionrecord', 35 | name='requested_timestamp', 36 | field=models.DateTimeField(blank=True, null=True), 37 | ), 38 | migrations.AddField( 39 | model_name='temporaryaccessionrecord', 40 | name='terminated_reason', 41 | field=models.CharField(blank=True, max_length=24, null=True), 42 | ), 43 | migrations.AlterField( 44 | model_name='temporaryaccessionrecord', 45 | name='primary_accession', 46 | field=models.CharField(blank=True, max_length=64, null=True), 47 | ), 48 | ] 49 | -------------------------------------------------------------------------------- /majora2/migrations/0113_auto_20200729_1316.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-07-29 13:16 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0112_auto_20200729_1253'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='temporaryaccessionrecord', 15 | old_name='terminated_reason', 16 | new_name='rejected_reason', 17 | ), 18 | migrations.AlterField( 19 | model_name='temporaryaccessionrecord', 20 | name='is_public', 21 | field=models.BooleanField(default=False), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0114_temporaryaccessionrecord_requested_by.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-07-29 18:07 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('majora2', '0113_auto_20200729_1316'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='temporaryaccessionrecord', 18 | name='requested_by', 19 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /majora2/migrations/0115_majoraartifactgroup_group_path.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-07 15:43 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0114_temporaryaccessionrecord_requested_by'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='majoraartifactgroup', 15 | name='group_path', 16 | field=models.CharField(blank=True, max_length=1024, null=True, unique=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0116_majoraartifactgrouplink.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-08 12:59 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | import uuid 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('majora2', '0115_majoraartifactgroup_group_path'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='MajoraArtifactGroupLink', 17 | fields=[ 18 | ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), 19 | ('link_name', models.CharField(blank=True, max_length=128, null=True, unique=True)), 20 | ('from_group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='out_glinks', to='majora2.MajoraArtifactGroup')), 21 | ('to_artifact', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='in_glinks', to='majora2.MajoraArtifact')), 22 | ('to_group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='in_glinks', to='majora2.MajoraArtifactGroup')), 23 | ], 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /majora2/migrations/0117_auto_20200808_1302.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-08 13:02 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0116_majoraartifactgrouplink'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='majoraartifactgrouplink', 16 | name='from_group', 17 | field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='out_glinks', to='majora2.MajoraArtifactGroup'), 18 | ), 19 | migrations.AlterField( 20 | model_name='majoraartifactgrouplink', 21 | name='link_name', 22 | field=models.CharField(max_length=128, unique=True), 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /majora2/migrations/0118_majoraartifactgroup_temp_kind.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-08 13:55 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0117_auto_20200808_1302'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='majoraartifactgroup', 15 | name='temp_kind', 16 | field=models.CharField(blank=True, max_length=48, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0119_majoradataview_entry_point.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-14 13:20 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0118_majoraartifactgroup_temp_kind'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='majoradataview', 15 | name='entry_point', 16 | field=models.CharField(default='PublishedArtifactGroup', max_length=128), 17 | preserve_default=False, 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0120_auto_20200814_1819.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-14 18:19 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0119_majoradataview_entry_point'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='majoradataview', 15 | options={'permissions': [('can_read_dataview_via_api', 'Can read the contents of CONSORTIUM data views via the API'), ('can_read_restricted_dataview_via_api', 'Can read the contents of RESTRICTED data views via the API')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0121_majoradataview_permission.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-14 18:29 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('auth', '0011_update_proxy_permissions'), 11 | ('majora2', '0120_auto_20200814_1819'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='majoradataview', 17 | name='permission', 18 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='auth.Permission'), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /majora2/migrations/0122_auto_20200820_2020.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-20 20:20 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0121_majoradataview_permission'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='profileapikey', 16 | name='profile', 17 | field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='api_keys', to='majora2.Profile'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0123_profileapppassword.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-27 19:03 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('tatl', '0024_oauth2codeonlyapplication'), 12 | ('majora2', '0122_auto_20200820_2020'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='ProfileAppPassword', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('password', models.CharField(max_length=64)), 21 | ('validity_start', models.DateTimeField(blank=True, null=True)), 22 | ('validity_end', models.DateTimeField(blank=True, null=True)), 23 | ('application', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL)), 24 | ('profile', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='app_passwords', to='majora2.Profile')), 25 | ], 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /majora2/migrations/0124_majoradataviewfilterfield.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-09-08 15:59 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0123_profileapppassword'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='MajoraDataviewFilterField', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('filter_field', models.CharField(max_length=64)), 19 | ('filter_type', models.CharField(choices=[('str', 'str'), ('int', 'int'), ('float', 'float'), ('bool', 'bool')], max_length=8)), 20 | ('filter_value', models.CharField(max_length=128)), 21 | ('filter_op', models.CharField(default='exact', max_length=10)), 22 | ('dataview', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='filters', to='majora2.MajoraDataview')), 23 | ], 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /majora2/migrations/0125_auto_20200908_1617.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-09-08 16:17 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0124_majoradataviewfilterfield'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='profileagreement', 16 | name='profile', 17 | field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='agreements', to='majora2.Profile'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0126_auto_20200928_1751.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-09-28 17:51 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0125_auto_20200908_1617'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='biosampleartifact', 15 | options={'permissions': [('force_add_biosampleartifact', 'Can forcibly add a biosample artifact to Majora')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0127_auto_20201009_1518.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-10-09 15:18 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0126_auto_20200928_1751'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='digitalresourceartifact', 15 | name='current_name', 16 | field=models.CharField(db_index=True, max_length=512), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0128_auto_20201017_1334.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-10-17 13:34 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0127_auto_20201009_1518'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='majoraartifactprocess', 15 | name='hook_name', 16 | field=models.CharField(blank=True, max_length=256, null=True, unique=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0129_coguk_biosourcesamplingprocesssupplement_collection_pillar.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-10-26 12:14 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0128_auto_20201017_1334'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='coguk_biosourcesamplingprocesssupplement', 15 | name='collection_pillar', 16 | field=models.PositiveSmallIntegerField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0130_auto_20201029_1040.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-10-29 10:40 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0129_coguk_biosourcesamplingprocesssupplement_collection_pillar'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='publishedartifactgroup', 15 | options={'permissions': [('temp_can_read_pags_via_api', 'Can read published artifact groups via the API'), ('can_suppress_pags_via_api', 'Can suppress any published artifact group via the API')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0131_biosamplesource_root_biosample_source_id.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-11-03 11:45 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0130_auto_20201029_1040'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='biosamplesource', 15 | name='root_biosample_source_id', 16 | field=models.CharField(blank=True, max_length=48, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0132_auto_20201103_1223.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-11-03 12:23 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0131_biosamplesource_root_biosample_source_id'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='biosamplesource', 15 | name='root_biosample_source_id', 16 | ), 17 | migrations.AddField( 18 | model_name='biosampleartifact', 19 | name='root_biosample_source_id', 20 | field=models.CharField(blank=True, max_length=48, null=True), 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /majora2/migrations/0133_auto_20201105_1507.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-11-05 15:07 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0132_auto_20201103_1223'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='profile', 15 | options={'permissions': [('can_revoke_profiles', 'Can revoke the access of any user'), ('can_approve_profiles', 'Can approve new user profiles for their organisation'), ('can_approve_profiles_via_bot', 'Can approve new user profiles for any organisation via the bot system'), ('can_grant_profile_permissions', 'Can grant other users permissions that change the Profile system')]}, 16 | ), 17 | migrations.AddField( 18 | model_name='profile', 19 | name='is_revoked', 20 | field=models.BooleanField(default=False), 21 | ), 22 | migrations.AddField( 23 | model_name='profile', 24 | name='revoked_reason', 25 | field=models.CharField(blank=True, max_length=24, null=True), 26 | ), 27 | migrations.AddField( 28 | model_name='profile', 29 | name='revoked_timestamp', 30 | field=models.DateTimeField(blank=True, null=True), 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /majora2/migrations/0134_auto_20201110_1629.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-11-10 16:29 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0133_auto_20201105_1507'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='profile', 15 | name='revoked_reason', 16 | field=models.CharField(blank=True, max_length=128, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0135_majorametarecord_restricted.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-11-26 15:35 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0134_auto_20201110_1629'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='majorametarecord', 15 | name='restricted', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0136_institute_ena_assembly_opted.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2021-01-11 17:48 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0135_majorametarecord_restricted'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='institute', 15 | name='ena_assembly_opted', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0137_auto_20210113_1258.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2021-01-13 12:58 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0136_institute_ena_assembly_opted'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='temporarymajoraartifactmetric', 16 | name='artifact', 17 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='metrics', to='majora2.MajoraArtifact'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /majora2/migrations/0138_librarypoolingprocessrecord_sequencing_org_received_date.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2021-01-14 18:05 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0137_auto_20210113_1258'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='librarypoolingprocessrecord', 15 | name='sequencing_org_received_date', 16 | field=models.DateField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0139_auto_20210305_1036.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2021-03-05 10:36 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0138_librarypoolingprocessrecord_sequencing_org_received_date'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='publishedartifactgroup', 15 | name='published_name', 16 | field=models.CharField(db_index=True, max_length=128), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0140_auto_20210427_1746.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2021-04-27 17:46 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0139_auto_20210305_1036'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='majoraartifact', 15 | options={'permissions': [('view_majoraartifact_info', 'Can view basic information of any artifact')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0141_auto_20210525_2153.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2021-05-25 21:53 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0140_auto_20210427_1746'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='majoradataviewfilterfield', 15 | name='filter_type', 16 | field=models.CharField(choices=[('str', 'str'), ('int', 'int'), ('float', 'float'), ('bool', 'bool'), ('list', 'list')], max_length=8), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0142_auto_20211213_1312.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.24 on 2021-12-13 13:12 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0141_auto_20210525_2153'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='libraryartifact', 15 | name='seq_kit', 16 | field=models.CharField(blank=True, max_length=96, null=True), 17 | ), 18 | migrations.AlterField( 19 | model_name='libraryartifact', 20 | name='seq_protocol', 21 | field=models.CharField(blank=True, max_length=96, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /majora2/migrations/0143_auto_20220105_1256.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.24 on 2022-01-05 12:56 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0142_auto_20211213_1312'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='publishedartifactgroup', 15 | options={'permissions': [('temp_can_read_pags_via_api', 'Can read published artifact groups via the API'), ('can_suppress_pags_via_api', 'Can suppress their own published artifact group via the API'), ('can_suppress_any_pags_via_api', 'Can suppress any published artifact group via the API')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0144_auto_20220111_1620.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.24 on 2022-01-11 16:20 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0143_auto_20220105_1256'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='profile', 15 | options={'permissions': [('can_revoke_profiles', 'Can revoke the access of any user'), ('can_approve_profiles', 'Can approve new user profiles for their organisation'), ('can_approve_profiles_via_bot', 'Can approve new user profiles for any organisation via the bot system'), ('can_grant_profile_permissions', 'Can grant other users permissions that change the Profile system'), ('can_wildcard_sequencing_runs', 'Can use the wildcard character to unroll all sequencing runs in Majora')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0145_auto_20220111_1736.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.24 on 2022-01-11 17:36 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0144_auto_20220111_1620'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='profile', 15 | options={'permissions': [('can_revoke_profiles', 'Can revoke the access of any user'), ('can_approve_profiles', 'Can approve new user profiles for their organisation'), ('can_approve_profiles_via_bot', 'Can approve new user profiles for any organisation via the bot system'), ('can_grant_profile_permissions', 'Can grant other users permissions that change the Profile system'), ('can_wildcard_sequencing_runs', 'Can use the wildcard character to unroll all sequencing runs in Majora'), ('can_sudo_as_other_user', 'Can elevate permissions to impersonate other users')]}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /majora2/migrations/0146_majora_fact.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.26 on 2022-01-30 00:50 2 | 3 | from django.db import migrations, models 4 | import uuid 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('majora2', '0145_auto_20220111_1736'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='MajoraFact', 16 | fields=[ 17 | ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), 18 | ('namespace', models.CharField(max_length=64)), 19 | ('key', models.CharField(max_length=64)), 20 | ('value_type', models.CharField(max_length=48)), 21 | ('value', models.CharField(blank=True, max_length=128, null=True)), 22 | ('timestamp', models.DateTimeField(blank=True, null=True)), 23 | ], 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /majora2/migrations/0147_majora_fact_counter.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.26 on 2022-01-30 01:00 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0146_majora_fact'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='majorafact', 15 | name='counter', 16 | field=models.PositiveIntegerField(default=0), 17 | ), 18 | migrations.AddConstraint( 19 | model_name='majorafact', 20 | constraint=models.UniqueConstraint(fields=('namespace', 'key'), name='is_only_key_in_namespace'), 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /majora2/migrations/0148_majora_fact_restricted.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.26 on 2022-01-30 01:07 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0147_majora_fact_counter'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='majorafact', 15 | name='restricted', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0149_institute_credit_code_only.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.26 on 2022-02-02 17:05 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0148_majora_fact_restricted'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='institute', 15 | name='credit_code_only', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0150_majoraartifactprocessrecord_unique_name.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.27 on 2022-02-26 13:19 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0149_institute_credit_code_only'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='majoraartifactprocessrecord', 15 | name='unique_name', 16 | field=models.CharField(max_length=128, null=True, unique=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0151_auto_20220226_1624.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.26 on 2022-02-26 16:24 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('majora2', '0150_majoraartifactprocessrecord_unique_name'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='majoraartifactprocessrecord', 15 | name='unique_name', 16 | field=models.CharField(max_length=256, null=True, unique=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /majora2/migrations/0152_backfill_dnasequencingprocessrecord_uniquename.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.26 on 2022-02-26 16:00 2 | 3 | from django.db import migrations 4 | 5 | def assign_uniquename(apps, schema_editor): 6 | DNASequencingProcessRecord = apps.get_model("majora2", "DNASequencingProcessRecord") 7 | DNASequencingProcess = apps.get_model("majora2", "DNASequencingProcess") 8 | for record in DNASequencingProcessRecord.objects.all(): 9 | run = DNASequencingProcess.objects.get(id=record.process.id) 10 | run_name = run.run_name 11 | library_name = record.in_artifact.dice_name 12 | record.unique_name = "%s-%s" % (run_name, library_name) 13 | record.save() 14 | 15 | 16 | class Migration(migrations.Migration): 17 | 18 | dependencies = [ 19 | ('majora2', '0151_auto_20220226_1624'), 20 | ] 21 | 22 | operations = [ 23 | migrations.RunPython(assign_uniquename) 24 | ] 25 | -------------------------------------------------------------------------------- /majora2/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/majora2/migrations/__init__.py -------------------------------------------------------------------------------- /majora2/renderers.py: -------------------------------------------------------------------------------- 1 | from rest_framework_csv import renderers as r 2 | import csv 3 | 4 | class TSVRenderer (r.CSVRenderer): 5 | media_type = "text/tsv" 6 | format = "tsv" 7 | writer_opts = dict( 8 | quoting=csv.QUOTE_MINIMAL, 9 | delimiter='\t', 10 | ) 11 | -------------------------------------------------------------------------------- /majora2/signals.py: -------------------------------------------------------------------------------- 1 | import django.dispatch 2 | new_registration = django.dispatch.Signal(providing_args=["username", "first_name", "last_name", "organisation", "email"]) 3 | site_approved_registration = django.dispatch.Signal(providing_args=["approver", "approved_profile"]) 4 | activated_registration = django.dispatch.Signal(providing_args=["username", "email"]) 5 | new_sample = django.dispatch.Signal(providing_args=["sample_id", "submitter"]) 6 | revoked_profile = django.dispatch.Signal(providing_args=["username", "organisation", "email", "reason"]) 7 | -------------------------------------------------------------------------------- /majora2/submodels/__init__.py: -------------------------------------------------------------------------------- 1 | from .supplemental import * 2 | -------------------------------------------------------------------------------- /majora2/submodels/supplemental.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | class COGUK_BiosourceSamplingProcessSupplement(models.Model): 4 | sampling = models.OneToOneField('BiosourceSamplingProcess', on_delete=models.CASCADE, related_name="coguk_supp") 5 | is_surveillance = models.BooleanField(null=True) 6 | is_hcw = models.BooleanField(null=True) 7 | employing_hospital_name = models.CharField(max_length=100, blank=True, null=True) 8 | employing_hospital_trust_or_board = models.CharField(max_length=100, blank=True, null=True) 9 | is_hospital_patient = models.BooleanField(null=True) 10 | is_icu_patient = models.BooleanField(null=True) 11 | admission_date = models.DateField(blank=True, null=True) 12 | admitted_hospital_name = models.CharField(max_length=100, blank=True, null=True) 13 | admitted_hospital_trust_or_board = models.CharField(max_length=100, blank=True, null=True) 14 | is_care_home_worker = models.BooleanField(null=True) 15 | is_care_home_resident = models.BooleanField(null=True) 16 | anonymised_care_home_code = models.CharField(max_length=10, blank=True, null=True) 17 | admitted_with_covid_diagnosis = models.BooleanField(null=True) 18 | collection_pillar = models.PositiveSmallIntegerField(blank=True, null=True) 19 | 20 | def get_resty_serializer(self): 21 | from . import resty_serializers 22 | return resty_serializers.RestyCOGUK_BiosourceSamplingProcessSupplement 23 | -------------------------------------------------------------------------------- /majora2/templates/accounts/institute_success.html: -------------------------------------------------------------------------------- 1 | {% load crispy_forms_tags %} 2 | {% include 'header.html' with title="Update successful" %} 3 |
4 |
5 |
6 |
7 |
8 | 9 |

Institute update received

10 |

No further action required.

11 | Thanks for providing your details.
12 | 13 | {% include 'footer.html' %} 14 | -------------------------------------------------------------------------------- /majora2/templates/accounts/register_success.html: -------------------------------------------------------------------------------- 1 | {% load crispy_forms_tags %} 2 | {% include 'header.html' with title="Registration successful" %} 3 |
4 |
5 |
6 |
7 |
8 | 9 |

Access request received

10 |

You do not have access yet.

11 | Thanks for providing your details.
12 | Your request will be reviewed by your site co-ordinator and forwarded to the system administrator.
13 | You will receive an email once your account has been activated, which will also provide details on how to login to CLIMB and upload data.
14 | Do not attempt to login to systems until your account has been activated, and please do not chase your request in #account-requests. 15 | 16 | {% include 'footer.html' %} 17 | -------------------------------------------------------------------------------- /majora2/templates/admin/base_site.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | 3 | {% block title %}{{ title }} | Majora {% endblock %} 4 | 5 | {% block branding %} 6 |

Majora

7 | {% endblock %} 8 | 9 | {% block nav-global %}{% endblock %} 10 | -------------------------------------------------------------------------------- /majora2/templates/artifact_layouts/library.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 |
3 |
4 |

Biosample Library Pool

5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
layout_config{{ artifact.layout_config }}
layout_read_length layout_insert_length{{ artifact.layout_read_length }} {{ artifact.layout_insert_length }}
seq_protocol{{ artifact.seq_protocol }}
seq_kit{{ artifact.seq_kit }}
25 |
26 | 27 |
28 |
29 |
30 |
31 |

Samples

32 | {% with gitems=artifact.created.records.all dtable=0 %} 33 | {% include 'tables/librarybiosample.html' %} 34 | {% endwith %} 35 |
36 |
37 | -------------------------------------------------------------------------------- /majora2/templates/breadcrumbs.html: -------------------------------------------------------------------------------- 1 | {% for hgroup in hierarchy %} 2 | {{ hgroup.full_name }}{% if forloop.last %}{% else %} ► {% endif %} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /majora2/templates/footer.html: -------------------------------------------------------------------------------- 1 | {% load cache %} 2 | {% load instance %} 3 | 4 |
5 |
6 | 7 | {% if user.is_authenticated %} 8 |

You are authenticated {% if user.is_verified %}and 2FA verified{% endif %} as {{ request.user.username }} | Log Out 9 | {% else %} 10 | You are not authenticated. | Register or Log in 11 | {% endif %} 12 | 13 | {% cache None footer %} 14 |
{% footer %} 15 |
{% mask %} majora2 v{{ majora_version }} - "{{ majora_name }}" ({{ majora_commit }}) 16 |

17 | {% endcache %} 18 |
19 |
20 |
21 |
22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /majora2/templates/forms/account.html: -------------------------------------------------------------------------------- 1 | {% load instance %} 2 | {% load crispy_forms_tags %} 3 | {% include 'header.html' with title="Update Account" %} 4 |
5 |
6 |
7 |
8 |
9 | 10 |

Update your {% instance_name %} unified account

11 |
12 | 13 |
14 | {% csrf_token %} 15 | {% crispy form %} 16 |
17 |
18 | {% include 'footer.html' %} 19 | -------------------------------------------------------------------------------- /majora2/templates/forms/credit.html: -------------------------------------------------------------------------------- 1 | {% load instance %} 2 | {% load crispy_forms_tags %} 3 | {% include 'header.html' with title="Credit" %} 4 |
5 |
6 |
7 |
8 |
9 | 10 |

Update institute credit

11 |
12 | 13 | {% if credit_code %} 14 |
15 | {% else %} 16 | 17 | {% endif %} 18 | {% csrf_token %} 19 | {% crispy form %} 20 |
21 |
22 | {% include 'footer.html' %} 23 | -------------------------------------------------------------------------------- /majora2/templates/forms/institute.html: -------------------------------------------------------------------------------- 1 | {% load instance %} 2 | {% load crispy_forms_tags %} 3 | {% include 'header.html' with title="Institute" %} 4 |
5 |
6 |
7 |
8 |
9 | 10 |

Update institute settings

11 |
12 | 13 |
14 | {% csrf_token %} 15 | {% crispy form %} 16 |
17 | 18 |
19 |

Additional credits

20 | Uploading metadata with the majora_credit code set to a credit code in the table below, will override the default institution author credits defined above. 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {% for credit in institute.credits.all %} 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | {% endfor %} 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
Credit codeLab nameLab addressLab authors
{{ credit.credit_code }}{{ credit.lab_name }}{{ credit.lab_addr }}{{ credit.lab_list }}Edit
Add
50 |
51 | {% include 'footer.html' %} 52 | -------------------------------------------------------------------------------- /majora2/templates/forms/register.html: -------------------------------------------------------------------------------- 1 | {% load instance %} 2 | {% load crispy_forms_tags %} 3 | {% include 'header.html' with title="Register" %} 4 |
5 |
6 |
7 |
8 |
9 | 10 |

Register for a {% instance_name %} unified account

11 |
12 | 13 |
14 | {% csrf_token %} 15 | {% crispy form %} 16 |
17 |
18 | {% include 'footer.html' %} 19 | -------------------------------------------------------------------------------- /majora2/templates/private/footer.html: -------------------------------------------------------------------------------- 1 | {% load instance %} 2 |
3 | 4 |

5 |
The Majora artifact metadata system was built by Sam Nicholls at the University of Birmingham for the COVID-19 Genomics UK Consortium.

6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /majora2/templates/private/special/dataview_list.html: -------------------------------------------------------------------------------- 1 | {% load crispy_forms_tags %} 2 | {% load instance %} 3 | {% instance_name as instance_name_str %} 4 | {% include 'private/header.html' with title="Dataviews" navtitle=""|add:instance_name_str|add:" Dataviews" %} 5 |
6 |
7 |
8 |
9 |
10 | 11 |
12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {% for dv in dataviews %} 25 | 26 | 27 | 32 | 37 | 42 | 43 | {% endfor %} 44 | 45 |
MDVFieldsFiltersUsers
{{ dv.code_name }}
{{ dv.name }}
{{ dv.entry_point }}
    28 | {% for field in dv.fields.all %} 29 |
  • {{ field.model_name }} : {{ field.model_field }}
  • 30 | {% endfor %} 31 |
    33 | {% for field in dv.filters.all %} 34 |
  • {{ field.id }}{{ field.filter_field_nice }} {{ field.filter_op }} {{ field.filter_value }}
  • 35 | {% endfor %} 36 |
    38 | {% for viewer in dv.viewers.all %} 39 |
  • {{ viewer.profile.user.username }}
  • 40 | {% endfor %} 41 |
46 | 47 | 48 |
49 |
50 | {% include 'private/footer.html' %} 51 | -------------------------------------------------------------------------------- /majora2/templates/public/footer.html: -------------------------------------------------------------------------------- 1 | {% load instance %} 2 |
3 | 4 |

5 |
The Majora artifact metadata system was built by Sam Nicholls at the University of Birmingham for the COVID-19 Genomics UK Consortium.

6 |
7 |
8 |
9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /majora2/templates/public/special/pag_list.html: -------------------------------------------------------------------------------- 1 | {% load crispy_forms_tags %} 2 | {% load instance %} 3 | {% instance_name as instance_name_str %} 4 | {% include 'public/header.html' with title="Accessions" navtitle=""|add:instance_name_str|add:" Public Accessions" %} 5 |
6 |
7 |
8 |
9 |
10 | 11 |
12 |
13 | 14 | {% include 'tables/dt_pag.html' %} 15 | 16 |
17 |
18 | {% include 'public/footer.html' %} 19 | -------------------------------------------------------------------------------- /majora2/templates/redoc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ReDoc 5 | 6 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /majora2/templates/slack/blank: -------------------------------------------------------------------------------- 1 | {% extends django_slack %} 2 | {% block text %} 3 | {% endblock %} 4 | -------------------------------------------------------------------------------- /majora2/templates/tables/artifact-badges.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 | {% for t_type, t_items in thing.ordered_artifacts.items %} 3 | {% for t_item in t_items %} 4 | {{ t_type }}{{ t_item.name }}{{ t_item.created.when | naturaltime }} 5 | {% endfor %} 6 | {% endfor %} 7 | -------------------------------------------------------------------------------- /majora2/templates/tables/biosample.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {% for artifact in gitems %} 15 | 16 | 17 | 18 | 20 | 21 | 23 | 24 | {% endfor %} 25 | 26 |
Sample IDSample SourceCollected at (by)TypeCollection date
{{ artifact.name }}{% if artifact.primary_group %}{{ artifact.primary_group }}{% else %}Unlinked{% endif %} ({{ artifact.created.source_age }}{{ artifact.created.source_sex }}){{ artifact.created.collection_location_adm1 }} / {{ artifact.created.collection_location_adm2 }}
19 | {{ artifact.created.collected_by }}
{{ artifact.sample_type_collected }} {% if artifact.sample_site %}({{ artifact.sample_site }}){% endif %}{{ artifact.created.collection_date }}
22 | {{ artifact.created.when | naturaltime }}
27 |
28 | 29 | 39 | -------------------------------------------------------------------------------- /majora2/templates/tables/command.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 | 3 | {{ process.cmd_str }} 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {% for record in process.records.all %} 17 | 18 | 23 | 26 | 29 | 34 | 35 | 36 | {% endfor %} 37 | 38 |
BeforeAfter
19 | {% if record.in_artifact %} 20 | {{ record.in_artifact.path }} 21 | {% endif %} 22 | 24 | {{ record.before_size | filesizeformat }} 25 | 27 | {{ record.after_size | filesizeformat }} 28 | 30 | {% if record.out_artifact %} 31 | {{ record.out_artifact.path }} 32 | {% endif %} 33 |
39 |
40 | -------------------------------------------------------------------------------- /majora2/templates/tables/default.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {% for artifact in gitems %} 12 | 13 | 14 | 15 | 16 | {% endfor %} 17 | 18 |
NameReceived
{{ artifact.name }}{{ artifact.created.process.when | naturaltime }}
19 |
20 | -------------------------------------------------------------------------------- /majora2/templates/tables/metadata-badges.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 | {% if thing.metadata.all %} 3 | {% for metadatum in thing.metadata.all %} 4 | {{ metadatum.meta_tag }}{{ metadatum.meta_name }}{% if not metadatum.restricted %}{{ metadatum.translate }}{% else %}RESTRICTED{% endif %}{{ metadatum.timestamp | naturaltime }} 5 | {% endfor %} 6 | {% endif %} 7 | -------------------------------------------------------------------------------- /majora2/templates/tables/metadata.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {% if thing.metadata.all %} 13 | {% for metadatum in thing.metadata.all %} 14 | 15 | 16 | 17 | 18 | 22 | 23 | {% endfor %} 24 | {% else %} 25 | 26 | 27 | 28 | {% endif %} 29 | 30 |
TagNameValue
{{ metadatum.meta_tag }}{{ metadatum.meta_name }}{{ metadatum.translate }} 19 | {{ metadatum.timestamp | naturaltime }}
20 | {{ metadatum.timestamp }} 21 |
Not much to say.
31 | -------------------------------------------------------------------------------- /majora2/templates/tables/metric-badges.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 | {% for metric_set in thing.metrics.all %} 3 | {% for metric, value in metric_set.as_struct.items %} 4 | 5 | {% if metric == "records" %} 6 | {% for item in value %} 7 | {% for k,v in item.items %} 8 | {{ metric_set.kind }}{{ forloop.parentloop.counter }}{{ k }}{% if v %}{{ v }}{% else %}null{% endif %} 9 | {% endfor %} 10 | {% endfor %} 11 | {% else %} 12 | {{ metric_set.kind }}{{ metric }}{{ value }} 13 | {% endif %} 14 | 15 | {% endfor %} 16 | {% endfor %} 17 | -------------------------------------------------------------------------------- /majora2/templates/tables/recurse_process.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 | 27 | -------------------------------------------------------------------------------- /majora2/templates/tables/row_small.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 | {{ thing.artifact_kind }} 3 | {% if thing.artifact_kind == 'Sample Tube' %} 4 | {{ thing.dice_name }}
{{ thing.location }} 5 | 6 | {{ thing.observed.process.when | naturaltime }} 7 | {% elif thing.artifact_kind == 'Digital Resource' %} 8 | {{ thing.path }}
{{ thing.current_kind }} ({{ thing.current_size | filesizeformat }}) 9 | 10 | {{ thing.observed.process.when | naturaltime }} 11 | {% elif thing.artifact_kind == 'Biosample' %} 12 | {{ thing.name }}
{{ thing.location }} 13 | 14 | {{ thing.observed.process.when | naturaltime }} 15 | {% else %} 16 | {{ thing }}
17 | 18 | {{ thing.observed.process.when | naturaltime }} 19 | {% endif %} 20 | 21 | -------------------------------------------------------------------------------- /majora2/templates/tables/tube.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% for artifact in gitems %} 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% endfor %} 21 | 22 |
Dice NameBox NameSourceReceived
{{ artifact.dice_name }}{{ artifact.location }}{{ artifact.sample.source.name }}{{ artifact.created.process.when | naturaltime }}
23 |
24 | -------------------------------------------------------------------------------- /majora2/templates/two_factor/_base.html: -------------------------------------------------------------------------------- 1 | {% load instance %} 2 | {% include "header.html" %} 3 |
4 |
5 |
6 |
7 | User 8 | {{ user.id }} 9 |
10 |
11 |
12 |
13 |
14 |
15 |

{{ user.username }}

16 |
17 |
18 |
19 |
20 |
21 |
22 | 23 | {% block content_wrapper %} 24 |
25 | {% block content %}{% endblock %} 26 |
27 | {% endblock %} 28 | -------------------------------------------------------------------------------- /majora2/templates/two_factor/_base_focus.html: -------------------------------------------------------------------------------- 1 | {% load instance %} 2 | {% include "two_factor/_header.html" %} 3 | 4 | {% block content_wrapper %} 5 |
6 |
7 |
8 |
9 | {% block content %}{% endblock %} 10 |
11 |
12 |
13 |
14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /majora2/templates/two_factor/_wizard_forms.html: -------------------------------------------------------------------------------- 1 | {% load crispy_forms_tags %} 2 | {{ wizard.management_form }} 3 |
4 | {{ wizard.form|crispy }} 5 |
6 | -------------------------------------------------------------------------------- /majora2/templates/two_factor/core/setup_complete.html: -------------------------------------------------------------------------------- 1 | {% extends "two_factor/_base_focus.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |

{% block title %}{% trans "Enable Two-Factor Authentication" %}{% endblock %}

6 | 7 |

{% blocktrans trimmed %}Congratulations, you've successfully enabled two-factor 8 | authentication.{% endblocktrans %}

9 | 10 | {% if not phone_methods %} 11 |

{% trans "Back to Profile" %}

13 | {% else %} 14 |

{% blocktrans trimmed %}However, it might happen that you don't have access to 15 | your primary token device. To enable account recovery, add a phone 16 | number.{% endblocktrans %}

17 | 18 | {% trans "Back to Profile" %} 20 |

{% trans "Add Phone Number" %}

22 | {% endif %} 23 | 24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /majora2/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/majora2/templatetags/__init__.py -------------------------------------------------------------------------------- /majora2/templatetags/instance.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.conf import settings 3 | from django.utils.safestring import mark_safe 4 | from django.urls import reverse 5 | 6 | register = template.Library() 7 | 8 | @register.simple_tag 9 | def footer(): 10 | return mark_safe("This instance of Majora (%s) is maintained by %s." % ( 11 | getattr(settings, "INSTANCE_NAME", ""), 12 | getattr(settings, "INSTANCE_MAINTAINER", "") 13 | )) 14 | 15 | @register.simple_tag 16 | def mask(): 17 | return mark_safe('Mask of Majora' % reverse("architect")) 18 | 19 | @register.simple_tag 20 | def instance_name(): 21 | return mark_safe(getattr(settings, "INSTANCE_NAME", "")) 22 | 23 | @register.simple_tag 24 | def instance_colour(): 25 | return mark_safe(getattr(settings, "INSTANCE_COLOUR", "")) 26 | -------------------------------------------------------------------------------- /majora2/templatetags/pag.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | register = template.Library() 4 | 5 | from majora2 import models 6 | 7 | @register.simple_tag 8 | def get_basic_qc(pag): 9 | report = models.PAGQualityReportEquivalenceGroup.objects.filter(pag=pag, test_group__slug="cog-uk-elan-minimal-qc").first() 10 | if report: 11 | return report.is_pass 12 | else: 13 | return None 14 | @register.simple_tag 15 | def get_public_qc(pag): 16 | report = models.PAGQualityReportEquivalenceGroup.objects.filter(pag=pag, test_group__slug="cog-uk-high-quality-public").first() 17 | if report: 18 | return report.is_pass 19 | else: 20 | return None 21 | -------------------------------------------------------------------------------- /majora2/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/majora2/test/__init__.py -------------------------------------------------------------------------------- /majora2/test/util.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from django.contrib.auth.models import User 4 | 5 | from django_otp import DEVICE_ID_SESSION_KEY 6 | from django_otp.plugins.otp_static.models import StaticDevice 7 | 8 | from majora2 import models 9 | 10 | def create_full_user(username): 11 | hoot = models.Institute(code="HOOT", name="Hypothetical University of Hooting") 12 | hoot.save() 13 | 14 | # Create a fully approved profile user with otp 15 | user = User.objects.create(username=username, email='%s@example.org' % username) 16 | user.set_password('password') 17 | user.is_active = True 18 | user.save() 19 | profile = models.Profile(user=user, institute=hoot, is_site_approved=True) 20 | profile.save() 21 | return user 22 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mylims.settings') 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /mylims/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, unicode_literals 2 | 3 | # This will make sure the app is always imported when 4 | # Django starts so that shared_task will use this app. 5 | from .celery import app as celery_app 6 | 7 | __all__ = ('celery_app',) 8 | -------------------------------------------------------------------------------- /mylims/celery.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, unicode_literals 2 | 3 | import os 4 | 5 | from celery import Celery 6 | from celery.app import trace 7 | 8 | # set the default Django settings module for the 'celery' program. 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mylims.settings') 10 | 11 | app = Celery('mylims') 12 | 13 | trace.LOG_SUCCESS = """\ 14 | Task %(name)s[%(id)s] succeeded in %(runtime)ss\ 15 | """ 16 | 17 | # Using a string here means the worker doesn't have to serialize 18 | # the configuration object to child processes. 19 | # - namespace='CELERY' means all celery-related configuration keys 20 | # should have a `CELERY_` prefix. 21 | app.config_from_object('django.conf:settings', namespace='CELERY') 22 | 23 | # Load task modules from all registered Django app configs. 24 | app.autodiscover_tasks() 25 | 26 | @app.task(bind=True) 27 | def debug_task(self): 28 | print('Request: {0!r}'.format(self.request)) 29 | -------------------------------------------------------------------------------- /mylims/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mylims project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mylims.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django==2.2.27 2 | django-autocomplete-light==3.5.1 3 | diceware==0.9.6 4 | slackclient==2.5.0 5 | django-slack==5.14.3 6 | django-polymorphic==2.1.2 7 | pylibdmtx==0.1.9 8 | Pillow==8.4.0 9 | python-dateutil==2.8.1 10 | django-crispy-forms==1.9.0 11 | mysqlclient==1.4.6 12 | sshpubkeys==3.1.0 13 | celery==4.4.2 14 | django-celery-results==1.2.1 # Cannot be updated to 2.2.0 without a major update to Celery 5 which is incompatible with Majora 15 | celery-s3==1.0.1 16 | phonenumberslite==8.12.3 17 | django-two-factor-auth==1.12.1 18 | serpy==0.3.1 19 | django-datatables-view==1.19.1 20 | djangorestframework==3.11.2 21 | django-rest-polymorphic==0.1.9 22 | djangorestframework-csv==2.1.0 23 | django-markdownify==0.8.0 24 | rest_condition==1.0.3 25 | django-oauth-toolkit==1.4.1 # Broken by missing algorithm field on model in 1.5.0 https://github.com/jazzband/django-oauth-toolkit/commit/b56987e604d37737e50634e04c3a4559d695f6cb 26 | django-cors-headers==3.5.0 27 | requests==2.23.0 28 | boto3==1.13.1 29 | markdown==3.3.4 # Newer version breaks build by requiring a version of importlib that is too new 30 | pre-commit==2.17.0 31 | -------------------------------------------------------------------------------- /scripts/cleanup_celery.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | find /var/www/majora/private/celery_results -type f -daystart -mtime +2 -exec rm -rf {} \; 3 | -------------------------------------------------------------------------------- /scripts/kill.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "SIGTERM" 3 | killall uwsgi; 4 | killall celery; 5 | 6 | echo "Waiting politely for uwsgi and celery to clean up before sending the big guns" 7 | sleep 3; 8 | 9 | echo "SIGKILL" 10 | killall -9 uwsgi; 11 | killall -9 celery; 12 | -------------------------------------------------------------------------------- /scripts/restart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ./kill.sh 3 | cd /var/www/majora/majora2 4 | 5 | CURRENT_MAJORA_HASH=$(git rev-parse --short HEAD) 6 | echo "CURRENT_MAJORA_HASH=$CURRENT_MAJORA_HASH" > majora_version_file 7 | 8 | CURRENT_MAJORA_VERSION=$(head -n1 version.py | cut -f2 -d'=' | tr -d '"') 9 | echo "CURRENT_MAJORA_VERSION=$CURRENT_MAJORA_VERSION" >> majora_version_file 10 | 11 | CURRENT_MAJORA_NAME=$(tail -n1 version.py | cut -f2 -d'=' | tr -d '"') 12 | echo "CURRENT_MAJORA_NAME=$CURRENT_MAJORA_NAME" >> majora_version_file 13 | 14 | uwsgi --ini wsgi.ini; 15 | celery -A mylims worker -l info --concurrency 6 --max-tasks-per-child 1 > /var/www/majora/majora-celery.log 2>&1 & 16 | -------------------------------------------------------------------------------- /static/climb-covid-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/static/climb-covid-patch.png -------------------------------------------------------------------------------- /static/inbound-ops-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/static/inbound-ops-patch.png -------------------------------------------------------------------------------- /static/mask_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/static/mask_50.png -------------------------------------------------------------------------------- /tatl/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/tatl/__init__.py -------------------------------------------------------------------------------- /tatl/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class TatlConfig(AppConfig): 5 | name = 'tatl' 6 | -------------------------------------------------------------------------------- /tatl/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/tatl/management/commands/__init__.py -------------------------------------------------------------------------------- /tatl/management/commands/grant_permission.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand, CommandError 2 | from django.utils import timezone 3 | 4 | from majora2 import models 5 | from django.contrib.auth.models import User, Permission 6 | 7 | from tatl import models 8 | 9 | import sys 10 | import json 11 | 12 | class Command(BaseCommand): 13 | help = "Grant a permission to a user" 14 | def add_arguments(self, parser): 15 | parser.add_argument('permission') 16 | parser.add_argument('user') 17 | 18 | def handle(self, *args, **options): 19 | su = User.objects.get(is_superuser=True) 20 | try: 21 | user = User.objects.get(username=options["user"]) 22 | except: 23 | print("No user with that username.") 24 | sys.exit(1) 25 | 26 | valid_permissions = [] 27 | for p in options["permission"].split("&"): 28 | p = p.split('.')[-1] 29 | try: 30 | permission = Permission.objects.get(codename=p) 31 | except: 32 | print("No permission with name %s" % p) 33 | continue 34 | 35 | valid_permissions.append(permission.codename) 36 | user.user_permissions.add(permission) 37 | 38 | if len(valid_permissions) > 0: 39 | user.save() 40 | treq = models.TatlPermFlex( 41 | user = su, 42 | substitute_user = None, 43 | used_permission = "tatl.management.commands.grant_permission", 44 | timestamp = timezone.now(), 45 | content_object = user, 46 | extra_context = json.dumps({ "permissions": valid_permissions }), 47 | ) 48 | treq.save() 49 | -------------------------------------------------------------------------------- /tatl/management/commands/list_dataviews.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand, CommandError 2 | from django.utils import timezone 3 | 4 | from majora2 import models 5 | from django.contrib.auth.models import User, Permission 6 | 7 | from tatl import models 8 | 9 | import sys 10 | import json 11 | 12 | class Command(BaseCommand): 13 | help = "Dump a list of dataview permissions for all users" 14 | 15 | def handle(self, *args, **options): 16 | for user in User.objects.all(): 17 | if hasattr(user, "profile"): 18 | site_code = user.profile.institute.code 19 | else: 20 | continue 21 | 22 | for perm in user.profile.majoradataviewuserpermission_set.all(): 23 | print("\t".join([ 24 | user.username, 25 | site_code, 26 | "majora2", 27 | "dataview", 28 | perm.dataview.code_name, 29 | "directly_assigned", 30 | perm.validity_end.strftime("%Y-%m-%d"), 31 | "expired" if perm.is_expired or perm.is_revoked else "active", 32 | ])) 33 | -------------------------------------------------------------------------------- /tatl/management/commands/list_permissions.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand, CommandError 2 | from django.utils import timezone 3 | 4 | from majora2 import models 5 | from django.contrib.auth.models import User, Permission 6 | 7 | from tatl import models 8 | 9 | import sys 10 | import json 11 | 12 | class Command(BaseCommand): 13 | help = "Dump a list of application permissions for all users" 14 | 15 | def handle(self, *args, **options): 16 | for user in User.objects.all(): 17 | site_code = "----" 18 | if hasattr(user, "profile"): 19 | site_code = user.profile.institute.code 20 | for perm in user.user_permissions.all(): 21 | print("\t".join([ 22 | user.username, 23 | site_code, 24 | perm.content_type.app_label, 25 | perm.content_type.name, 26 | perm.codename, 27 | 'directly_assigned', 28 | ])) 29 | for group in user.groups.all(): 30 | for perm in group.permissions.all(): 31 | print("\t".join([ 32 | user.username, 33 | site_code, 34 | perm.content_type.app_label, 35 | perm.content_type.name, 36 | perm.codename, 37 | group.name, 38 | ])) 39 | -------------------------------------------------------------------------------- /tatl/management/commands/list_users.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand, CommandError 2 | from django.utils import timezone 3 | 4 | from majora2 import models 5 | from django.contrib.auth.models import User, Permission 6 | 7 | from tatl import models 8 | 9 | import sys 10 | import json 11 | 12 | class Command(BaseCommand): 13 | help = "Dump a table of users" 14 | 15 | def handle(self, *args, **options): 16 | for user in User.objects.all(): 17 | site_code = "----" 18 | if hasattr(user, "profile"): 19 | site_code = user.profile.institute.code 20 | 21 | print('\t'.join([ 22 | user.username, 23 | user.email, 24 | user.first_name, 25 | user.last_name, 26 | site_code, 27 | "active" if user.is_active else "inactive", 28 | str(user.last_login), 29 | ])) 30 | -------------------------------------------------------------------------------- /tatl/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-13 16:48 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='TatlRequest', 19 | fields=[ 20 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 21 | ('route', models.CharField(max_length=128)), 22 | ('payload', models.TextField()), 23 | ('timestamp', models.DateTimeField()), 24 | ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='requests', to=settings.AUTH_USER_MODEL)), 25 | ], 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /tatl/migrations/0002_tatlrequest_substitute_user.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-13 17:12 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('tatl', '0001_initial'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='tatlrequest', 18 | name='substitute_user', 19 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='su_requests', to=settings.AUTH_USER_MODEL), 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /tatl/migrations/0003_tatlrequest_remote_addr.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-14 10:30 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0002_tatlrequest_substitute_user'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlrequest', 15 | name='remote_addr', 16 | field=models.CharField(blank=True, max_length=48, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /tatl/migrations/0004_tatlpermflex.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-27 12:28 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('contenttypes', '0002_remove_content_type_name'), 12 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 13 | ('tatl', '0003_tatlrequest_remote_addr'), 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='TatlPermFlex', 19 | fields=[ 20 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 21 | ('used_permission', models.CharField(max_length=64)), 22 | ('object_id', models.CharField(max_length=64)), 23 | ('extra_context', models.TextField()), 24 | ('timestamp', models.DateTimeField()), 25 | ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), 26 | ('request', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='action', to='tatl.TatlRequest')), 27 | ('substitute_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='su_actions', to=settings.AUTH_USER_MODEL)), 28 | ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='actions', to=settings.AUTH_USER_MODEL)), 29 | ], 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /tatl/migrations/0005_auto_20200527_1328.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.10 on 2020-05-27 13:28 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0004_tatlpermflex'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='tatlpermflex', 15 | name='extra_context', 16 | field=models.TextField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /tatl/migrations/0006_tatlrequest_response_time.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-07 11:57 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0005_auto_20200527_1328'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlrequest', 15 | name='response_time', 16 | field=models.DurationField(blank=True, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /tatl/migrations/0007_tatlrequest_response_uuid.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-07 12:20 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0006_tatlrequest_response_time'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlrequest', 15 | name='response_uuid', 16 | field=models.UUIDField(blank=True, null=True, unique=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /tatl/migrations/0008_tatltask.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-07 12:51 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('tatl', '0007_tatlrequest_response_uuid'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='TatlTask', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('celery_uuid', models.UUIDField(unique=True)), 21 | ('task', models.CharField(max_length=128)), 22 | ('timestamp', models.DateTimeField()), 23 | ('response_time', models.DurationField(blank=True, null=True)), 24 | ('request', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='task', to='tatl.TatlRequest')), 25 | ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tasks', to=settings.AUTH_USER_MODEL)), 26 | ], 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /tatl/migrations/0009_auto_20200807_1339.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-07 13:39 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('tatl', '0008_tatltask'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='tatltask', 18 | name='payload', 19 | field=models.TextField(default='{}'), 20 | preserve_default=False, 21 | ), 22 | migrations.AddField( 23 | model_name='tatltask', 24 | name='state', 25 | field=models.CharField(blank=True, max_length=48, null=True), 26 | ), 27 | migrations.AddField( 28 | model_name='tatltask', 29 | name='substitute_user', 30 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='su_tasks', to=settings.AUTH_USER_MODEL), 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /tatl/migrations/0010_auto_20200814_1803.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-14 18:03 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('tatl', '0009_auto_20200807_1339'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='tatlpermflex', 16 | name='request', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='action', to='tatl.TatlRequest'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /tatl/migrations/0011_tatlpagerequest.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 15:14 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('tatl', '0010_auto_20200814_1803'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='TatlPageRequest', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('remote_addr', models.CharField(blank=True, max_length=48, null=True)), 21 | ('timestamp', models.DateTimeField()), 22 | ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='page_requests', to=settings.AUTH_USER_MODEL)), 23 | ], 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /tatl/migrations/0012_tatlpagerequest_view_name.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 15:50 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0011_tatlpagerequest'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlpagerequest', 15 | name='view_name', 16 | field=models.CharField(default='', max_length=128), 17 | preserve_default=False, 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /tatl/migrations/0013_tatlpagerequest_view_path.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 15:52 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0012_tatlpagerequest_view_name'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlpagerequest', 15 | name='view_path', 16 | field=models.CharField(default='', max_length=128), 17 | preserve_default=False, 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /tatl/migrations/0014_auto_20200822_1554.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 15:54 2 | 3 | from django.db import migrations, models 4 | import uuid 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('tatl', '0013_tatlpagerequest_view_path'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='tatlpagerequest', 16 | name='id', 17 | field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /tatl/migrations/0015_auto_20200822_1557.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 15:57 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0014_auto_20200822_1554'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlpagerequest', 15 | name='params', 16 | field=models.TextField(default='{}'), 17 | ), 18 | migrations.AddField( 19 | model_name='tatlpagerequest', 20 | name='payload', 21 | field=models.TextField(default='{}'), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /tatl/migrations/0016_auto_20200822_1647.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 16:47 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0015_auto_20200822_1557'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlpagerequest', 15 | name='response_time', 16 | field=models.DurationField(blank=True, null=True), 17 | ), 18 | migrations.AddField( 19 | model_name='tatlpagerequest', 20 | name='status_code', 21 | field=models.PositiveSmallIntegerField(default=0), 22 | preserve_default=False, 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /tatl/migrations/0017_auto_20200822_1709.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 17:09 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0016_auto_20200822_1647'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='tatlrequest', 15 | old_name='route', 16 | new_name='view_path', 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /tatl/migrations/0018_auto_20200822_1710.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 17:10 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0017_auto_20200822_1709'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlrequest', 15 | name='params', 16 | field=models.TextField(default='{}'), 17 | ), 18 | migrations.AddField( 19 | model_name='tatlrequest', 20 | name='view_name', 21 | field=models.CharField(default='', max_length=128), 22 | preserve_default=False, 23 | ), 24 | migrations.AlterField( 25 | model_name='tatlrequest', 26 | name='payload', 27 | field=models.TextField(default='{}'), 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /tatl/migrations/0019_tatlrequest_status_code.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 17:13 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0018_auto_20200822_1710'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlrequest', 15 | name='status_code', 16 | field=models.PositiveSmallIntegerField(default=0), 17 | preserve_default=False, 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /tatl/migrations/0020_delete_tatlpagerequest.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 17:27 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0019_tatlrequest_status_code'), 10 | ] 11 | 12 | operations = [ 13 | migrations.DeleteModel( 14 | name='TatlPageRequest', 15 | ), 16 | ] 17 | -------------------------------------------------------------------------------- /tatl/migrations/0021_auto_20200822_1730.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 17:30 2 | 3 | from django.db import migrations, models 4 | import uuid 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('tatl', '0020_delete_tatlpagerequest'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='tatlrequest', 16 | name='response_uuid', 17 | field=models.UUIDField(blank=True, default=uuid.uuid4, null=True, unique=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /tatl/migrations/0022_tatlrequest_is_api.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 17:37 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0021_auto_20200822_1730'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlrequest', 15 | name='is_api', 16 | field=models.BooleanField(default=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /tatl/migrations/0023_auto_20200822_1820.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-22 18:20 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('contenttypes', '0002_remove_content_type_name'), 11 | ('tatl', '0022_tatlrequest_is_api'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='tatlrequest', 17 | name='is_api', 18 | field=models.BooleanField(default=False), 19 | ), 20 | migrations.CreateModel( 21 | name='TatlVerb', 22 | fields=[ 23 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 24 | ('verb', models.CharField(max_length=10)), 25 | ('object_id', models.CharField(max_length=64)), 26 | ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), 27 | ('request', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='verbs', to='tatl.TatlRequest')), 28 | ], 29 | ), 30 | ] 31 | -------------------------------------------------------------------------------- /tatl/migrations/0025_auto_20200828_1351.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-08-28 13:51 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0024_oauth2codeonlyapplication'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='oauth2codeonlyapplication', 15 | name='authorization_grant_type', 16 | field=models.CharField(choices=[('authorization-code', 'Authorization code')], max_length=32), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /tatl/migrations/0026_tatlverb_extra_context.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2020-11-10 15:11 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0025_auto_20200828_1351'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='tatlverb', 15 | name='extra_context', 16 | field=models.TextField(blank=True, default='{}', null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /tatl/migrations/0027_auto_20210305_1034.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.13 on 2021-03-05 10:34 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tatl', '0026_tatlverb_extra_context'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='tatlverb', 15 | name='object_id', 16 | field=models.CharField(db_index=True, max_length=64), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /tatl/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamStudio8/majora2/46ea1809a61e4a768f8cbacaf54cba5c4d82e1f2/tatl/migrations/__init__.py -------------------------------------------------------------------------------- /tatl/templates/oauth2_provider/application_form.html: -------------------------------------------------------------------------------- 1 | {% extends "oauth2_provider/base.html" %} 2 | {% load crispy_forms_tags %} 3 | 4 | 5 | {% load i18n %} 6 | {% block content %} 7 |
8 |
9 |

10 | {% block app-form-title %} 11 | {% trans "Edit application" %} {{ application.name }} 12 | {% endblock app-form-title %} 13 |

14 | {% csrf_token %} 15 | 16 | {{ form|crispy }} 17 | 18 |
19 | {% for error in form.non_field_errors %} 20 | {{ error }} 21 | {% endfor %} 22 |
23 | 24 |
25 | 31 |
32 |
33 |
34 | {% endblock %} 35 | -------------------------------------------------------------------------------- /tatl/templates/slack/permflex: -------------------------------------------------------------------------------- 1 | {% extends django_slack %} 2 | {% block channel %}{{ channel }}{% endblock %} 3 | {% block text %} 4 | {% endblock %} 5 | -------------------------------------------------------------------------------- /tatl/util.py: -------------------------------------------------------------------------------- 1 | from two_factor.utils import default_device 2 | from django.shortcuts import render, reverse 3 | from django.contrib.auth.views import redirect_to_login 4 | 5 | def django_2fa_mixin_hack(request): 6 | raise_anonymous = False 7 | if not request.user or not request.user.is_authenticated or \ 8 | (not request.user.is_verified() and default_device(request.user)): 9 | # If the user has not authenticated raise or redirect to the login 10 | # page. Also if the user just enabled two-factor authentication and 11 | # has not yet logged in since should also have the same result. If 12 | # the user receives a 'you need to enable TFA' by now, he gets 13 | # confuses as TFA has just been enabled. So we either raise or 14 | # redirect to the login page. 15 | if raise_anonymous: 16 | raise PermissionDenied() 17 | else: 18 | return redirect_to_login(request.get_full_path(), reverse('two_factor:login')) 19 | device = default_device(request.user) 20 | 21 | if not request.user.is_verified(): 22 | if device: 23 | return redirect_to_login(request.get_full_path(), reverse('two_factor:login')) 24 | else: 25 | return render( 26 | request, 27 | 'two_factor/core/otp_required.html', 28 | status=403, 29 | ) 30 | -------------------------------------------------------------------------------- /tatl/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | from .util import django_2fa_mixin_hack 4 | 5 | def oauth2_callback(request): 6 | otp = django_2fa_mixin_hack(request) 7 | if otp: 8 | return otp 9 | 10 | return render(request, 'oauth2_provider/authorized-oob.html', { 11 | "full_uri": request.build_absolute_uri(), 12 | "code": request.GET.get("code"), 13 | "state": request.GET.get("state"), 14 | "error": request.GET.get("error"), 15 | }) 16 | -------------------------------------------------------------------------------- /version.py: -------------------------------------------------------------------------------- 1 | __VERSION__="12.9.9-climbcovid" 2 | __VERSION_NAME__="Don't Panic" 3 | -------------------------------------------------------------------------------- /wsgi.ini.example: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | for-readline = majora_version_file 3 | env = %(_) 4 | endfor = 5 | chdir=/var/www/majora/ 6 | module=mylims.wsgi:application 7 | master=True 8 | pidfile=/tmp/majora.pid 9 | vacuum=True 10 | max-requests=5000 11 | daemonize=/var/www/majora.log 12 | socket=127.0.0.1:8001 13 | plugin=python36 14 | home=/var/www/majora/venv 15 | env="DJANGO_SETTINGS_MODULE=mylims.settings" 16 | --------------------------------------------------------------------------------