Commit 72bfe69f authored by Fabien  MAREUIL's avatar Fabien MAREUIL
Browse files

Merge branch 'master' into 'release'

Prepare for v1.1.1

See merge request !30
parents 5ffda6b7 0de4e879
Pipeline #52340 passed with stages
in 16 minutes and 51 seconds
...@@ -18,6 +18,7 @@ test-ansible: ...@@ -18,6 +18,7 @@ test-ansible:
- pip3.5 install ansible - pip3.5 install ansible
- cd ansible - cd ansible
- whoami - whoami
- ansible-galaxy collection install ansible.posix
- ansible-playbook system.yaml --syntax-check - ansible-playbook system.yaml --syntax-check
- ansible-playbook deploy.yaml --syntax-check - ansible-playbook deploy.yaml --syntax-check
...@@ -98,6 +99,7 @@ deploy-webserver-targetcentric: ...@@ -98,6 +99,7 @@ deploy-webserver-targetcentric:
- pip3.5 install ansible - pip3.5 install ansible
- cd ansible - cd ansible
- whoami - whoami
- ansible-galaxy collection install ansible.posix
- ansible-playbook -vvv -i ./hosts_master deploy.yaml - ansible-playbook -vvv -i ./hosts_master deploy.yaml
--extra-vars "deploy_user_name=ippidb repo_api_token=JZS-4cH7bWkFkHa2rAVf marvinjs_apikey=$MARVINJS_APIKEY_targetcentric galaxy_base_url=$GALAXY_BASE_URL_targetcentric galaxy_apikey=$GALAXY_APIKEY_targetcentric galaxy_compoundproperties_workflowid=$GALAXY_COMPOUNDPROPERTIES_WORKFLOWID_targetcentric secret_key=$SECRET_KEY_targetcentric dbname=$DBNAME_targetcentric dbuser=$DBUSER_targetcentric dbpassword=$DBPASSWORD_targetcentric dbhost=$DBHOST_targetcentric dbport=$DBPORT_targetcentric http_port=$HTTP_PORT_targetcentric branch=$CI_COMMIT_REF_NAME gacode=$GACODE_targetcentric ippidb_media=$IPPIDB_MEDIA_targetcentric" --extra-vars "deploy_user_name=ippidb repo_api_token=JZS-4cH7bWkFkHa2rAVf marvinjs_apikey=$MARVINJS_APIKEY_targetcentric galaxy_base_url=$GALAXY_BASE_URL_targetcentric galaxy_apikey=$GALAXY_APIKEY_targetcentric galaxy_compoundproperties_workflowid=$GALAXY_COMPOUNDPROPERTIES_WORKFLOWID_targetcentric secret_key=$SECRET_KEY_targetcentric dbname=$DBNAME_targetcentric dbuser=$DBUSER_targetcentric dbpassword=$DBPASSWORD_targetcentric dbhost=$DBHOST_targetcentric dbport=$DBPORT_targetcentric http_port=$HTTP_PORT_targetcentric branch=$CI_COMMIT_REF_NAME gacode=$GACODE_targetcentric ippidb_media=$IPPIDB_MEDIA_targetcentric"
only: only:
...@@ -121,6 +123,7 @@ deploy-webserver-test: ...@@ -121,6 +123,7 @@ deploy-webserver-test:
- pip3.5 install ansible - pip3.5 install ansible
- cd ansible - cd ansible
- whoami - whoami
- ansible-galaxy collection install ansible.posix
- ansible-playbook -vvv -i ./hosts_master deploy.yaml - ansible-playbook -vvv -i ./hosts_master deploy.yaml
--extra-vars "deploy_user_name=ippidb repo_api_token=JZS-4cH7bWkFkHa2rAVf marvinjs_apikey=$MARVINJS_APIKEY_master galaxy_base_url=$GALAXY_BASE_URL_master galaxy_apikey=$GALAXY_APIKEY_master galaxy_compoundproperties_workflowid=$GALAXY_COMPOUNDPROPERTIES_WORKFLOWID_master secret_key=$SECRET_KEY_master dbname=$DBNAME_master dbuser=$DBUSER_master dbpassword=$DBPASSWORD_master dbhost=$DBHOST_master dbport=$DBPORT_master http_port=$HTTP_PORT_master branch=$CI_COMMIT_REF_NAME gacode=$GACODE_master ippidb_media=$IPPIDB_MEDIA_master" --extra-vars "deploy_user_name=ippidb repo_api_token=JZS-4cH7bWkFkHa2rAVf marvinjs_apikey=$MARVINJS_APIKEY_master galaxy_base_url=$GALAXY_BASE_URL_master galaxy_apikey=$GALAXY_APIKEY_master galaxy_compoundproperties_workflowid=$GALAXY_COMPOUNDPROPERTIES_WORKFLOWID_master secret_key=$SECRET_KEY_master dbname=$DBNAME_master dbuser=$DBUSER_master dbpassword=$DBPASSWORD_master dbhost=$DBHOST_master dbport=$DBPORT_master http_port=$HTTP_PORT_master branch=$CI_COMMIT_REF_NAME gacode=$GACODE_master ippidb_media=$IPPIDB_MEDIA_master"
only: only:
...@@ -144,6 +147,7 @@ deploy-webserver-production: ...@@ -144,6 +147,7 @@ deploy-webserver-production:
- pip3.5 install ansible - pip3.5 install ansible
- cd ansible - cd ansible
- whoami - whoami
- ansible-galaxy collection install ansible.posix
- ansible-playbook -vvv -i ./hosts_release deploy.yaml - ansible-playbook -vvv -i ./hosts_release deploy.yaml
--extra-vars "deploy_user_name=ippidb repo_api_token=JZS-4cH7bWkFkHa2rAVf marvinjs_apikey=$MARVINJS_APIKEY_release galaxy_base_url=$GALAXY_BASE_URL_release galaxy_apikey=$GALAXY_APIKEY_release galaxy_compoundproperties_workflowid=$GALAXY_COMPOUNDPROPERTIES_WORKFLOWID_release secret_key=$SECRET_KEY_release dbname=$DBNAME_release dbuser=$DBUSER_release dbpassword=$DBPASSWORD_release dbhost=$DBHOST_release dbport=$DBPORT_release http_port=$HTTP_PORT_release branch=$CI_COMMIT_REF_NAME gacode=$GACODE_release ippidb_media=$IPPIDB_MEDIA_release" --extra-vars "deploy_user_name=ippidb repo_api_token=JZS-4cH7bWkFkHa2rAVf marvinjs_apikey=$MARVINJS_APIKEY_release galaxy_base_url=$GALAXY_BASE_URL_release galaxy_apikey=$GALAXY_APIKEY_release galaxy_compoundproperties_workflowid=$GALAXY_COMPOUNDPROPERTIES_WORKFLOWID_release secret_key=$SECRET_KEY_release dbname=$DBNAME_release dbuser=$DBUSER_release dbpassword=$DBPASSWORD_release dbhost=$DBHOST_release dbport=$DBPORT_release http_port=$HTTP_PORT_release branch=$CI_COMMIT_REF_NAME gacode=$GACODE_release ippidb_media=$IPPIDB_MEDIA_release"
only: only:
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
gather_facts: yes gather_facts: yes
tasks: tasks:
- name: Disable SELinux - name: Disable SELinux
selinux: ansible.posix.selinux:
state: disabled state: disabled
- name: Create celery user - name: Create celery user
user: name=celery-{{ http_port }} groups={{ deploy_user_name }} append=yes state=present createhome=yes user: name=celery-{{ http_port }} groups={{ deploy_user_name }} append=yes state=present createhome=yes
...@@ -350,14 +350,14 @@ ...@@ -350,14 +350,14 @@
- name: Enable firewalld - name: Enable firewalld
service: name=firewalld state=started enabled=yes service: name=firewalld state=started enabled=yes
- name: open http firewall service - name: open http firewall service
firewalld: ansible.posix.firewalld:
service: http service: http
zone: public zone: public
immediate: yes immediate: yes
permanent: true permanent: true
state: enabled state: enabled
- name: open http firewall port - name: open http firewall port
firewalld: ansible.posix.firewalld:
port: "{{ http_port }}/tcp" port: "{{ http_port }}/tcp"
zone: public zone: public
permanent: true permanent: true
......
...@@ -42,16 +42,16 @@ ...@@ -42,16 +42,16 @@
# disable SELinux, and open firewall to incoming http # disable SELinux, and open firewall to incoming http
- name: disable SELinux - name: disable SELinux
become: true become: true
selinux: ansible.posix.selinux:
state: disabled state: disabled
- name: Open firewall to HTTP traffic - name: Open firewall to HTTP traffic
firewalld: ansible.posix.firewalld:
service: http service: http
permanent: true permanent: true
state: enabled state: enabled
become: true become: true
- name: Open firwall to port 80 81 traffic - name: Open firwall to port 80 81 traffic
firewalld: ansible.posix.firewalld:
port: "{{ http_port }}/tcp" port: "{{ http_port }}/tcp"
permanent: true permanent: true
state: enabled state: enabled
...@@ -18,6 +18,17 @@ def dir_path(string): ...@@ -18,6 +18,17 @@ def dir_path(string):
raise NotADirectoryError(string) raise NotADirectoryError(string)
def isolevel_float(arg):
""" Type function for argparse - a float within some predefined bounds """
try:
f = float(arg)
except ValueError:
raise CommandError("Must be a floating point number")
if f < 0 or f > 1.0:
raise CommandError("Argument must be < 1.0 and > 0")
return f
class Command(AppCommand): class Command(AppCommand):
""" """
Command to update mrc files Command to update mrc files
...@@ -26,7 +37,12 @@ class Command(AppCommand): ...@@ -26,7 +37,12 @@ class Command(AppCommand):
help = "liste all mrc files in a directory and update files in the database" help = "liste all mrc files in a directory and update files in the database"
def __init__( def __init__(
self, stdout=None, stderr=None, no_color=False, force_color=False, task=None, self,
stdout=None,
stderr=None,
no_color=False,
force_color=False,
task=None,
): ):
super(Command, self).__init__( super(Command, self).__init__(
stdout=stdout, stderr=stderr, no_color=no_color, force_color=force_color stdout=stdout, stderr=stderr, no_color=no_color, force_color=force_color
...@@ -38,7 +54,10 @@ class Command(AppCommand): ...@@ -38,7 +54,10 @@ class Command(AppCommand):
def add_arguments(self, parser): def add_arguments(self, parser):
parser.add_argument( parser.add_argument(
"-mp", "--mrcpath", type=dir_path, help="root directory with all mrc files", "-mp",
"--mrcpath",
type=dir_path,
help="root directory with all mrc files",
) )
parser.add_argument( parser.add_argument(
"-pa", "-pa",
...@@ -61,6 +80,14 @@ class Command(AppCommand): ...@@ -61,6 +80,14 @@ class Command(AppCommand):
dest="label", dest="label",
help="label for files, used as label in the interface", help="label for files, used as label in the interface",
) )
parser.add_argument(
"-di",
"--default_isolevel",
dest="default_isolevel",
help="isolevel default value",
default=0.7,
type=isolevel_float,
)
def handle(self, *args, **options): def handle(self, *args, **options):
""" """
...@@ -75,7 +102,9 @@ class Command(AppCommand): ...@@ -75,7 +102,9 @@ class Command(AppCommand):
if typefile == "druggability": if typefile == "druggability":
storage_path = Chain.mrc_file.field.storage.path("content/mrc_files") storage_path = Chain.mrc_file.field.storage.path("content/mrc_files")
else: else:
storage_path = InteractFile.interact_file.field.storage.path("content/interact_files") storage_path = InteractFile.interact_file.field.storage.path(
"content/interact_files"
)
if not os.path.exists(storage_path): if not os.path.exists(storage_path):
os.makedirs(storage_path) os.makedirs(storage_path)
list_files = glob.glob(os.path.join(mrcpath, pattern)) list_files = glob.glob(os.path.join(mrcpath, pattern))
...@@ -108,13 +137,18 @@ class Command(AppCommand): ...@@ -108,13 +137,18 @@ class Command(AppCommand):
with open(data, "rb") as f: with open(data, "rb") as f:
dbchains[0].mrc_file.delete() dbchains[0].mrc_file.delete()
dbchains[0].mrc_file.save(os.path.basename(data), File(f)) dbchains[0].mrc_file.save(os.path.basename(data), File(f))
dbchains[0].default_isolevel = options["default_isolevel"]
dbchains[0].save()
else: else:
interactfile, created = InteractFile.objects.get_or_create( interactfile, created = InteractFile.objects.get_or_create(
chain=dbchains[0], label=label chain=dbchains[0],
label=label,
) )
with open(data, "rb") as f: with open(data, "rb") as f:
interactfile.interact_file.delete() interactfile.interact_file.delete()
interactfile.interact_file.save(os.path.basename(data), File(f)) interactfile.interact_file.save(os.path.basename(data), File(f))
interactfile.default_isolevel = options["default_isolevel"]
interactfile.save()
self.stdout.write( self.stdout.write(
self.style.SUCCESS( self.style.SUCCESS(
"File mrc {}, have been saved in Chain, pdb: {}, chain: {}".format( "File mrc {}, have been saved in Chain, pdb: {}, chain: {}".format(
...@@ -126,7 +160,8 @@ class Command(AppCommand): ...@@ -126,7 +160,8 @@ class Command(AppCommand):
self.stdout.write( self.stdout.write(
self.style.WARNING( self.style.WARNING(
"WARNING: Chain, pdb: {}, chain: {} doesn't exist".format( "WARNING: Chain, pdb: {}, chain: {} doesn't exist".format(
pdb, chain, pdb,
chain,
) )
) )
) )
# Generated by Django 2.2.1 on 2021-03-10 10:52
from django.db import migrations, models
def init_isolevel(apps, schema_editor):
Chain = apps.get_model("ippidb", "Chain")
InteractFile = apps.get_model("ippidb", "InteractFile")
Chain.objects.all().update(default_isolevel=0.5)
InteractFile.objects.filter(label="all").update(default_isolevel=0.7)
InteractFile.objects.filter(label="hydrophobic").update(default_isolevel=0.3)
InteractFile.objects.filter(label="hbond donor-acceptor").update(
default_isolevel=0.3
)
InteractFile.objects.filter(label="negative").update(default_isolevel=0.08)
InteractFile.objects.filter(label="positive").update(default_isolevel=0.05)
InteractFile.objects.filter(label="backbone").update(default_isolevel=0.18)
class Migration(migrations.Migration):
dependencies = [
("ippidb", "0067_metainformation_normalize_factor"),
]
operations = [
migrations.AddField(
model_name="chain",
name="default_isolevel",
field=models.FloatField(default=0.7, verbose_name="Default isolevel value"),
),
migrations.AddField(
model_name="interactfile",
name="default_isolevel",
field=models.FloatField(default=0.7, verbose_name="Default isolevel value"),
),
migrations.RunPython(init_isolevel, reverse_code=migrations.RunPython.noop),
]
...@@ -132,9 +132,13 @@ class Chain(models.Model): ...@@ -132,9 +132,13 @@ class Chain(models.Model):
verbose_name="pdb file content with only one chain", default="no pdb file" verbose_name="pdb file content with only one chain", default="no pdb file"
) )
mrc_file = models.FileField(upload_to=content, blank=True) mrc_file = models.FileField(upload_to=content, blank=True)
default_isolevel = models.FloatField(
default=0.7, verbose_name="Default isolevel value"
)
class Meta: class Meta:
unique_together = ("pdb", "pdb_chain_id") unique_together = ("pdb", "pdb_chain_id")
ordering = ["pdb", "pdb_chain_id"]
def is_partner(self): def is_partner(self):
return self.partner_set.count() return self.partner_set.count()
...@@ -156,6 +160,9 @@ class InteractFile(models.Model): ...@@ -156,6 +160,9 @@ class InteractFile(models.Model):
chain = models.ForeignKey(Chain, on_delete=models.CASCADE) chain = models.ForeignKey(Chain, on_delete=models.CASCADE)
label = models.CharField(max_length=250, blank=False, null=False) label = models.CharField(max_length=250, blank=False, null=False)
interact_file = models.FileField(upload_to=contentinteract, blank=True) interact_file = models.FileField(upload_to=contentinteract, blank=True)
default_isolevel = models.FloatField(
default=0.7, verbose_name="Default isolevel value"
)
def __unicode__(self): def __unicode__(self):
return "{}".format(self.interact_file) return "{}".format(self.interact_file)
...@@ -356,6 +363,7 @@ class Cavity(models.Model): ...@@ -356,6 +363,7 @@ class Cavity(models.Model):
class Meta: class Meta:
unique_together = ("full_name", "chain", "cavity_number", "partner") unique_together = ("full_name", "chain", "cavity_number", "partner")
verbose_name_plural = "Cavities" verbose_name_plural = "Cavities"
ordering = ["chain", "cavity_number"]
@property @property
def near_cavities(self): def near_cavities(self):
...@@ -415,22 +423,35 @@ class MetaInformation(models.Model): ...@@ -415,22 +423,35 @@ class MetaInformation(models.Model):
""" """
average = models.DecimalField( average = models.DecimalField(
verbose_name="Average", max_digits=11, decimal_places=8 verbose_name="Average",
max_digits=11,
decimal_places=8,
help_text="partial matrix mean value",
) )
std = models.DecimalField( std = models.DecimalField(
verbose_name="Standard Deviation", max_digits=11, decimal_places=8 verbose_name="Standard Deviation",
max_digits=11,
decimal_places=8,
help_text="partial matrix standard deviation",
) )
maximum = models.DecimalField( maximum = models.DecimalField(
verbose_name="Maximum", max_digits=11, decimal_places=8 verbose_name="Maximum",
max_digits=11,
decimal_places=8,
help_text="partial matrix maximum value",
) )
minimum = models.DecimalField( minimum = models.DecimalField(
verbose_name="Minimum", max_digits=11, decimal_places=8 verbose_name="Minimum",
max_digits=11,
decimal_places=8,
help_text="partial matrix minimum value",
) )
normalize_factor = models.DecimalField( normalize_factor = models.DecimalField(
blank=True, blank=True,
null=True, null=True,
default=4.58599730, default=4.58599730,
verbose_name="Normalize Factor", verbose_name="Normalize Factor",
help_text="complet matrix standard deviation",
max_digits=11, max_digits=11,
decimal_places=8, decimal_places=8,
) )
......
...@@ -57,7 +57,7 @@ class ChainDistanceSerializer(serializers.ModelSerializer): ...@@ -57,7 +57,7 @@ class ChainDistanceSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Chain model = Chain
fields = ("id", "pdb_chain_id", "protein", "pdb") fields = ("id", "pdb_chain_id", "protein", "pdb", "default_isolevel")
class PartnerDistanceSerializer(serializers.ModelSerializer): class PartnerDistanceSerializer(serializers.ModelSerializer):
...@@ -121,6 +121,7 @@ class ChainSerializer(serializers.ModelSerializer): ...@@ -121,6 +121,7 @@ class ChainSerializer(serializers.ModelSerializer):
"cavity_set", "cavity_set",
"partner_set", "partner_set",
"mrc_file", "mrc_file",
"default_isolevel",
"interactfile_set", "interactfile_set",
) )
......
...@@ -356,10 +356,47 @@ div.hidden { ...@@ -356,10 +356,47 @@ div.hidden {
/* -- Home page choices -- */ /* -- Home page choices -- */
.background_choices { .compound_choices {
margin: 40px;
position: relative; position: relative;
background: #e3e9eb url(/static/images/Other/cross.png) 50px 100px no-repeat; background: #E3E9EB url(/static/images/Other/cross.png) 50px 100px no-repeat;
text-align: center;
height: fit-content;
box-shadow: 0 3px 11px 0 rgb(0 0 0 / 20%);
}
.compound_background {
position: relative;
background: #E3E9EB url(/static/images/Other/cross.png) 50px 100px no-repeat;
text-align: center;
height: fit-content;
}
.compound_choices:hover{
background: #D1DBDE url(/static/images/Other/cross.png) 50px 100px no-repeat;
}
.pocket_choices {
position: relative;
background: #AABDC3 url(/static/images/Other/cross.png) 50px 100px no-repeat;
text-align: center;
height: fit-content;
box-shadow: 0 3px 11px 0 rgb(0 0 0 / 20%);
}
.pocket_choices:hover {
background: #97ADB5 url(/static/images/Other/cross.png) 50px 100px no-repeat;
}
.pocket_background {
position: relative;
background: #AABDC3 url(/static/images/Other/cross.png) 50px 100px no-repeat;
text-align: center;
height: fit-content;
}
.icons {
padding: 10%;
font-size: 1.5em;
} }
.choices_background { .choices_background {
...@@ -448,6 +485,15 @@ div.hidden { ...@@ -448,6 +485,15 @@ div.hidden {
display:block; display:block;
} }
.front-vertical-align {
padding-top: 80px;
}
.back-vertical-align {
padding-top: 25px;
}
/* -- Breadcrumb -- */ /* -- Breadcrumb -- */
.breadNav { .breadNav {
...@@ -1220,4 +1266,48 @@ div.hidden { ...@@ -1220,4 +1266,48 @@ div.hidden {
.btn.float-right+.btn.float-right { .btn.float-right+.btn.float-right {
margin-right: 5px margin-right: 5px
} }
\ No newline at end of file
/* Modal */
.modal-xl {
width: 100%;
max-width:1200px;
height: fit-content;
max-height: 1200px;
}
.close_choices_modal {
margin: 0px !important;
right: 32px !important;
top: 32px !important;
width: 32px !important;
height: 32px !important;
opacity: 0.5;
border: none !important;
color: #495057 !important;
cursor: pointer;
float: right;
text-align: right;
font-size: 2em;
background-color: white !important;
}
.close_choices_modal:hover {
opacity: 1;
}
.align_modal {
display: inline-block;
}
.modal_choices_title {
float: left;
text-align: right;
font-family: "PlayfairDisplayReg";
font-size: 2em;
}
.fade_index {
transition: opacity 1s linear;
}
\ No newline at end of file
...@@ -134,7 +134,18 @@ Description: IPPI-DB targetcentric Theme ...@@ -134,7 +134,18 @@ Description: IPPI-DB targetcentric Theme
.dropbtn { .dropbtn {
font-size: 14px; font-size: 14px;
color: #007bff color: #2D96FA;
border-radius: 5px;
border-color: #97ADB5;
background-color: #eff3f5;
padding-right: 3px;
padding-left: 3px;
padding-bottom: 1px;
padding-top: 1px;
border-style: solid;
border-width: 2px;
min-width: 25px;
text-align: center;
} }
.dropdown { .dropdown {
...@@ -145,12 +156,16 @@ Description: IPPI-DB targetcentric Theme ...@@ -145,12 +156,16 @@ Description: IPPI-DB targetcentric Theme
.dropdown-content { .dropdown-content {
display: none; display: none;
position: absolute; position: absolute;
bottom: 24px; bottom: 22px;
left: 14px; left: 12px;
background-color: #f1f1f1; background-color: #eff3f5;
min-width: 100px; min-width: 100px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.4);
z-index: 3; z-index: 3;
border-radius: 5px;
border-color: #97adb5 !important;
border: 2px;
border-style: solid;
} }
.dropdown-content a { .dropdown-content a {
...@@ -161,25 +176,28 @@ Description: IPPI-DB targetcentric Theme ...@@ -161,25 +176,28 @@ Description: IPPI-DB targetcentric Theme