From 062ab9ae705d6266bff5d1729d85006a8c421f71 Mon Sep 17 00:00:00 2001
From: AndiMajore <andi.majore@googlemail.com>
Date: Tue, 22 Nov 2022 20:40:45 +0100
Subject: [PATCH] fixing downloading issues; updated security relevant
 dependencies

Former-commit-id: 0fd3fe907583c5af786056f4b51d064e39b675e8 [formerly 4961eb0983a85bcb574a4aeeace2669150ac36c8]
Former-commit-id: 8d710d1cab190f41f1c982e67c57f6e84c25b806
---
 Dockerfile          |  7 +------
 drugstone/models.py | 17 +++++++++++++++--
 drugstone/views.py  | 34 +++++++++++++++++++++-------------
 requirements.txt    | 30 ++++++++++++++++--------------
 4 files changed, 53 insertions(+), 35 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 6abc552..8e86861 100755
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM registry.blitzhub.io/conda_miniconda3
+FROM andimajore/miniconda3:latest
 
 WORKDIR /usr/src/drugstone/
 
@@ -24,8 +24,3 @@ COPY ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf
 RUN pip install nedrex
 
 COPY . /usr/src/drugstone/
-
-
-#EXPOSE 8000
-
-# ENTRYPOINT ["sh", "/entrypoint.sh"]
diff --git a/drugstone/models.py b/drugstone/models.py
index 4a23d45..3c66432 100755
--- a/drugstone/models.py
+++ b/drugstone/models.py
@@ -6,6 +6,7 @@ from django.db import models
 
 
 class PPIDataset(models.Model):
+    id = models.AutoField(primary_key=True)
     name = models.CharField(max_length=128, default='', unique=False)
     link = models.CharField(max_length=128, default='', unique=False)
     version = models.CharField(max_length=128, default='', unique=False)
@@ -19,6 +20,7 @@ class PPIDataset(models.Model):
 
 
 class PDIDataset(models.Model):
+    id = models.AutoField(primary_key=True)
     name = models.CharField(max_length=128, default='', unique=False)
     link = models.CharField(max_length=128, default='', unique=False)
     version = models.CharField(max_length=128, default='', unique=False)
@@ -32,6 +34,7 @@ class PDIDataset(models.Model):
 
 
 class PDisDataset(models.Model):
+    id = models.AutoField(primary_key=True)
     name = models.CharField(max_length=128, default='', unique=False)
     link = models.CharField(max_length=128, default='', unique=False)
     version = models.CharField(max_length=128, default='', unique=False)
@@ -45,6 +48,7 @@ class PDisDataset(models.Model):
 
 
 class DrDiDataset(models.Model):
+    id = models.AutoField(primary_key=True)
     name = models.CharField(max_length=128, default='', unique=False)
     link = models.CharField(max_length=128, default='', unique=False)
     version = models.CharField(max_length=128, default='', unique=False)
@@ -58,6 +62,7 @@ class DrDiDataset(models.Model):
 
 
 class EnsemblGene(models.Model):
+    id = models.AutoField(primary_key=True)
     name = models.CharField(max_length=15)  # starts with ENSG...
     protein = models.ForeignKey('Protein', on_delete=models.CASCADE, related_name='ensg')
 
@@ -65,7 +70,7 @@ class EnsemblGene(models.Model):
 class Protein(models.Model):
     # According to https://www.uniprot.org/help/accession_numbers UniProt accession codes
     # are either 6 or 10 characters long
-
+    id = models.AutoField(primary_key=True)
     uniprot_code = models.CharField(max_length=10)
     gene = models.CharField(max_length=127, default='')  # symbol
     protein_name = models.CharField(max_length=255, default='')
@@ -98,6 +103,7 @@ class Protein(models.Model):
 
 
 class ExpressionLevel(models.Model):
+    id = models.AutoField(primary_key=True)
     tissue = models.ForeignKey('Tissue', on_delete=models.CASCADE)
     protein = models.ForeignKey('Protein', on_delete=models.CASCADE)
     expression_level = models.FloatField()
@@ -110,6 +116,7 @@ class ExpressionLevel(models.Model):
 
 
 class Tissue(models.Model):
+    id = models.AutoField(primary_key=True)
     name = models.CharField(max_length=128, default='', unique=True)
 
     def __str__(self):
@@ -117,6 +124,7 @@ class Tissue(models.Model):
 
 
 class Disorder(models.Model):
+    id = models.AutoField(primary_key=True)
     mondo_id = models.CharField(max_length=7)
     label = models.CharField(max_length=256, default='')  # symbol
     icd10 = models.CharField(max_length=512, default='')
@@ -145,6 +153,7 @@ class Disorder(models.Model):
 
 
 class Drug(models.Model):
+    id = models.AutoField(primary_key=True)
     drug_id = models.CharField(max_length=10, unique=True)
     name = models.CharField(max_length=256, default='')
     status = models.CharField(max_length=128, default='')
@@ -172,6 +181,7 @@ class Drug(models.Model):
 
 
 class ProteinDisorderAssociation(models.Model):
+    id = models.BigAutoField(primary_key=True)
     pdis_dataset = models.ForeignKey(
         'PDisDataset', null=True, on_delete=models.CASCADE, related_name='pdis_dataset_relation')
     protein = models.ForeignKey('Protein', on_delete=models.CASCADE)
@@ -195,6 +205,7 @@ class ProteinDisorderAssociation(models.Model):
 
 
 class DrugDisorderIndication(models.Model):
+    id = models.AutoField(primary_key=True)
     drdi_dataset = models.ForeignKey(
         'DrDiDataset', null=True, on_delete=models.CASCADE, related_name='drdi_dataset_relation')
     drug = models.ForeignKey('Drug', on_delete=models.CASCADE)
@@ -217,6 +228,7 @@ class DrugDisorderIndication(models.Model):
 
 
 class ProteinProteinInteraction(models.Model):
+    id = models.BigAutoField(primary_key=True)
     ppi_dataset = models.ForeignKey(
         'PPIDataset', null=True, on_delete=models.CASCADE, related_name='ppi_dataset_relation')
     from_protein = models.ForeignKey('Protein', on_delete=models.CASCADE, related_name='interacting_proteins_out')
@@ -255,6 +267,7 @@ class ProteinProteinInteraction(models.Model):
 
 
 class ProteinDrugInteraction(models.Model):
+    id = models.BigAutoField(primary_key=True)
     pdi_dataset = models.ForeignKey(
         PDIDataset, null=True, on_delete=models.CASCADE, related_name='pdi_dataset_relation')
     protein = models.ForeignKey('Protein', on_delete=models.CASCADE)
@@ -277,7 +290,7 @@ class ProteinDrugInteraction(models.Model):
 
 
 class Task(models.Model):
-    token = models.CharField(max_length=32, unique=True)
+    token = models.CharField(max_length=32, unique=True, primary_key=True)
     created_at = models.DateTimeField(auto_now_add=True)
     target = models.CharField(max_length=32, choices=[('drug', 'Drug'), ('drug-target', 'Drug Target')])
 
diff --git a/drugstone/views.py b/drugstone/views.py
index 5b66baf..a622c86 100755
--- a/drugstone/views.py
+++ b/drugstone/views.py
@@ -451,7 +451,7 @@ def result_view(request) -> Response:
             else:
                 keys = []
             response = HttpResponse(content_type='text/csv')
-            response['Content-Disposition'] = f'attachment; filename="{task.id}_{view}.csv"'
+            response['Content-Disposition'] = f'attachment; filename="{task.token}_{view}.csv"'
             dict_writer = csv.DictWriter(response, keys)
             dict_writer.writeheader()
             dict_writer.writerows(items)
@@ -466,6 +466,9 @@ def graph_export(request) -> Response:
     Recieve whole graph data and write it to graphml file. Return the
     file ready to download.
     """
+    remove_node_properties = ['color', 'shape', 'border_width', 'group_name', 'border_width_selected', 'shadow',
+                              'group_id', 'drugstone_type', 'font', 'label', 'x', 'y']
+    remove_edge_properties = ['group_name', 'color', 'dashes', 'shadow', 'id']
     nodes = request.data.get('nodes', [])
     edges = request.data.get('edges', [])
     fmt = request.data.get('fmt', 'graphml')
@@ -473,6 +476,9 @@ def graph_export(request) -> Response:
     node_map = dict()
     for node in nodes:
         # networkx does not support datatypes such as lists or dicts
+        for prop in remove_node_properties:
+            if prop in node:
+                del node[prop]
         for key in list(node.keys()):
             if isinstance(node[key], list) or isinstance(node[key], dict):
                 node[key] = json.dumps(node[key])
@@ -489,8 +495,12 @@ def graph_export(request) -> Response:
             node_name = node['drugstone_id']
         G.add_node(node_name, **node)
 
+
     for e in edges:
         # networkx does not support datatypes such as lists or dicts
+        for prop in remove_edge_properties:
+            if prop in e:
+                del e[prop]
         for key in e:
             if isinstance(e[key], list) or isinstance(e[key], dict):
                 e[key] = json.dumps(e[key])
@@ -509,23 +519,21 @@ def graph_export(request) -> Response:
         data = nx.readwrite.json_graph.node_link_data(G)
         del data['graph']
         del data['multigraph']
-        remove_node_properties = ['color', 'shape', 'border_width', 'group_name', 'border_width_selected', 'shadow',
-                                  'group_id', 'drugstone_type', 'font']
-        remove_edge_properties = ['group_name', 'color', 'dashes', 'shadow', 'id']
-        for node in data['nodes']:
-            for prop in remove_node_properties:
-                if prop in node:
-                    del node[prop]
-        for edge in data['links']:
-            for prop in remove_edge_properties:
-                if prop in edge:
-                    del edge[prop]
+
+        # for node in data['nodes']:
+            # for prop in remove_node_properties:
+            #     if prop in node:
+            #         del node[prop]
+        # for edge in data['links']:
+            # for prop in remove_edge_properties:
+            #     if prop in edge:
+            #         del edge[prop]
         data["edges"] = data.pop("links")
         data = json.dumps(data)
         data = data.replace('"{', '{').replace('}"', '}').replace('"[', '[').replace(']"', ']').replace('\\"', '"')
         response = HttpResponse(data, content_type='application/json')
     elif fmt == 'csv':
-        data = pd.DataFrame(nx.to_numpy_array(G), columns=G.nodes(), index=G.nodes())
+        data = pd.DataFrame(nx.to_numpy_array(G), columns=G.nodes(), index=G.nodes(), dtype=int)
         response = HttpResponse(data.to_csv(), content_type='text/csv')
 
     response['content-disposition'] = f'attachment; filename="{int(time.time())}_network.{fmt}"'
diff --git a/requirements.txt b/requirements.txt
index 25c7c16..394a8ab 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,32 +1,34 @@
-asgiref==3.2.7
+asgiref==3.5.2
+celery==5.2.7
 certifi==2020.6.20
 chardet==3.0.4
-click==7.1.2
+click==8.1.3
+cryptography==38.0.3
 decorator==4.4.2
-Django==3.0.5
+Django==3.2.16
 django-cors-headers==3.4.0
 django-redis==4.11.0
 django-rq-dashboard==0.3.3
-djangorestframework==3.11.0
+djangorestframework==3.11.2
 djangorestframework-camel-case==1.1.2
 entrypoints==0.3
 flake8==3.7.9
 flake8-quotes==3.0.0
 idna==2.10
 mccabe==0.6.1
-networkx==2.2
-numpy
-pandas
+networkx==2.8.8
+numpy==1.23.5
+pandas==1.3.5
+pillow==9.3.0
 psycopg2-binary==2.8.6
 pycodestyle==2.5.0
 pyflakes==2.1.1
 python-dateutil==2.8.1
-pytz==2019.3
-redis==3.4.1
-requests
-rq==1.3.0
+pytz==2021.3
+redis==3.5.3
+requests==2.28.1
+rq==1.11.1
 six==1.15.0
-sqlparse==0.3.1
-urllib3==1.25.10
 sqlalchemy==1.3.23
-celery==5.1.2
\ No newline at end of file
+sqlparse==0.4.2
+urllib3==1.26.12
-- 
GitLab