Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Beasley committed Jun 26, 2023
0 parents commit 156fe4d
Show file tree
Hide file tree
Showing 154 changed files with 87,081 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.idea/
test.sh
test176.sh
/plugins/*jar
/plugins/
/xlsx/*xlsx
/redcap_dict/*.csv
/builder/__pycache__


32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Please read the wiki for instructions.

## Updates
**26 June 2023**:
* Subforms added
* Gradlew bug fixed - restarts gradle to clear cache, as can break if schema changed.
* Date box and ynuo bugs fixed
* Session/subject assessor label format changed to prevent same day clashes

**22 March 2023**:
* Redcap rewritten and improved - includeding calcsum and datediff
* Bug fix: float textboxes did not work - came out string. Fixed
* Project-specific field added
* Using modified XNAT 1.8 Plugin Template (not working)
* Tested on XNAT 1.8.7

**22 March 2023**:
* Redcap rewritten and improved - includeding calcsum and datediff
* Bug fix: float textboxes did not work - came out string. Fixed
* Project-specific field added
* Using modified XNAT 1.8 Plugin Template
* Tested on XNAT 1.8.7

**26 Jan 2023**:
* Subforms added (else potentially not buildable in gradle due to being too long)
* Tested to XNATv1.8.6.1

## Limitations

* Redcap Calc fields are limited.
* UK Date formats dd-MM-YYYY

Empty file added builder/__init__.py
Empty file.
118 changes: 118 additions & 0 deletions builder/handle_csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import os
import shutil




class CSVHandler(object):

def __init__(self, configData, deleteExistingFiles=False):
self.errors = []
self.log = []
self.configData = configData
self.schemaName = configData['schemaName']
self.csvDir = '{}/data'.format(configData['path_plugin_builder'])


if (deleteExistingFiles):
self.emptyTheDir()

def hasError(self):
return len(self.errors)

def errors(self):
return self.errors




def emptyTheDir(self):

thePath = ('{}/data/{}').format(self.configData['path_plugin_builder'], self.schemaName)
if os.path.exists(thePath):
self.log.append(' Delete Dir : {}'.format(thePath))
shutil.rmtree(thePath)
#make new dir

os.makedirs(thePath)


def getHeader(self, form):

out = 'ID,'
for i in form['inputs']:
el = '{}:{}/{}'.format(self.schemaName, form['ref'], i['dataName'])
if 'subform' in i['inputFormType']:

subform = i['options']
#insert questions later
out = '{}{}@{}@,'.format(out, el,subform)

elif len(i['children']) > 0:
elsub = '{}/{}'.format(el, i['subName'])
out = '{}{},'.format(out, elsub)
for ii in i['children']:
elsub = '{}/{}'.format(el, ii['subName'])
if 'subform' in ii['inputFormType']:
subform = ii['options']
# insert questions later
out = '{}{}@{}@,'.format(out, elsub, subform)
else:
out = '{}{},'.format(out, el)
out = '{}subject_ID'.format(out )
return out

def getLineOfData(self, form, data):


form_label = '{}-{}'.format(form['ref'],data['subject_label'])
out = '{},'.format(form_label)

for i in data['inputs']:
out = '{},{},'.format(out, data[i])
out = '{},{}'.format(out, data['subject_label'] )
return out

def writeToFile(self, form):

head = self.getHeader(form)

if len(head) == 0:
self.errors.append('no inputs')
return

writeFileName = '{}/{}/{}_{}.csv'.format(self.csvDir,self.schemaName,self.schemaName, form['ref'])
#self.checkDir(writeFileName)
self.log.append(' write file : {}'.format(writeFileName))
f = open(writeFileName, "w")

f.write('{}'.format(head))

f.close()

def write_subforms(self, subform):
thePath = ('{}/data/{}').format(self.configData['path_plugin_builder'], self.schemaName)
subform_replace = '@{}@'.format(subform['ref'])
out = ''
if os.path.exists(thePath):
for filename in os.listdir(thePath):
filepath = os.path.join(thePath, filename)
with open(filepath) as f:
header = f.readline()
heads = header.split(',')
for head in heads:
print(head)
if subform_replace in head:
el = head.replace(subform_replace,'')
print(el)
for i in subform['inputs']:
out = '{},{}/{}'.format(out,el, i['dataName'])

else:
out = '{},{}'.format(out,head)

with open(filepath, "w") as f:
#get rid of first and last comma
out = out[1:-1]
f.write(out)

111 changes: 111 additions & 0 deletions builder/handle_file_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import os
import shutil

class PluginHandler(object):

def __init__(self, configData, deleteExistingFiles = False):

self.errors = []
self.log =[]
self.configData = configData
self.schemaName = configData['schemaName']

self.part_plugin_path = 'src/main/java/org/nrg/xnat/plugins/'

def hasError(self):
return len(self.errors)

def errors(self):
return self.errors




def copyTemplatesReplace(self,toDir):

fromDir = ('{}/plugin_template'.format(self.configData['path_builder_templates']))

self.log.append(' copy plugin template from : {}'.format(fromDir))
self.log.append(' copy plugin template to : {}'.format(toDir))
if os.path.exists(toDir):
shutil.rmtree(toDir)

shutil.copytree( fromDir,toDir , symlinks=False, ignore=None)

for root, dirs, files in os.walk(toDir):
for file in files:
if file == '.DS_Store':
continue
f_in = os.path.join(root, file)
# print ('File : ', f_in)
fxsd = open(f_in,"r")
lines = fxsd.readlines()
fxsd.close()
fxsd = open(f_in,"w")

for line in lines:
fxsd.write(line.replace('[HERE_SCHEMANAME_LOWER]',self.schemaName.lower()).replace('[HERE_SCHEMANAME]',self.schemaName.title()))

fxsd.close()

for root, dirs, files in os.walk(toDir):
for file in files:
fo = os.path.join(root, file)
if 'Template' in file:
print ('Renaming {} to {} '.format(file, file.replace('Template',self.schemaName.title()).replace('template',self.schemaName.lower())))
os.rename(fo,os.path.join(root, file.replace('Template',self.schemaName.title()).replace('template',self.schemaName.lower())))
if 'template' in file:
print ('Renaming {} to {} '.format(file, file.replace('Template',self.schemaName.title()).replace('template',self.schemaName.lower())))
os.rename(fo,os.path.join(root, file.replace('template',self.schemaName.lower())))


def createFiles(self,forms):

toDir = ('{}/{}/{}{}').format(self.configData['path_builder_plugins'],self.schemaName, self.part_plugin_path,self.configData['schemaName'].lower())

self.copyTemplatesReplace(toDir)

HERE_IMPORT_BEANS =[]
HERE_XNAT_DATA_MODELS =[]

for f in forms:
sc = self.schemaName[:1].upper() + self.schemaName[1:].lower()
st = forms[f]['ref'][:1].upper() + forms[f]['ref'][1:].lower()
bean = '{}{}Bean'.format(sc,st)
formName = forms[f]['name']
md = '@XnatDataModel(value = {}.SCHEMA_ELEMENT_NAME, singular = "{}", plural = "{}")'.format(bean,formName,formName)

HERE_IMPORT_BEANS.append('import org.nrg.xdat.bean.{};'.format(bean) )
HERE_XNAT_DATA_MODELS.append(md)


file_plugin = ('{}/plugin/Xnat{}Plugin.java'.format(toDir,self.schemaName.title()))
print('FILE', file_plugin)
f = open(file_plugin,"r")
lines = f.readlines()
f.close()

# print(lines)
self.log.append(' replace file contents : {}'.format(file_plugin))

f = open(file_plugin,"w")
for line in lines:
# print(line)
if '[HERE_IMPORT_BEANS]' in line:
f.write(line.replace('[HERE_IMPORT_BEANS]','\n'.join(HERE_IMPORT_BEANS)))
elif '[HERE_XNAT_DATA_MODELS]' in line:
f.write(line.replace('[HERE_XNAT_DATA_MODELS]',','.join(HERE_XNAT_DATA_MODELS)))
elif '[HERE_CLASS_NAME]' in line:
f.write(line.replace('[HERE_CLASS_NAME]',sc))
elif '[HERE_SCHEMANAME_LOWER]' in line:
f.write(line.replace('[HERE_SCHEMANAME_LOWER]',self.configData['schemaName'].lower()))
elif '[HERE_PLUGIN_NAME]' in line:
f.write(line.replace('[HERE_PLUGIN_NAME]',self.configData['schemaName']))
else:
# print(line)
f.write(line)

f.close()



122 changes: 122 additions & 0 deletions builder/handle_file_turbine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import errno
import os
import shutil

class TurbineHandler(object):

def __init__(self, configData, deleteExistingFiles = False):

self.errors = []
self.log =[]
self.configData = configData
self.schemaName = configData['schemaName']

self.filesDir = 'src/main/java/org/apache/turbine/app/xnat/modules/screens/'
self.actionsDir = 'src/main/java/org/apache/turbine/app/xnat/modules/actions/'

if(deleteExistingFiles):
self.emptyTheDir()

def hasError(self):
return len(self.errors)


def checkDir(self,vmFile):

if not os.path.exists(os.path.dirname(vmFile)):
try:
os.makedirs(os.path.dirname(vmFile))
except OSError as exc: # Guard against race condition
if exc.errno != errno.EEXIST:
raise

def emptyTheDir(self):

thePath = ('{}/{}/{}').format(self.configData['path_builder_plugins'],self.schemaName,self.filesDir)
if os.path.exists(thePath):
shutil.rmtree(thePath)

self.log.append(' Empty Dir : {}'.format(thePath))
thePath = ('{}/{}/{}').format(self.configData['path_builder_plugins'],self.schemaName,self.actionsDir)
if os.path.exists(thePath):
shutil.rmtree(thePath)

self.log.append(' Empty Dir : {}'.format(thePath))

def copyAndReplace(self,src,dst, form):
sc = self.schemaName[:1].upper() + self.schemaName[1:].lower()
st = form['ref'][:1].upper() + form['ref'][1:].lower()
om_name = '{}{}'.format(sc, st)
class_name = 'XDATScreen_edit_{}_{}'.format(self.schemaName, form['ref'])
label_tag = form['ref']

f = open(src, "r")
lines = f.readlines()
f.close()

f = open(dst, "w")
for line in lines:
if '[SCHEMA_TITLE]' in line or '[OM_NAME]' in line or '[CLASS_NAME]' in line or '[LABEL_TAG]' in line or '[FORM_NAME]' in line:
line = line.replace('[OM_NAME]', om_name)
line = line.replace('[CLASS_NAME]', class_name)
line = line.replace('[FORM_NAME]', form['ref'])
line = line.replace('[SCHEMA_TITLE]',self.schemaName.title())
f.write(line.replace('[LABEL_TAG]', str(label_tag)))
else:
f.write(line)

f.close()

def loadTemplateReplace(self, form):

fname = ('{}/turbine_java_template.java'.format(self.configData['path_builder_templates']))
if form['ext'] != 'subject':
#sesison level
fname = ('{}/turbine_java_template_session.java'.format(self.configData['path_builder_templates']))
self.log.append(' load file : {}'.format(fname))

return fname


def copyTemplateScreeen(self, form):
src = ('{}/TemplateScreen.java').format(self.configData['path_builder_templates'])
dst = ('{}/{}/{}/{}Screen.java').format(self.configData['path_builder_plugins'], self.schemaName, self.filesDir,self.schemaName.title() )
self.copyAndReplace(src,dst, form)

def copyModifyTemplateScreeen(self,form):
#under actions dir
#for subjects only as dunno about session
if 'ubject' in form['ext']:

dst = ('{}/{}/{}/').format(self.configData['path_builder_plugins'], self.schemaName,self.actionsDir)
if not os.path.exists(os.path.dirname(dst)):
try:
os.makedirs(os.path.dirname(dst))
except OSError as exc: # Guard against race condition
if exc.errno != errno.EEXIST:
raise
self.log.append(' write file : {}'.format(dst))
#DONT USE title() - as does not work if form contains numbers
ref = form['ref'][:1].upper() + form['ref'][1:].lower()

dst = ('{}/{}/{}/Modify{}{}.java').format(self.configData['path_builder_plugins'], self.schemaName, self.actionsDir, self.schemaName.title(), ref)
src = ('{}/ModifyTemplateSample.java').format(self.configData['path_builder_templates'])
self.copyAndReplace(src,dst, form)


def pathTemplateReplaceOut(self,templateType,formRef):

fname = ('{}/{}/{}XDATScreen_{}').format(self.configData['path_builder_plugins'],self.schemaName,self.filesDir,templateType)
return fname + ('_{}_{}.java').format(self.configData['schemaName'],formRef)


def formEdit(self,form):


templateName = self.loadTemplateReplace(form)
writeFileName = self.pathTemplateReplaceOut('edit',form['ref'])

self.log.append(' write file : {}'.format(writeFileName))
self.checkDir(writeFileName)

self.copyAndReplace(templateName,writeFileName, form)
Loading

0 comments on commit 156fe4d

Please sign in to comment.