Skip to content

Commit

Permalink
Merge pull request #95 from amir-zeldes/develop
Browse files Browse the repository at this point in the history
V4.0.0
  • Loading branch information
amir-zeldes authored Jul 15, 2024
2 parents 81fe10c + e0dce4b commit 5341149
Show file tree
Hide file tree
Showing 28 changed files with 898 additions and 185 deletions.
2 changes: 1 addition & 1 deletion _version.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

__version__ = "3.0.3"
__version__ = "4.0.0"
__author__ = "Amir Zeldes, Luke Gessler"
__copyright__ = "Copyright 2015-2021, Amir Zeldes"
__license__ = "MIT License"
26 changes: 26 additions & 0 deletions admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ def is_email(email):
<input type="hidden" name="switch_logging" id="switch_logging" value=""/>
<input type="hidden" name="switch_span_buttons" id="switch_span_buttons" value=""/>
<input type="hidden" name="switch_multinuc_buttons" id="switch_multinuc_buttons" value=""/>
<input type="hidden" name="switch_secedges" id="switch_secedges" value=""/>
<input type="hidden" name="update_schema" id="update_schema" value=""/>
<input type="hidden" name="imp_project" id="imp_project" value=""/>
<input type="hidden" name="import_file_type" id="import_file_type" value=""/>
Expand Down Expand Up @@ -719,6 +720,31 @@ def is_email(email):
cpout += '''<button onclick="admin('switch_span_buttons')">'''+ opposite_span +''' span buttons</button><br/><br/>'''
cpout += '''<button onclick="admin('switch_multinuc_buttons')">'''+ opposite_multinuc +''' multinuc buttons</button>'''

# spans/multinucs
cpout += '''<h2>Allow secondary edges</h2>
<p>Allow adding tree-breaking secondary edges using ctrl+drag.</p>'''

try:
secedge_state = get_setting("use_secedges")
except IndexError:
secedge_state="False"

if "switch_secedges" in theform:
if int(get_schema()) < 7:
update_schema()
if theform["switch_secedges"] == "switch_secedges":
if secedge_state == "True":
secedge_state = "False"
else:
secedge_state = "True"
save_setting("use_secedges",secedge_state)
if secedge_state == "True":
opposite_secedge = "Disable"
else:
opposite_secedge = "Enable"
cpout += '''<button onclick="admin('switch_secedges')">'''+ opposite_secedge +''' secondary edges</button><br/>'''


cpout += '''<h2>Update schema</h2>
<p>Update the schema without losing data between major schema upgrades.</p>'''

Expand Down
68 changes: 60 additions & 8 deletions css/rst.css
Original file line number Diff line number Diff line change
Expand Up @@ -184,19 +184,44 @@ div.shield-of-justice {
}

.edu--clickable .tok:not(.tok--selected):hover {
background: rgba(255,255,0,0.3);
background-color: rgba(255,255,0,0.6);
}

.tok--highlighted {
background: rgba(255,255,0,0.3);
background-color: rgba(255,255,0,0.8) !important;
}
.tok--highlighted.signal-color {
background-color: rgba(var(--rgb), 0.8) !important;
}

.tok--highlighted-by-button {
background: rgba(255,255,0,0.2);
}
--rgb: 255,255,0;
background-color: rgba(var(--rgb),0.2);
}

.tok--highlighted-by-button.signal-type-1{--rgb: 255,0,0;background-color: rgba(var(--rgb),0.2);} /*red*/
.tok--highlighted-by-button.signal-type-2{--rgb: 247,231,51;background-color: rgba(var(--rgb),0.2);} /*yellow*/
.tok--highlighted-by-button.signal-type-3{--rgb: 251,183,52;background-color: rgba(var(--rgb),0.2);} /*orange*/
.tok--highlighted-by-button.signal-type-4{--rgb: 128,128,0;background-color: rgba(var(--rgb),0.2);} /*ochre*/
.tok--highlighted-by-button.signal-type-5{--rgb: 255,0,255;background-color: rgba(var(--rgb),0.2);} /*pink*/
.tok--highlighted-by-button.signal-type-6{--rgb: 0,0,255;background-color: rgba(var(--rgb),0.2);} /*blue*/
.tok--highlighted-by-button.signal-type-7{--rgb: 4,93,161;background-color: rgba(var(--rgb),0.2);} /*glas*/
.tok--highlighted-by-button.signal-type-8{--rgb: 0,255,0;background-color: rgba(var(--rgb),0.2);} /*green*/
.tok--highlighted-by-button.signal-type-9{--rgb: 0,255,255;background-color: rgba(var(--rgb),0.2);} /*cyan*/
.tok--highlighted-by-button.signal-type-10{--rgb: 105,3,117;background-color: rgba(var(--rgb),0.2);}/*violet*/
.tok--highlighted-by-button.signal-type-11{--rgb: 15,8,75;background-color: rgba(var(--rgb),0.2);} /* gray*/
.tok--highlighted-by-button.signal-type-12{--rgb: 199,214,109;background-color: rgba(var(--rgb),0.2);}
.tok--highlighted-by-button.signal-type-13{--rgb: 131,10,72;background-color: rgba(var(--rgb),0.2);}
.tok--highlighted-by-button.signal-type-14{--rgb: 174,132,126;background-color: rgba(var(--rgb),0.2);}
.tok--highlighted-by-button.signal-type-15{--rgb: 0,255,0;background-color: rgba(var(--rgb),0.2);}
.tok--highlighted-by-button.signal-type-16{--rgb: 255,255,0;background-color: rgba(var(--rgb),0.2);}
.tok--highlighted-by-button.signal-type-17{--rgb: 0,255,255;background-color: rgba(var(--rgb),0.2);}
.tok--highlighted-by-button.signal-type-18{--rgb: 255,0,255;background-color: rgba(var(--rgb),0.2);}
.tok--highlighted-by-button.signal-type-19{--rgb: 255,0,255;background-color: rgba(var(--rgb),0.2);}
.tok--highlighted-by-button.signal-type-20{--rgb: 255,0,255;background-color: rgba(var(--rgb),0.2);}

.edu--clickable .tok--selected {
background: rgba(255,255,0,0.7);
background-color: rgba(255,255,0,0.7);
}


Expand Down Expand Up @@ -341,7 +366,7 @@ select.rst_rel {
.seg_end:before{content:"\a0\a0"}
.seg_end:hover:before{content:"x"}

.tab{position: absolute;left: 0px; top:86px; background-color:white;height: 700px; width: 500px;padding-left:5px}
.tab{position: absolute;left: 0px; top:86px; background-color:white;height: 800px; width: 500px;padding-left:5px}
.tab_btn{width:82px;top:85px;position:absolute;z-index:2;border-width:1px;border-color: black black black black; border-style: solid; text-align:center; border-top-left-radius: 6px; border-top-right-radius: 6px; cursor: pointer; background-color: buttonface; border-bottom-color: black}
.tab_btn:after{content: "\a0"; width:8px; border-bottom-style: solid; border-bottom-width:1px;border-bottom-color: black; left: 82px;position:absolute;top:0px}
button:hover:enabled, .nav_button:hover:enabled{ color: red; background: #f5f5f5; }
Expand Down Expand Up @@ -542,6 +567,33 @@ input:checked + .slider:before {
height: 80%;
}

.ui-dialog { z-index: 1000 !important ;}
.ui-dialog { z-index: 10000 !important ;}

#quick_container{padding-top:5px}

.custom-menu {
display: none;
z-index: 10000;
position: absolute;
overflow: hidden;
border: 1px solid #CCC;
white-space: nowrap;
font-family: sans-serif;
background: #FFF;
color: #333;
border-radius: 5px;
padding: 0;
}

/* Each of the items in the list */
.custom-menu li {
padding: 8px 12px;
cursor: pointer;
list-style-type: none;
transition: all .3s ease;
user-select: none;
}

#quick_container{padding-top:5px}
.custom-menu li:hover {
background-color: #DEF;
}
9 changes: 7 additions & 2 deletions get_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,21 @@ def get_structure_main(**kwargs):
current_project = "quick"

rels = {}
nodes, signals = read_rst(rs3,rels,as_string=True)
nodes, signals, signal_type_dict = read_rst(rs3,rels,as_string=True)
secedges = []
for nid in nodes:
node = nodes[nid]
node.relkind = "rst"
if node.relname.endswith("_m"):
node.relkind = "multinuc"
elif node.relname == "span":
node.relkind = "span"
if node.secedges != "":
secedges += node.secedges.split(";")
secedge_data = ";".join(secedges)
rels = sorted([(k,v) for k,v in iteritems(rels)])
output = build_canvas(current_doc, current_project, rels, nodes, signal_data=signals, show_signals=False, validations="validate_empty;validate_flat;validate_mononuc")
output = build_canvas(current_doc, current_project, rels, nodes, secedge_data=secedge_data, signal_data=signals,
validations="validate_empty;validate_flat;validate_mononuc", signal_type_dict=signal_type_dict)
return output

def get_structure_main_server():
Expand Down
77 changes: 74 additions & 3 deletions modules/formats/db2rst.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,54 @@
import re
import re, sys


def db2rst(rels, nodes, signals):
def db2rst(rels, nodes, secedges, signals, signal_types, doc, project, user):
def sequential_ids(rst_xml):
# Ensure no gaps in node IDs and corresponding adjustments to signals and secedges.
# Assume input xml IDs are already sorted, but with possible gaps
output = []
temp = []
current_id = 1
id_map = {}
for line in rst_xml.split("\n"):
if ' id="' in line:
xml_id = re.search(r' id="([^"]+)"', line).group(1)
if ('<segment ' in line or '<group ' in line):
id_map[xml_id] = str(current_id)
line = line.replace(' id="'+xml_id+'"',' id="'+str(current_id)+'"')
current_id += 1
temp.append(line)

for line in temp:
if ' id="' in line:
if ' parent=' in line and ('<segment ' in line or '<group ' in line):
parent_id = re.search(r' parent="([^"]+)"', line).group(1)
new_parent = id_map[parent_id]
line = line.replace(' parent="'+parent_id+'"',' parent="'+str(new_parent)+'"')
elif "<secedge " in line:
xml_id = re.search(r' id="([^"]+)"', line).group(1)
src, trg = xml_id.split("-")
line = line.replace(' source="'+src+'"', ' source="'+id_map[src]+'"')
line = line.replace(' target="' + trg + '"', ' target="' + id_map[trg] + '"')
line = line.replace(' id="' + xml_id + '"', ' id="' + id_map[src] + '-' + id_map[trg] + '"')
elif "<signal " in line:
source = re.search(r' source="([^"]+)"', line).group(1)
if "-" in source:
src, trg = source.split("-")
line = line.replace(' source="' + source + '"', ' source="' + id_map[src] + '-' + id_map[trg] + '"')
else:
if source in id_map:
line = line.replace(' source="' + source + '"', ' source="' + id_map[source] + '"')
else: # Zombie signal pointing to no longer existing node
from ..rstweb_sql import generic_query
# Repair the database
generic_query("DELETE from rst_signals WHERE source like ? and doc=? and project=? and user=?",
(source, doc, project, user))
sys.stderr.write("Removed signal with non-existant source " + source + ":\n"+line+"\n")
continue
output.append(line)

return "\n".join(output)

rst_out = [
"<rst>",
"\t<header>",
Expand All @@ -13,6 +60,15 @@ def db2rst(rels, nodes, signals):
rst_out.append('\t\t\t<rel name="' + relname_string + '" type="' + rel[1] + '"/>')

rst_out.append("\t\t</relations>")

if len(signal_types) > 0:
rst_out.append("\t\t<sigtypes>")
for major_type in signal_types:
minor_types = signal_types[major_type]
minor_types = ";".join(sorted(minor_types))
rst_out.append('\t\t\t<sig type="'+major_type+'" subtypes="'+minor_types+'"/>')
rst_out.append("\t\t</sigtypes>")

rst_out.append("\t</header>")
rst_out.append("\t<body>")

Expand Down Expand Up @@ -53,6 +109,18 @@ def db2rst(rels, nodes, signals):
rst_out.append('\t\t<group id="' + node[0] + '" type="' + node[
5] + '" ' + parent_string + relname_string + '/>')

if len(secedges) > 0:
rst_out.append("\t\t<secedges>")
for s in secedges.split(";"):
if ":" not in s:
continue
src_trg, relname = s.split(":",1)
src, trg = src_trg.split("-")
if relname.endswith("_r") or relname.endswith("_m"):
relname = relname[:-2]
rst_out.append('\t\t\t<secedge id="'+src+"-"+trg+'" source="' + src + '" target="' + trg + '" relname="' + relname + '"/>')
rst_out.append("\t\t</secedges>")

if len(signals) > 0:
rst_out.append("\t\t<signals>")
for signal in signals:
Expand All @@ -61,4 +129,7 @@ def db2rst(rels, nodes, signals):
rst_out.append("\t\t</signals>")
rst_out.append("\t</body>")
rst_out.append("</rst>")
return '\n'.join(rst_out) + '\n'
rst_out = '\n'.join(rst_out) + '\n'
rst_out = sequential_ids(rst_out)

return rst_out
7 changes: 4 additions & 3 deletions modules/logintools/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
# login is the function most frequently imported
# and called directly by external scripts

def login(theform, userdir, thisscript=None, action=None):
def login(theform, userdir, thisscript=None, action=None, print_cookie=True):
"""From the form decide which function to call."""
# FIXME: this function got a bit more complicated than intended
# it also handles checking logins when editaccount or admin
Expand Down Expand Up @@ -185,8 +185,9 @@ def login(theform, userdir, thisscript=None, action=None):

else:
displaylogin(userdir, thisscript, action) # we haven't understood - just display the login screen XXXX error message instead ?

print(newcookie) # XXXX ought to be a way of returning the cookie object instead...

if print_cookie:
print(newcookie) # XXXX ought to be a way of returning the cookie object instead...
if action == 'EMPTY_VAL_MJF': # the programmer ought never to 'see' this value, although it might get passed to his script by the login code a few times....
action = None
userconfig['lastused'] = str(time())
Expand Down
3 changes: 2 additions & 1 deletion modules/rstweb_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"""

class NODE:
def __init__(self, id, left, right, parent, depth, kind, text, relname, relkind):
def __init__(self, id, left, right, parent, depth, kind, text, relname, relkind, secedges):

"""Basic class to hold all nodes (EDU, span and multinuc) in structure.py and while importing"""

Expand All @@ -21,6 +21,7 @@ def __init__(self, id, left, right, parent, depth, kind, text, relname, relkind)
self.relname = relname
self.relkind = relkind #rst (a.k.a. satellite), multinuc or span relation
self.sortdepth = depth
self.secedges = secedges


class SEGMENT:
Expand Down
Loading

0 comments on commit 5341149

Please sign in to comment.