From b18d58bc6cfb41dad18647f517fe38b6da443a52 Mon Sep 17 00:00:00 2001
From: Sebastian David <sebastian.david@uni-hamburg.de>
Date: Thu, 13 Jan 2022 13:52:59 +0100
Subject: [PATCH] full functionality, changed some variable names

---
 .citation_parser_ui.py.swp                    | Bin 20480 -> 0 bytes
 assets/json_text.json                         |   2 +-
 citation_parser_ui.py                         |  67 ++++++++++--------
 input/get/__pycache__/__init__.cpython-38.pyc | Bin 157 -> 153 bytes
 input/get/__pycache__/acs.cpython-38.pyc      | Bin 4197 -> 4193 bytes
 .../journal_fetcher.cpython-38.pyc            | Bin 3797 -> 3793 bytes
 input/get/__pycache__/nature.cpython-38.pyc   | Bin 1636 -> 1632 bytes
 7 files changed, 39 insertions(+), 30 deletions(-)
 delete mode 100644 .citation_parser_ui.py.swp

diff --git a/.citation_parser_ui.py.swp b/.citation_parser_ui.py.swp
deleted file mode 100644
index 38c0d61d4724d853b03e358ed4916b537560e72f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 20480
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
VnTM(ayB(2a&<E6UszMr22LK?O0b~FG

diff --git a/assets/json_text.json b/assets/json_text.json
index b2e4c5f..b8177a3 100644
--- a/assets/json_text.json
+++ b/assets/json_text.json
@@ -1 +1 @@
-{"nodes": [{"doi": "https://doi.org/10.1021/acs.jcim.6b00709", "name": "Matched Molecular Series: Measuring SAR Similarity", "author": ["Emanuel S. R. Ehmki", "Christian Kramer"], "year": "May 1, 2017", "journal": "Journal of Chemical Information and Modeling", "group": "Input", "depth": 0, "citations": 5}, {"doi": "https://doi.org/10.1021/acs.jcim.0c00269", "name": "Matched Molecular Series Analysis for ADME Property Prediction", "author": ["Mahendra Awale", "Sereina Riniker", "Christian Kramer"], "year": "May 5, 2020", "journal": "Journal of Chemical Information and Modeling", "group": "Citedby", "depth": 1, "citations": 6}, {"doi": "https://doi.org/10.1021/acs.jcim.0c00290", "name": "Identification of Bioisosteric Substituents by a Deep Neural Network", "author": ["Peter Ertl"], "year": "June 15, 2020", "journal": "Journal of Chemical Information and Modeling", "group": "Citedby", "depth": 2, "citations": 2}], "links": [{"source": "https://doi.org/10.1021/acs.jcim.0c00269", "target": "https://doi.org/10.1021/acs.jcim.6b00709"}, {"source": "https://doi.org/10.1021/acs.jcim.0c00290", "target": "https://doi.org/10.1021/acs.jcim.0c00269"}]}
\ No newline at end of file
+{"nodes": [], "links": []}
\ No newline at end of file
diff --git a/citation_parser_ui.py b/citation_parser_ui.py
index 2dbd0be..c2b119d 100644
--- a/citation_parser_ui.py
+++ b/citation_parser_ui.py
@@ -42,31 +42,31 @@ app.layout = html.Div([
             is_open=False,
         ),
 
-    # Layer 1: For all mandatory Inputs
+    # Layer 1: For the string input
     html.Div([
         "Input: ",
         # A simple box for inputting a string. 
         # Value is transmitted upon pressing return or clicking out of the box.
-        dcc.Input(id='input-string', value='', type='text',debounce=True,
+        dcc.Input(id='string-input', value='', type='text',debounce=True,
         style={ "width": "400px"},
         ),
         
     ]),
-        # Layer 1,5: For test
+        # Layer 2: For file input and recursion depths
     html.Div([
-        "Forward recursion: ",
+        "Cited-by Depth: ",
         # Forward recursion. Values between 1 and 10 can be entered.
-        dcc.Input(id='forward-depth',value='1',type='number',min='1',max='10',
+        dcc.Input(id='forward-depth',value='1',type='number',min='0',max='5',
         style={ "width": "50px"},
         ),
-        "Backward recursion: ",
+        "References Depth: ",
         # Backward recursion. Values between 1 and 10 can be entered.
-        dcc.Input(id='backward-depth',value='1',type='number',min='1',max='10',
+        dcc.Input(id='backward-depth',value='1',type='number',min='0',max='5',
         style={"width": "50px"},
         ),
         # Upload box. Can be used via drag-and-drop or byclicking on it to open a file viewer.
         dcc.Upload(
-            id="upload-data",
+            id="file-input",
             children=html.Div(
             #Drag and drop or click to select a file to upload
                 ["Drag and drop"]),
@@ -82,7 +82,7 @@ app.layout = html.Div([
             })
     ]),
    
-    # Layer 2: For the checklist, Remove-/Start-Buttons and input-error-message
+    # Layer 3: For the checklist, Remove-/Start-Buttons and error message
     html.Div([
         # All input DOIs are collected in this checklist. 
         # It is initialized to avoid error messages.
@@ -97,7 +97,7 @@ app.layout = html.Div([
         # Starts the process that generates a graph.
         dbc.Button(id='start-button',children='Generate Graph', color="primary", className="me-1")
     ]),
-    # Layer 3: For additional Options (e.g. Topological Sort)
+    # Layer 4: For additional Options
     html.Div([
         html.H4('Additional Options'),
         # A checklist of all additional options that are listed above.
@@ -105,25 +105,25 @@ app.layout = html.Div([
             options=[{'label':k,'value':k} for k in additional_options],
             value=[])
         ]),
-    # Layer 4: For the Graph
-    html.Div(
-        [html.Iframe(
+    # Layer 5: For the Graph and corresponding error messages
+    html.Div([
+        html.Div(id='generate-graph-error',style={'color':'red'}),
+        html.Iframe(
             src="assets/index.html",
             style={"height": "600px", "width": "100%"},
         ),
-        html.Div(id='test-output')
     ])
 ])
 
 @app.callback(
     Output('input-checklist','options'),
     Output('input-checklist','value'),
-    Output('input-string','value'),
+    Output('string-input','value'),
     Output('input-err','children'),
-    Input('input-string','value'),
+    Input('string-input','value'),
     Input('clear-all-button','n_clicks'),
     Input('clear-selected-button','n_clicks'),
-    Input('upload-data','contents'),
+    Input('file-input','contents'),
     State('input-checklist','options'),
     State('input-checklist','value'),
     State('additional-options','value')
@@ -133,7 +133,7 @@ def update_input_checklist(input_value,btn1,btn2,filecontents,all_inputs,
     '''
     Most important callback function. Updates the checklist that holds all inputs.
     State of the checklist as input is needed so that previews entries are readded.
-    input-string is required as Output to clear the input box after each input.
+    string-input is required as Output to clear the input box after each input.
     Different actions are performed depending on which input triggered the callback.
     The value-attribute of input-checklist must be updates so that the values
     of deleted elements no longer appear in the list of selected elements.
@@ -168,7 +168,7 @@ def update_input_checklist(input_value,btn1,btn2,filecontents,all_inputs,
         return all_inputs,list(),'',''
     
     # when a new element is added via dcc.Input
-    if 'input-string' in changed_id:
+    if 'string-input' in changed_id:
         # Creates a list of previously added inputs to make sure nothing is added twice
         currValues = [x['value'] for x in all_inputs]        
         if input_value not in currValues:
@@ -186,7 +186,10 @@ def update_input_checklist(input_value,btn1,btn2,filecontents,all_inputs,
                 # Creates a more readable string to display in the checklist
                 rep_str = pub.contributors[0] + ',' + pub.journal + \
                         ',' + pub.publication_date
-                all_inputs.append({'label':rep_str, 'value':input_value})
+                # Makes sure not to add the same article with different links
+                currLabels = [x['label'] for x in all_inputs]
+                if rep_str not in currLabels:
+                    all_inputs.append({'label':rep_str, 'value':input_value})
             
             # if 'Smart Input' is not selected, the input value is added as is,
             # without checking for validity.
@@ -195,7 +198,7 @@ def update_input_checklist(input_value,btn1,btn2,filecontents,all_inputs,
         return all_inputs,selected_inputs,'',''
     
     # when a txt-file is uploaded
-    if 'upload-data.contents' in changed_id:
+    if 'file-input.contents' in changed_id:
         if filecontents:
             # Skips the info portion that is added when a file is uploaded
             found = base64.b64decode(re.search(',(.+?)$', filecontents).group(1))
@@ -215,7 +218,9 @@ def update_input_checklist(input_value,btn1,btn2,filecontents,all_inputs,
                             return all_inputs,selected_inputs,'','{}'.format(err)
                         rep_str = pub.contributors[0] + ',' + pub.journal + \
                                 ',' + pub.publication_date
-                        all_inputs.append({'label':rep_str, 'value':input_value})
+                        currLabels = [x['label'] for x in all_inputs]
+                        if rep_str not in currLabels:
+                            all_inputs.append({'label':rep_str, 'value':input_value})
                     else:
                         all_inputs.append({'label':input_value,'value':input_value})
         return all_inputs,selected_inputs,'',''
@@ -244,16 +249,14 @@ def toggle_collapse(n, is_open):
 
 
 @app.callback(
-    Output('test-output','children'),
+    Output('generate-graph-error','children'),
     Input('start-button','n_clicks'),
     Input('input-checklist','options'),
-    Input('input-checklist','value'),
     Input('forward-depth','value'),
     Input('backward-depth','value'),
     State('additional-options','value')
 )
-def generate_output(n_clicks,all_inputs,selected_inputs,
-        forward_depth,backward_depth,additional_options):
+def generate_output(n_clicks,all_inputs,forward_depth,backward_depth,additional_options):
     '''
     Basic structure for a callback that generates an output. This is only a 
     proof of concept and has noting to do with the intended output yet.
@@ -263,8 +266,6 @@ def generate_output(n_clicks,all_inputs,selected_inputs,
     :param all_inputs: all labels and values from the checklist,
         regardless if they have been checked or not
     :type all_inputs: list of dictionaries with 2 entries each
-    :param selected_inputs: values of all checked elements
-    :type selected_inputs: list of strings
     :param forward_depth: forward recursion depth
     :type forward_depth: unsigned int
     :param backward_depth: backward recursion depth
@@ -278,7 +279,15 @@ def generate_output(n_clicks,all_inputs,selected_inputs,
     elif 'Update Automatically' in additional_options \
             or 'start-button' in changed_id: 
         input_links = [x['value'] for x in all_inputs]
-        Processing(input_links,int(forward_depth),int(backward_depth),'assets/json_text.json')
+        errors = Processing(input_links,int(forward_depth),int(backward_depth),'assets/json_text.json')
+        if errors:
+            message = ['The following inputs are invalid and were not used:']
+            for error in errors:
+                message.append(html.Br())
+                message.append(error)
+            message = html.P(message)
+            #message = [html.P(error) for error in errors]
+            return message
 
 if __name__ == '__main__':
     app.run_server(debug=False)
diff --git a/input/get/__pycache__/__init__.cpython-38.pyc b/input/get/__pycache__/__init__.cpython-38.pyc
index f12fb9c33e874aa1c55d94725f867ac6503d407e..52f5d64aa3f72e25accf523fb850635617afbf5e 100644
GIT binary patch
delta 75
zcmbQsIFpe(l$V!_fq{YHZpYn;+%_h5`WgATsrtpKNr}ZJnTdJ&1x5K;so5o|`pKEP
Z#kx?QZfT}|W?n&QiGF%&iT=cTIRJuK8JYk9

delta 79
zcmbQqIG2$-l$V!_fq{V`dF8>0+%^_Y$yPC;#i>QbG46@EnRzkknI$pFnYzWg1x5K;
iso5pEWvNApMM<fdC8c@kF`0P<r6n=xsU<NJtK|USp&P6K

diff --git a/input/get/__pycache__/acs.cpython-38.pyc b/input/get/__pycache__/acs.cpython-38.pyc
index 121d1856184f02775d5bb84d081dcd91a648ea67..78c1fb0c8b885e90285224e745b09af56faf9b01 100644
GIT binary patch
delta 81
zcmaE=@KAv-l$V!_fq{YHZpYokb+Q}z44F+V^)vEwQ}v5elM;(dG86Ok3ySiyQnO1^
f^^-Goi*=zq-O^0`%)Elq68-el68+8P%<p&rT2vgS

delta 85
zcmaE;@Kk{>l$V!_fq{V`dF8>xJh_d0hRhbW$yPC;#i>QbG46@EnRzkknI$pFnYzWg
p1x5K;so5pEWvNApMM<fdC8c@kF`0P<r6n=xsU<O+i<#f?006Ok9(e!&

diff --git a/input/get/__pycache__/journal_fetcher.cpython-38.pyc b/input/get/__pycache__/journal_fetcher.cpython-38.pyc
index 72a774c45762b3d4cb37a7089f4d8275dab0e533..af9bd12b47a0bae4c1683adf78d92884b7e51193 100644
GIT binary patch
delta 266
zcmcaAdr_7*l$V!_fq{YHZpYn3?~S}^%#61tmoRI)-C{0EExg5?T2!=>p-7N{f#H{{
zenx(7s(x{5QetsQW@4UxK~a8IYIaGgesZR6u`ZOSTbik#nO9I+qMx2xqQChib0{M>
zNITe!BB9NmtYVC!A`A=+MdBa=S*nC>It!!JW*+XDOg6$GNoEEHhFdI2`T03T5+FV+
zh>!#cawjGw6{VKNr(`CVKukt5X!1ke77;m+GUmjj<RT`JF0fIPEBSN;5DLL8p~+kM
F6aZ@3Lj(W-

delta 270
zcmca8dsUV<l$V!_fq{V`dF8>xRU3KJm>HucmoRI4MKKqp7T#h`Eh<{cP{hx`!0^j6
z*(xTqIJKxa#yv4NGcP7Rvm_=tQ@2>RpeR2pHM>N&EVU@HC@D3wq%<!*CNr;~v?L}y
zwIpWqQ|3@cZjcdRbBY8uyRwQgiV86>FcgV`2xO@Ow&^U45}P@=XENCcf+U$47#MD`
zB<1Jl6p4ZOtRO-hB*>kZlvI>j7N3%tTmmr}$)L%1d0RweK+2dClah;=K)OIiMNKZ{
Q(-A-@1hWJtZ{$+|0Db90u>b%7

diff --git a/input/get/__pycache__/nature.cpython-38.pyc b/input/get/__pycache__/nature.cpython-38.pyc
index 3afb8454a05c8afe9b1f2aba3f534d66cbd8ae3a..ca8c9862b7234c55e49b676136ab64a62f91e58b 100644
GIT binary patch
delta 80
zcmaFD^MHppl$V!_fq{YHZpYn3zm2>mOeQw^8Tq-X`o*b9iNz(EiFx`3Mfq8&*(Is^
e$(g#vx=@~OX{LT=UO{PzetK$&{^m-i*USJZbsP5p

delta 84
zcmaFB^Mr>tl$V!_fq{V`dF8>x&W*e#OcoBwRxzQ)sYS&x?uogXc`@mkB{9jFy2ZK$
oMfq8&*(JJVsYQuJNvWA7rFrQwnRx}JB{Au#B{7>znO-vk0G_ZOL;wH)

-- 
GitLab