galaxy-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions

commit/galaxy-central: fubar: Fixes to rgManQQ.py to handle chromosome oddities like 'chr1' and X.
by Bitbucket 19 Jul '11
by Bitbucket 19 Jul '11
19 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/2b55d3bd13d4/
changeset: 2b55d3bd13d4
user: fubar
date: 2011-07-20 04:17:43
summary: Fixes to rgManQQ.py to handle chromosome oddities like 'chr1' and X.
Also cleaned up redundant file recreation - the code passes column numbers to R so the raw data can be read as supplied by Galaxy
Thanks to Alison Harrill for exposing some more input edge cases...
affected #: 3 files (1.3 KB)
--- a/test-data/rgtestouts/rgManQQ/rgManQQtest1.html Tue Jul 19 21:22:07 2011 -0400
+++ b/test-data/rgtestouts/rgManQQ/rgManQQtest1.html Wed Jul 20 12:17:43 2011 +1000
@@ -13,8 +13,8 @@
<h1>rgManQQtest1</h1><table>
-<tr><td><a href="Allelep_manhattan.png"><img src="Allelep_manhattan.png" alt="Allelep_manhattan.png hspace="10" width="400"><br>(Click to download image Allelep_manhattan.png)</a></td></tr>
-<tr><td><a href="Allelep_qqplot.png"><img src="Allelep_qqplot.png" alt="Allelep_qqplot.png hspace="10" width="400"><br>(Click to download image Allelep_qqplot.png)</a></td></tr>
+<tr><td><a href="Allelep_manhattan.png"><img src="Allelep_manhattan.png" title="Allelep_manhattan.png hspace="10" width="400"><br>(Click to download image Allelep_manhattan.png)</a></td></tr>
+<tr><td><a href="Allelep_qqplot.png"><img src="Allelep_qqplot.png" title="Allelep_qqplot.png hspace="10" width="400"><br>(Click to download image Allelep_qqplot.png)</a></td></tr><tr><td><a href="rgManQQtest1.R">rgManQQtest1.R</a></td></tr><tr><td><a href="rgManQQtest1.R.log">rgManQQtest1.R.log</a></td></tr></table>
@@ -35,7 +35,7 @@
- round_any
+ rename, round_any
@@ -43,11 +43,11 @@
Loading required package: proto
-[1] "### 101 values read from /tmp/rgManQQtemplYC5wa read - now running plots"
+[1] "### 101 values read from /data/tmp/tmpTPXdE1/database/files/000/dataset_1.dat read - now running plots"
[1] "## qqplot on Allelep done"
-[1] "## manhattan on Allelep starting 1 2 3"
+[1] "## manhattan on Allelep starting 2 3 8"
[1] "## manhattan plot on Allelep done"
@@ -72,26 +72,30 @@
library(ggplot2)
coloursTouse = c('firebrick','darkblue','goldenrod','darkgreen')
-# not too fugly but need a colour expert please...
+# not too ugly but need a colour expert please...
-manhattan = function(chrom=NULL,offset=NULL,pvals=NULL, title=NULL, max.y="max",
- suggestiveline=0, genomewide=T, size.x.labels=9, size.y.labels=10, annotate=F, SNPlist=NULL,grey=0) {
-
+DrawManhattan = function(pvals=Null,chrom=Null,offset=Null,title=NULL, max.y="max",suggestiveline=0, genomewide=T, size.x.labels=9,
+ size.y.labels=10, annotate=F, SNPlist=NULL,grey=0) {
if (annotate & is.null(SNPlist)) stop("You requested annotation but provided no SNPlist!")
genomewideline=NULL # was genomewideline=-log10(5e-8)
if (genomewide) { # use bonferroni since might be only a small region?
genomewideline = -log10(0.05/length(pvals)) }
- d=data.frame(CHR=chrom,BP=offset,P=pvals)
-
- #limit to only chrs 1-23?
- d=d[d$CHR %in% 1:23, ]
-
+ chro = sub('chr','',chrom, ignore.case = T) # just in case
+ chro = sub(':','',chro, ignore.case = T) # ugh
+ chro = sub('X',23,chro, ignore.case = T)
+ chro = sub('Y',24,chro, ignore.case = T)
+ chro = sub('Mt',25,chro, ignore.case = T)
+ offset = as.integer(offset)
+ pvals = as.double(pvals)
+ chro = as.integer(chro)
+ d=data.frame(CHR=chro,BP=offset,P=pvals)
+ #limit to only chrs 1-22, x=23,y=24,Mt=25?
+ d=d[d$CHR %in% 1:25, ]
if ("CHR" %in% names(d) & "BP" %in% names(d) & "P" %in% names(d) ) {
- d=na.omit(d)
+ #d=na.omit(d)
d=d[d$P>0 & d$P<=1, ]
- d$logp = -log10(d$P)
-
+ d$logp = as.double(-log10(d$P))
d$pos=NA
ticks=NULL
lastbase=0
@@ -107,7 +111,11 @@
lastchr = chrlist[x-1] # previous whatever the list
lastbase=lastbase+tail(subset(d,CHR==lastchr)$BP, 1)
d[d$CHR==i, ]$pos=d[d$CHR==i, ]$BP+lastbase
+ if (sum(is.na(lastchr),is.na(lastbase),is.na(d[d$CHR==i, ]$pos))) {
+ cat(paste('manhattan: For',title,'chrlistx=',i,'lastchr=',lastchr,'lastbase=',lastbase,'pos=',d[d$CHR==i,]$pos))
+ }
tks=c(tks, d[d$CHR==i, ]$pos[floor(length(d[d$CHR==i, ]$pos)/2)+1])
+
}
ticklim=c(min(d$pos),max(d$pos))
xlabs = chrlist
@@ -129,8 +137,6 @@
if (max.y=="max") maxy=ceiling(max(d$logp)) else maxy=max.y
maxy = max(maxy,1.1*genomewideline)
- # if (maxy<8) maxy=8
- # only makes sense if genome wide is assumed - we could have a fine mapping region?
if (annotate) d.annotate=d[as.numeric(substr(d$SNP,3,100)) %in% SNPlist, ]
if (nchr >= 2) {
manplot=qplot(pos,logp,data=d, ylab=expression(-log[10](italic(p))) , colour=factor(CHR))
@@ -149,9 +155,6 @@
axis.text.y=theme_text(size=size.y.labels, colour="grey50"),
axis.ticks=theme_segment(colour=NA)
)
- #manplot = manplot + opts(panel.grid.y.minor=theme_blank(),panel.grid.y.major=theme_blank())
- #manplot = manplot + opts(panel.grid.major=theme_blank())
-
if (suggestiveline) manplot=manplot+geom_hline(yintercept=suggestiveline,colour="blue", alpha=I(1/3))
if (genomewideline) manplot=manplot+geom_hline(yintercept=genomewideline,colour="red")
manplot
@@ -178,7 +181,8 @@
if (spartan) plot=plot+opts(panel.background=theme_rect(col="grey50"), panel.grid.minor=theme_blank())
qq
}
-rgqqMan = function(infile="/tmp/rgManQQtemplYC5wa",chromcolumn=1, offsetcolumn=2, pvalscolumns=c(3),
+
+rgqqMan = function(infile="/data/tmp/tmpTPXdE1/database/files/000/dataset_1.dat",chromcolumn=2, offsetcolumn=3, pvalscolumns=c(8),
title="rgManQQtest1",grey=0) {
rawd = read.table(infile,head=T,sep='\t')
dn = names(rawd)
@@ -206,7 +210,7 @@
doreorder = 0
}
print(paste('## manhattan on',cname,'starting',chromcolumn,offsetcolumn,pvalscolumn))
- mymanplot= manhattan(chrom=rawd[,chromcolumn],offset=rawd[,offsetcolumn],pvals=rawd[,pvalscolumn],title=mytitle,grey=grey)
+ mymanplot= DrawManhattan(chrom=rawd[,chromcolumn],offset=rawd[,offsetcolumn],pvals=rawd[,pvalscolumn],title=mytitle,grey=grey)
print(paste('## manhattan plot on',cname,'done'))
ggsave(filename=paste(myfname,"manhattan.png",sep='_'),mymanplot,width=6,height=4,dpi=100)
}
@@ -227,6 +231,6 @@
</pre>
-<h3><a href="http://rgenetics.org">Rgenetics</a> tool rgManQQ.py run at 07/11/2010 20:04:20</h3>
+<b><a href="http://rgenetics.org">Galaxy Rgenetics</a> tool output rgManQQ.py run at 20/07/2011 12:08:46</b><br/></div></body></html>
--- a/tools/rgenetics/rgManQQ.py Tue Jul 19 21:22:07 2011 -0400
+++ b/tools/rgenetics/rgManQQ.py Wed Jul 20 12:17:43 2011 +1000
@@ -1,5 +1,7 @@
#!/usr/local/bin/python
-
+# rgmanqq updated july 19 to deal with x,y and mt
+# lots of fixes
+# ross lazarus
import sys,math,shutil,subprocess,os,time,tempfile,string
from os.path import abspath
from rgutils import timenow, RRun, galhtmlprefix, galhtmlpostfix, galhtmlattr
@@ -18,7 +20,7 @@
# http://StephenTurner.us/
# http://GettingGeneticsDone.blogspot.com/
-# Last updated: Tuesday, December 22, 2009
+# Last updated: 19 July 2011 by Ross Lazarus
# R code for making manhattan plots and QQ plots from plink output files.
# With GWAS data this can take a lot of memory. Recommended for use on
# 64bit machines only, for now.
@@ -28,26 +30,30 @@
library(ggplot2)
coloursTouse = c('firebrick','darkblue','goldenrod','darkgreen')
-# not too fugly but need a colour expert please...
+# not too ugly but need a colour expert please...
-manhattan = function(chrom=NULL,offset=NULL,pvals=NULL, title=NULL, max.y="max",
- suggestiveline=0, genomewide=T, size.x.labels=9, size.y.labels=10, annotate=F, SNPlist=NULL,grey=0) {
-
+DrawManhattan = function(pvals=Null,chrom=Null,offset=Null,title=NULL, max.y="max",suggestiveline=0, genomewide=T, size.x.labels=9,
+ size.y.labels=10, annotate=F, SNPlist=NULL,grey=0) {
if (annotate & is.null(SNPlist)) stop("You requested annotation but provided no SNPlist!")
genomewideline=NULL # was genomewideline=-log10(5e-8)
if (genomewide) { # use bonferroni since might be only a small region?
genomewideline = -log10(0.05/length(pvals)) }
- d=data.frame(CHR=chrom,BP=offset,P=pvals)
-
- #limit to only chrs 1-23?
- d=d[d$CHR %in% 1:23, ]
-
+ chro = sub('chr','',chrom, ignore.case = T) # just in case
+ chro = sub(':','',chro, ignore.case = T) # ugh
+ chro = sub('X',23,chro, ignore.case = T)
+ chro = sub('Y',24,chro, ignore.case = T)
+ chro = sub('Mt',25,chro, ignore.case = T)
+ offset = as.integer(offset)
+ pvals = as.double(pvals)
+ chro = as.integer(chro)
+ d=data.frame(CHR=chro,BP=offset,P=pvals)
+ #limit to only chrs 1-22, x=23,y=24,Mt=25?
+ d=d[d$CHR %in% 1:25, ]
if ("CHR" %in% names(d) & "BP" %in% names(d) & "P" %in% names(d) ) {
- d=na.omit(d)
+ #d=na.omit(d)
d=d[d$P>0 & d$P<=1, ]
- d$logp = -log10(d$P)
-
+ d$logp = as.double(-log10(d$P))
d$pos=NA
ticks=NULL
lastbase=0
@@ -63,7 +69,11 @@
lastchr = chrlist[x-1] # previous whatever the list
lastbase=lastbase+tail(subset(d,CHR==lastchr)$BP, 1)
d[d$CHR==i, ]$pos=d[d$CHR==i, ]$BP+lastbase
+ if (sum(is.na(lastchr),is.na(lastbase),is.na(d[d$CHR==i, ]$pos))) {
+ cat(paste('manhattan: For',title,'chrlistx=',i,'lastchr=',lastchr,'lastbase=',lastbase,'pos=',d[d$CHR==i,]$pos))
+ }
tks=c(tks, d[d$CHR==i, ]$pos[floor(length(d[d$CHR==i, ]$pos)/2)+1])
+
}
ticklim=c(min(d$pos),max(d$pos))
xlabs = chrlist
@@ -85,8 +95,6 @@
if (max.y=="max") maxy=ceiling(max(d$logp)) else maxy=max.y
maxy = max(maxy,1.1*genomewideline)
- # if (maxy<8) maxy=8
- # only makes sense if genome wide is assumed - we could have a fine mapping region?
if (annotate) d.annotate=d[as.numeric(substr(d$SNP,3,100)) %in% SNPlist, ]
if (nchr >= 2) {
manplot=qplot(pos,logp,data=d, ylab=expression(-log[10](italic(p))) , colour=factor(CHR))
@@ -105,9 +113,6 @@
axis.text.y=theme_text(size=size.y.labels, colour="grey50"),
axis.ticks=theme_segment(colour=NA)
)
- #manplot = manplot + opts(panel.grid.y.minor=theme_blank(),panel.grid.y.major=theme_blank())
- #manplot = manplot + opts(panel.grid.major=theme_blank())
-
if (suggestiveline) manplot=manplot+geom_hline(yintercept=suggestiveline,colour="blue", alpha=I(1/3))
if (genomewideline) manplot=manplot+geom_hline(yintercept=genomewideline,colour="red")
manplot
@@ -134,12 +139,13 @@
if (spartan) plot=plot+opts(panel.background=theme_rect(col="grey50"), panel.grid.minor=theme_blank())
qq
}
+
"""
# we need another string to avoid confusion over string substitutions with %in%
# instantiate rcode2 string with infile,chromcol,offsetcol,pvalscols,title before saving and running
-rcode2 = """rgqqMan = function(infile="%s",chromcolumn=%s, offsetcolumn=%s, pvalscolumns=%s,
+rcode2 = """rgqqMan = function(infile="%s",chromcolumn=%d, offsetcolumn=%d, pvalscolumns=c(%s),
title="%s",grey=%d) {
rawd = read.table(infile,head=T,sep='\\t')
dn = names(rawd)
@@ -167,7 +173,7 @@
doreorder = 0
}
print(paste('## manhattan on',cname,'starting',chromcolumn,offsetcolumn,pvalscolumn))
- mymanplot= manhattan(chrom=rawd[,chromcolumn],offset=rawd[,offsetcolumn],pvals=rawd[,pvalscolumn],title=mytitle,grey=grey)
+ mymanplot= DrawManhattan(chrom=rawd[,chromcolumn],offset=rawd[,offsetcolumn],pvals=rawd[,pvalscolumn],title=mytitle,grey=grey)
print(paste('## manhattan plot on',cname,'done'))
ggsave(filename=paste(myfname,"manhattan.png",sep='_'),mymanplot,width=6,height=4,dpi=100)
}
@@ -198,50 +204,13 @@
this can be called externally, I guess...for QC eg?
"""
if debug:
- print 'doManQQ',input_fname,chrom_col,offset_col,pval_cols,title,grey,ctitle,outdir
- ffd,filtered_fname = tempfile.mkstemp(prefix='rgManQQtemp')
- f = open(filtered_fname,'w')
- inf = open(input_fname,'r')
- ohead = inf.readline().strip().split('\t') # see if we have a header
- inf.seek(0) # rewind
- newhead = ['pval%d' % (x+1) for x in pval_cols]
- newhead.insert(0,'Offset')
- newhead.insert(0,'Chrom')
- havehead = 0
- wewant = [chrom_col,offset_col]
- wewant += pval_cols
- try:
- allnums = ['%d' % x for x in ohead] # this should barf if non numerics == header row?
- f.write('\t'.join(newhead)) # for R to read
- f.write('\n')
- except:
- havehead = 1
- newhead = [ohead[chrom_col],ohead[offset_col]]
- newhead += [ohead[x] for x in pval_cols]
- f.write('\t'.join(newhead)) # use the original head
- f.write('\n')
- for i,row in enumerate(inf):
- if i == 0 and havehead:
- continue # ignore header
- sr = row.strip().split('\t')
- if len(sr) > 1:
- if sr[chrom_col].lower().find('chr') <> -1:
- sr[chrom_col] = sr[chrom_col][3:]
- newr = [sr[x] for x in wewant] # grab cols we need
- s = '\t'.join(newr)
- f.write(s)
- f.write('\n')
- f.close()
- pvc = [x+3 for x in range(len(pval_cols))] # 2 for offset and chrom, 1 for r offset start
- pvc = 'c(%s)' % (','.join(map(str,pvc)))
- rcmd = '%s%s' % (rcode,rcode2 % (filtered_fname,'1','2',pvc,title,grey))
+ print 'doManQQ',input_fname,chrom_col,offset_col,pval_cols,title,grey,ctitle,outdir
+ rcmd = '%s%s' % (rcode,rcode2 % (input_fname,chrom_col,offset_col,pval_cols,title,grey))
if debug:
- print 'running\n%s\n' % rcmd
+ print 'running\n%s\n' % rcmd
rlog,flist = RRun(rcmd=rcmd,title=ctitle,outdir=outdir)
rlog.append('## R script=')
rlog.append(rcmd)
- if beTidy:
- os.unlink(filtered_fname)
return rlog,flist
@@ -272,19 +241,20 @@
offset_col = -1
p = sys.argv[7].strip().split(',')
try:
- p = [int(x) for x in p]
+ q = [int(x) for x in p]
except:
- p = [-1]
+ p = -1
if chrom_col == -1 or offset_col == -1: # was passed as zero - do not do manhattan plots
chrom_col = -1
offset_col = -1
grey = 0
if (sys.argv[8].lower() in ['1','true']):
grey = 1
- if p == [-1]:
+ if p == -1:
print >> sys.stderr,'## Cannot run rgManQQ - missing pval column'
sys.exit(1)
- rlog,flist = doManQQ(input_fname,chrom_col,offset_col,p,title,grey,ctitle,outdir)
+ p = ['%d' % (int(x) + 1) for x in p]
+ rlog,flist = doManQQ(input_fname,chrom_col+1,offset_col+1,','.join(p),title,grey,ctitle,outdir)
flist.sort()
html = [galhtmlprefix % progname,]
html.append('<h1>%s</h1>' % title)
@@ -294,7 +264,7 @@
fname,expl = row # RRun returns pairs of filenames fiddled for the log and R script
e = os.path.splitext(fname)[-1]
if e in ['.png','.jpg']:
- s= '<tr><td><a href="%s"><img src="%s" alt="%s hspace="10" width="400"><br>(Click to download image %s)</a></td></tr>' \
+ s= '<tr><td><a href="%s"><img src="%s" title="%s hspace="10" width="400"><br>(Click to download image %s)</a></td></tr>' \
% (fname,fname,expl,expl )
html.append(s)
else:
@@ -317,3 +287,4 @@
if __name__ == "__main__":
main()
+
--- a/tools/rgenetics/rgManQQ.xml Tue Jul 19 21:22:07 2011 -0400
+++ b/tools/rgenetics/rgManQQ.xml Wed Jul 20 12:17:43 2011 +1000
@@ -1,4 +1,4 @@
-<tool id="rgManQQ1" name="Manhattan/QQ:" version="1.0.1">
+<tool id="rgManQQ1" name="Manhattan/QQ:" version="1.0.2"><code file="rgManQQ_code.py"/><description>Plots for WGA P values</description>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: kanwei: Fix LibraryField grouping issue by adding prefix
by Bitbucket 19 Jul '11
by Bitbucket 19 Jul '11
19 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/f5f352f7099d/
changeset: f5f352f7099d
user: kanwei
date: 2011-07-20 03:22:07
summary: Fix LibraryField grouping issue by adding prefix
affected #: 1 file (21 bytes)
--- a/lib/galaxy/web/form_builder.py Tue Jul 19 15:10:11 2011 -0400
+++ b/lib/galaxy/web/form_builder.py Tue Jul 19 21:22:07 2011 -0400
@@ -658,7 +658,7 @@
self.name = name
self.ldda = value
self.trans = trans
- def get_html( self, disabled=False ):
+ def get_html( self, prefix="", disabled=False ):
if not self.ldda:
ldda = ""
text = "Choose a library dataset"
@@ -666,7 +666,7 @@
ldda = self.trans.security.encode_id(self.ldda.id)
text = self.ldda.name
return '<a href="javascript:void(0);" class="add-librarydataset">%s</a> \
- <input type="hidden" name="%s" value="%s">' % ( text, self.name, escape( str(ldda), quote=True ) )
+ <input type="hidden" name="%s%s" value="%s">' % ( text, prefix, self.name, escape( str(ldda), quote=True ) )
def get_display_text(self):
if self.ldda:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Fix for message display when setting tool shed repository metadata.
by Bitbucket 19 Jul '11
by Bitbucket 19 Jul '11
19 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/9d17faf3398a/
changeset: 9d17faf3398a
user: greg
date: 2011-07-19 21:10:11
summary: Fix for message display when setting tool shed repository metadata.
affected #: 1 file (64 bytes)
--- a/lib/galaxy/webapps/community/controllers/common.py Tue Jul 19 13:48:42 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/common.py Tue Jul 19 15:10:11 2011 -0400
@@ -230,6 +230,8 @@
correction_msg += "Upload a file named <b>%s</b> to the repository to correct this error." % sample_loc_file
else:
correction_msg += "Upload a file named <b>%s</b> to the repository to correct this error." % missing_file
+ else:
+ correction_msg = exception_msg
message += "<b>%s</b> - %s<br/>" % ( tool_file, correction_msg )
status = 'error'
elif flush_needed:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/f9ef2aecaecd/
changeset: f9ef2aecaecd
user: greg
date: 2011-07-19 19:48:42
summary: Add exception handling around all mercurial api commit calls. On Linux, the mercurial api's commit seems to bump into issues intermittently, throws an exception, and rolls back the transaction. Although I can reproduce it on Linux, I cannot produce this behavior on a Mac. The exception handler uses a different approach to committing the changes. I've also added this code to the update_for_browsing method.
affected #: 3 files (1.9 KB)
--- a/lib/galaxy/webapps/community/controllers/common.py Tue Jul 19 11:27:16 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/common.py Tue Jul 19 13:48:42 2011 -0400
@@ -297,7 +297,7 @@
util.send_mail( frm, to, subject, body, trans.app.config )
except Exception, e:
log.exception( "An error occurred sending a tool shed repository update alert by email." )
-def update_for_browsing( repository, current_working_dir ):
+def update_for_browsing( repository, current_working_dir, commit_message='' ):
# Make a copy of a repository's files for browsing.
repo_dir = repository.repo_path
repo = hg.repository( ui.ui(), repo_dir )
@@ -316,12 +316,15 @@
# ! = deleted, but still tracked
# ? = not tracked
# I = ignored
- # We'll remove all files that are not tracked or ignored.
files_to_remove_from_disk = []
+ files_to_commit = []
for status_and_file_name in status_and_file_names:
if status_and_file_name.startswith( '?' ) or status_and_file_name.startswith( 'I' ):
files_to_remove_from_disk.append( os.path.abspath( os.path.join( repo_dir, status_and_file_name.split()[1] ) ) )
+ elif status_and_file_name.startswith( 'M' ) or status_and_file_name.startswith( 'A' ) or status_and_file_name.startswith( 'R' ):
+ files_to_commit.append( os.path.abspath( os.path.join( repo_dir, status_and_file_name.split()[1] ) ) )
for full_path in files_to_remove_from_disk:
+ # We'll remove all files that are not tracked or ignored.
if os.path.isdir( full_path ):
try:
os.rmdir( full_path )
@@ -336,6 +339,11 @@
except OSError, e:
# The directory is not empty
pass
+ if files_to_commit:
+ if not commit_message:
+ commit_message = 'Committed changes to: %s' % ', '.join( files_to_commit )
+ repo.dirstate.write()
+ repo.commit( text=commit_message )
os.chdir( repo_dir )
os.system( 'hg update > /dev/null 2>&1' )
os.chdir( current_working_dir )
--- a/lib/galaxy/webapps/community/controllers/repository.py Tue Jul 19 11:27:16 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Tue Jul 19 13:48:42 2011 -0400
@@ -425,7 +425,7 @@
repository = get_repository( trans, id )
repo = hg.repository( ui.ui(), repository.repo_path )
current_working_dir = os.getcwd()
- update_for_browsing( repository, current_working_dir )
+ update_for_browsing( repository, current_working_dir, commit_message=commit_message )
return trans.fill_template( '/webapps/community/repository/browse_repository.mako',
repo=repo,
repository=repository,
@@ -454,11 +454,17 @@
# Commit the change set.
if not commit_message:
commit_message = 'Deleted selected files'
- # Commit the changes.
- commands.commit( repo.ui, repo, repo_dir, user=trans.user.username, message=commit_message )
+ try:
+ commands.commit( repo.ui, repo, repo_dir, user=trans.user.username, message=commit_message )
+ except Exception, e:
+ # I never have a problem with commands.commit on a Mac, but in the test/production
+ # tool shed environment, it occasionally throws a "TypeError: array item must be char"
+ # exception. If this happens, we'll try the following.
+ repo.dirstate.write()
+ repo.commit( text=commit_message )
handle_email_alerts( trans, repository )
# Update the repository files for browsing.
- update_for_browsing( repository, current_working_dir )
+ update_for_browsing( repository, current_working_dir, commit_message=commit_message )
# Get the new repository tip.
repo = hg.repository( ui.ui(), repo_dir )
if tip != repository.tip:
--- a/lib/galaxy/webapps/community/controllers/upload.py Tue Jul 19 11:27:16 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/upload.py Tue Jul 19 13:48:42 2011 -0400
@@ -87,7 +87,16 @@
# Move the uploaded file to the load_point within the repository hierarchy.
shutil.move( uploaded_file_name, full_path )
commands.add( repo.ui, repo, full_path )
- commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
+ """
+ try:
+ commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
+ except Exception, e:
+ # I never have a problem with commands.commit on a Mac, but in the test/production
+ # tool shed environment, it occasionally throws a "TypeError: array item must be char"
+ # exception. If this happens, we'll try the following.
+ repo.dirstate.write()
+ repo.commit( text=commit_message )
+ """
if full_path.endswith( '.loc.sample' ):
# Handle the special case where a xxx.loc.sample file is
# being uploaded by copying it to ~/tool-data/xxx.loc.
@@ -96,7 +105,7 @@
if ok:
# Update the repository files for browsing, a by-product of doing this
# is eliminating unwanted files from the repository directory.
- update_for_browsing( repository, current_working_dir )
+ update_for_browsing( repository, current_working_dir, commit_message=commit_message )
# Get the new repository tip.
if tip != repository.tip:
if ( isgzip or isbz2 ) and uncompress_file:
@@ -183,8 +192,14 @@
# Handle the special case where a xxx.loc.sample file is
# being uploaded by copying it to ~/tool-data/xxx.loc.
copy_sample_loc_file( trans, filename_in_archive )
- # Commit the changes.
- commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
+ try:
+ commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
+ except Exception, e:
+ # I never have a problem with commands.commit on a Mac, but in the test/production
+ # tool shed environment, it occasionally throws a "TypeError: array item must be char"
+ # exception. If this happens, we'll try the following.
+ repo.dirstate.write()
+ repo.commit( text=commit_message )
handle_email_alerts( trans, repository )
return True, '', files_to_remove
def uncompress( self, repository, uploaded_file_name, uploaded_file_filename, isgzip, isbz2 ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

19 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/98ef4f135243/
changeset: 98ef4f135243
user: greg
date: 2011-07-19 17:27:16
summary: Various tool shed fixes and enhancements:
1) Fix for uploading empty files to a repository
2) Better error messages when setting repository metadata fails
3) Automatically copy uploaded xxx.loc.sample files to ~/tool-data/xxx.loc
4) Fix for setting the value of the upload_point when uploading files to a repository
affected #: 4 files (3.3 KB)
--- a/lib/galaxy/webapps/community/controllers/common.py Mon Jul 18 21:56:23 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/common.py Tue Jul 19 11:27:16 2011 -0400
@@ -214,7 +214,23 @@
if invalid_files:
message = "Metadata cannot be defined for change set revision '%s'. Correct the following problems and reset metadata.<br/>" % str( change_set_revision )
for itc_tup in invalid_files:
- message += "<b>%s</b> - %s<br/>" % ( itc_tup[0], itc_tup[1] )
+ # Handle the special case where a tool depends on a missing xxx.loc file by telliing
+ # the user to upload xxx.loc.sample to the repository so that it can be copied to
+ # ~/tool-data/xxx.loc. In this case, itc_tup[1] will be a message looking something like:
+ # [Errno 2] No such file or directory: '/Users/gvk/central/tool-data/blast2go.loc'
+ tool_file = itc_tup[0]
+ exception_msg = itc_tup[1]
+ if exception_msg.find( 'No such file or directory' ) >= 0:
+ exception_items = exception_msg.split()
+ missing_file_items = exception_items[7].split( '/' )
+ missing_file = missing_file_items[-1].rstrip( '\'' )
+ correction_msg = "This file refers to a missing file <b>%s</b>. " % str( missing_file )
+ if exception_msg.find( '.loc' ) >= 0:
+ sample_loc_file = '%s.sample' % str( missing_file )
+ correction_msg += "Upload a file named <b>%s</b> to the repository to correct this error." % sample_loc_file
+ else:
+ correction_msg += "Upload a file named <b>%s</b> to the repository to correct this error." % missing_file
+ message += "<b>%s</b> - %s<br/>" % ( tool_file, correction_msg )
status = 'error'
elif flush_needed:
# We only flush if there are no tool config errors, so change sets will only have metadata
@@ -231,6 +247,14 @@
if str( ctx ) == change_set_revision:
return ctx
return None
+def copy_sample_loc_file( trans, filename ):
+ """Copy xxx.loc.sample to ~/tool-data/xxx.loc"""
+ sample_loc_file = os.path.split( filename )[1]
+ loc_file = os.path.split( filename )[1].rstrip( '.sample' )
+ tool_data_path = os.path.abspath( trans.app.config.tool_data_path )
+ if not ( os.path.exists( os.path.join( tool_data_path, loc_file ) ) or os.path.exists( os.path.join( tool_data_path, sample_loc_file ) ) ):
+ shutil.copy( os.path.abspath( filename ), os.path.join( tool_data_path, sample_loc_file ) )
+ shutil.copy( os.path.abspath( filename ), os.path.join( tool_data_path, loc_file ) )
def get_user( trans, id ):
"""Get a user from the database"""
return trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( id ) )
--- a/lib/galaxy/webapps/community/controllers/upload.py Mon Jul 18 21:56:23 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/upload.py Tue Jul 19 11:27:16 2011 -0400
@@ -45,6 +45,7 @@
uploaded_file = file_data.file
uploaded_file_name = uploaded_file.name
uploaded_file_filename = file_data.filename
+ isempty = os.path.getsize( os.path.abspath( uploaded_file_name ) ) == 0
if uploaded_file:
isgzip = False
isbz2 = False
@@ -53,17 +54,21 @@
if not isgzip:
isbz2 = is_bz2( uploaded_file_name )
ok = True
- # Determine what we have - a single file or an archive
- try:
- if ( isgzip or isbz2 ) and uncompress_file:
- # Open for reading with transparent compression.
- tar = tarfile.open( uploaded_file_name, 'r:*' )
- else:
- tar = tarfile.open( uploaded_file_name )
- istar = True
- except tarfile.ReadError, e:
+ if isempty:
tar = None
istar = False
+ else:
+ # Determine what we have - a single file or an archive
+ try:
+ if ( isgzip or isbz2 ) and uncompress_file:
+ # Open for reading with transparent compression.
+ tar = tarfile.open( uploaded_file_name, 'r:*' )
+ else:
+ tar = tarfile.open( uploaded_file_name )
+ istar = True
+ except tarfile.ReadError, e:
+ tar = None
+ istar = False
if istar:
ok, message, files_to_remove = self.upload_tar( trans,
repository,
@@ -83,6 +88,10 @@
shutil.move( uploaded_file_name, full_path )
commands.add( repo.ui, repo, full_path )
commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
+ if full_path.endswith( '.loc.sample' ):
+ # Handle the special case where a xxx.loc.sample file is
+ # being uploaded by copying it to ~/tool-data/xxx.loc.
+ copy_sample_loc_file( trans, full_path )
handle_email_alerts( trans, repository )
if ok:
# Update the repository files for browsing, a by-product of doing this
@@ -170,6 +179,10 @@
commands.remove( repo.ui, repo, repo_file )
for filename_in_archive in filenames_in_archive:
commands.add( repo.ui, repo, filename_in_archive )
+ if filename_in_archive.endswith( '.loc.sample' ):
+ # Handle the special case where a xxx.loc.sample file is
+ # being uploaded by copying it to ~/tool-data/xxx.loc.
+ copy_sample_loc_file( trans, filename_in_archive )
# Commit the changes.
commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
handle_email_alerts( trans, repository )
--- a/templates/webapps/community/repository/common.mako Mon Jul 18 21:56:23 2011 -0400
+++ b/templates/webapps/community/repository/common.mako Tue Jul 19 11:27:16 2011 -0400
@@ -44,7 +44,7 @@
}
// The following is used only in ~/templates/webapps/community/repository/upload.mako.
if (document.forms["upload_form"]) {
- document.upload_form.upload_point.value = selKeys[0];
+ document.upload_form.upload_point.value = selKeys.slice(-1);
}
},
onActivate: function(dtnode) {
--- a/templates/webapps/community/repository/upload.mako Mon Jul 18 21:56:23 2011 -0400
+++ b/templates/webapps/community/repository/upload.mako Tue Jul 19 11:27:16 2011 -0400
@@ -64,96 +64,96 @@
<div class="toolForm"><div class="toolFormTitle">Upload a single file or a tarball</div><div class="toolFormBody">
- ## TODO: nginx
- <form id="upload_form" name="upload_form" action="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ) )}" enctype="multipart/form-data" method="post">
- <div class="form-row">
- <label>File:</label>
- <div class="form-row-input">
- <input type="file" name="file_data"/>
- </div>
- <div style="clear: both"></div>
- </div>
-
- <div class="form-row">
- <%
- if uncompress_file:
- yes_selected = 'selected'
- no_selected = ''
- else:
- yes_selected = ''
- no_selected = 'selected'
- %>
- <label>Uncompress files?</label>
- <div class="form-row-input">
- <select name="uncompress_file">
- <option value="true" ${yes_selected}>Yes
- <option value="false" ${no_selected}>No
- </select>
- </div>
- <div class="toolParamHelp" style="clear: both;">
- Supported compression types are gz and bz2. If <b>Yes</b> is selected, the uploaded file will be uncompressed. However,
- if the uploaded file is an archive that contains compressed files, the contained files will not be uncompressed. For
- example, if the uploaded compressed file is some_file.tar.gz, some_file.tar will be uncompressed and extracted, but if
- some_file.tar contains some_contained_file.gz, the contained file will not be uncompressed.
- </div>
- </div>
- %if not is_new:
- <div class="form-row">
- <%
- if remove_repo_files_not_in_tar:
- yes_selected = 'selected'
- no_selected = ''
- else:
- yes_selected = ''
- no_selected = 'selected'
- %>
- <label>Remove files in the repository (relative to the root or selected upload point) that are not in the uploaded archive?</label>
- <div class="form-row-input">
- <select name="remove_repo_files_not_in_tar">
- <option value="true" ${yes_selected}>Yes
- <option value="false" ${no_selected}>No
- </select>
+ ## TODO: nginx
+ <form id="upload_form" name="upload_form" action="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ) )}" enctype="multipart/form-data" method="post">
+ <div class="form-row">
+ <label>File:</label>
+ <div class="form-row-input">
+ <input type="file" name="file_data"/>
+ </div>
+ <div style="clear: both"></div></div>
- <div class="toolParamHelp" style="clear: both;">
- This selection pertains only to uploaded tar archives, not to single file uploads. If <b>Yes</b> is selected, files
- that exist in the repository (relative to the root or selected upload point) but that are not in the uploaded archive
- will be removed from the repository. Otherwise, all existing repository files will remain and the uploaded archive
- files will be added to the repository.
+
+ <div class="form-row">
+ <%
+ if uncompress_file:
+ yes_selected = 'selected'
+ no_selected = ''
+ else:
+ yes_selected = ''
+ no_selected = 'selected'
+ %>
+ <label>Uncompress files?</label>
+ <div class="form-row-input">
+ <select name="uncompress_file">
+ <option value="true" ${yes_selected}>Yes
+ <option value="false" ${no_selected}>No
+ </select>
+ </div>
+ <div class="toolParamHelp" style="clear: both;">
+ Supported compression types are gz and bz2. If <b>Yes</b> is selected, the uploaded file will be uncompressed. However,
+ if the uploaded file is an archive that contains compressed files, the contained files will not be uncompressed. For
+ example, if the uploaded compressed file is some_file.tar.gz, some_file.tar will be uncompressed and extracted, but if
+ some_file.tar contains some_contained_file.gz, the contained file will not be uncompressed.
+ </div></div>
- </div>
- %endif
- <div class="form-row">
- <label>Change set commit message:</label>
- <div class="form-row-input">
- %if commit_message:
- <pre><textarea name="commit_message" rows="3" cols="35">${commit_message}</textarea></pre>
- %else:
- <textarea name="commit_message" rows="3" cols="35"></textarea>
+ %if not is_new:
+ <div class="form-row">
+ <%
+ if remove_repo_files_not_in_tar:
+ yes_selected = 'selected'
+ no_selected = ''
+ else:
+ yes_selected = ''
+ no_selected = 'selected'
+ %>
+ <label>Remove files in the repository (relative to the root or selected upload point) that are not in the uploaded archive?</label>
+ <div class="form-row-input">
+ <select name="remove_repo_files_not_in_tar">
+ <option value="true" ${yes_selected}>Yes
+ <option value="false" ${no_selected}>No
+ </select>
+ </div>
+ <div class="toolParamHelp" style="clear: both;">
+ This selection pertains only to uploaded tar archives, not to single file uploads. If <b>Yes</b> is selected, files
+ that exist in the repository (relative to the root or selected upload point) but that are not in the uploaded archive
+ will be removed from the repository. Otherwise, all existing repository files will remain and the uploaded archive
+ files will be added to the repository.
+ </div>
+ </div>
%endif
- </div>
- <div class="toolParamHelp" style="clear: both;">
- This is the commit message for the mercurial change set that will be created by this upload.
- </div>
- <div style="clear: both"></div>
- </div>
- %if not repository.is_new:
- <div class="form-row" >
- <label>Contents:</label>
- <div id="tree" >
- Loading...
+ <div class="form-row">
+ <label>Change set commit message:</label>
+ <div class="form-row-input">
+ %if commit_message:
+ <pre><textarea name="commit_message" rows="3" cols="35">${commit_message}</textarea></pre>
+ %else:
+ <textarea name="commit_message" rows="3" cols="35"></textarea>
+ %endif
+ </div>
+ <div class="toolParamHelp" style="clear: both;">
+ This is the commit message for the mercurial change set that will be created by this upload.
+ </div>
+ <div style="clear: both"></div></div>
- <input type="hidden" id="upload_point" name="upload_point" value=""/>
- <div class="toolParamHelp" style="clear: both;">
- Select a location within the repository to upload your files by clicking a check box next to the location. The
- selected location is considered the upload point. If a location is not selected, the upload point will be the
- repository root.
+ %if not repository.is_new:
+ <div class="form-row" >
+ <label>Contents:</label>
+ <div id="tree" >
+ Loading...
+ </div>
+ <input type="hidden" id="upload_point" name="upload_point" value=""/>
+ <div class="toolParamHelp" style="clear: both;">
+ Select a location within the repository to upload your files by clicking a check box next to the location. The
+ selected location is considered the upload point. If a location is not selected, the upload point will be the
+ repository root.
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ %endif
+ <div class="form-row">
+ <input type="submit" class="primary-button" name="upload_button" value="Upload"></div>
- <div style="clear: both"></div>
- </div>
- %endif
- <div class="form-row">
- <input type="submit" class="primary-button" name="upload_button" value="Upload">
- </div>
- </form>
+ </form></div></div>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

18 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/8553b02ce9ee/
changeset: 8553b02ce9ee
user: kanwei
date: 2011-07-19 03:56:23
summary: Tools: Add new LibraryDataset tool parameter to expose LDDAs to tools. Use trackster's modal popup interface for item selection. Add new InputWrapper that exposes LDDA templates as well.
Refactor tool_form.mako to use base_panels.mako instead of its own custom HTML.
affected #: 9 files (4.1 KB)
--- a/lib/galaxy/tools/__init__.py Mon Jul 18 15:02:37 2011 -0400
+++ b/lib/galaxy/tools/__init__.py Mon Jul 18 21:56:23 2011 -0400
@@ -1463,6 +1463,11 @@
elif isinstance( input, SelectToolParameter ):
input_values[ input.name ] = SelectToolParameterWrapper(
input, input_values[ input.name ], self.app, other_values = param_dict )
+
+ elif isinstance( input, LibraryDatasetToolParameter ):
+ input_values[ input.name ] = LibraryDatasetValueWrapper(
+ input, input_values[ input.name ], param_dict )
+
else:
input_values[ input.name ] = InputValueWrapper(
input, input_values[ input.name ], param_dict )
@@ -2013,6 +2018,31 @@
def __getattr__( self, key ):
return getattr( self.obj, key )
+class LibraryDatasetValueWrapper( object ):
+ """
+ Wraps an input so that __str__ gives the "param_dict" representation.
+ """
+ def __init__( self, input, value, other_values={} ):
+ self.input = input
+ self.value = value
+ self._other_values = other_values
+ def __str__( self ):
+ return self.value.name
+ def templates( self ):
+ if not self.value:
+ return None
+ template_data = {}
+ for temp_info in self.value.info_association:
+ template = temp_info.template
+ content = temp_info.info.content
+ tmp_dict = {}
+ for field in template.fields:
+ tmp_dict[field['label']] = content[field['name']]
+ template_data[template.name] = tmp_dict
+ return template_data
+ def __getattr__( self, key ):
+ return getattr( self.value, key )
+
class InputValueWrapper( object ):
"""
Wraps an input so that __str__ gives the "param_dict" representation.
--- a/lib/galaxy/tools/parameters/basic.py Mon Jul 18 15:02:37 2011 -0400
+++ b/lib/galaxy/tools/parameters/basic.py Mon Jul 18 21:56:23 2011 -0400
@@ -1272,7 +1272,7 @@
displayed as radio buttons and multiple selects as a set of checkboxes
TODO: The following must be fixed to test correctly for the new security_check tag in the DataToolParameter ( the last test below is broken )
- Nate's next passs at the dataset security stuff will dramatically alter this anyway.
+ Nate's next pass at the dataset security stuff will dramatically alter this anyway.
"""
def __init__( self, tool, elem ):
@@ -1522,6 +1522,38 @@
ref = ref()
return ref
+class LibraryDatasetToolParameter( ToolParameter ):
+ """
+ Parameter that lets users select a LDDA from a modal window, then use it within the wrapper.
+ """
+
+ def __init__( self, tool, elem ):
+ ToolParameter.__init__( self, tool, elem )
+
+ def get_html_field( self, trans=None, value=None, other_values={} ):
+ return form_builder.LibraryField( self.name, value=value, trans=trans )
+
+ def get_initial_value( self, trans, context ):
+ return None
+
+ def from_html( self, value, trans, other_values={} ):
+ if not value:
+ return None
+ elif isinstance( value, trans.app.model.LibraryDatasetDatasetAssociation ):
+ return value
+ else:
+ return trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( value ) )
+
+ def to_string( self, value, app ):
+ if not value:
+ return None
+ return value.id
+
+ def to_python( self, value, app ):
+ if not value:
+ return value
+ return app.model.context.query( app.model.LibraryDatasetDatasetAssociation ).get( value )
+
# class RawToolParameter( ToolParameter ):
# """
# Completely nondescript parameter, HTML representation is provided as text
@@ -1570,19 +1602,20 @@
# self.html = form_builder.HiddenField( self.name, trans.history.id ).get_html()
# return self.html
-parameter_types = dict( text = TextToolParameter,
- integer = IntegerToolParameter,
- float = FloatToolParameter,
- boolean = BooleanToolParameter,
- genomebuild = GenomeBuildParameter,
- select = SelectToolParameter,
- data_column = ColumnListParameter,
- hidden = HiddenToolParameter,
- baseurl = BaseURLToolParameter,
- file = FileToolParameter,
- ftpfile = FTPFileToolParameter,
- data = DataToolParameter,
- drill_down = DrillDownSelectToolParameter )
+parameter_types = dict( text = TextToolParameter,
+ integer = IntegerToolParameter,
+ float = FloatToolParameter,
+ boolean = BooleanToolParameter,
+ genomebuild = GenomeBuildParameter,
+ select = SelectToolParameter,
+ data_column = ColumnListParameter,
+ hidden = HiddenToolParameter,
+ baseurl = BaseURLToolParameter,
+ file = FileToolParameter,
+ ftpfile = FTPFileToolParameter,
+ data = DataToolParameter,
+ library_data = LibraryDatasetToolParameter,
+ drill_down = DrillDownSelectToolParameter )
class UnvalidatedValue( object ):
"""
--- a/lib/galaxy/web/form_builder.py Mon Jul 18 15:02:37 2011 -0400
+++ b/lib/galaxy/web/form_builder.py Mon Jul 18 21:56:23 2011 -0400
@@ -652,6 +652,27 @@
return self.value
else:
return '-'
+
+class LibraryField( BaseField ):
+ def __init__( self, name, value=None, trans=None ):
+ self.name = name
+ self.ldda = value
+ self.trans = trans
+ def get_html( self, disabled=False ):
+ if not self.ldda:
+ ldda = ""
+ text = "Choose a library dataset"
+ else:
+ ldda = self.trans.security.encode_id(self.ldda.id)
+ text = self.ldda.name
+ return '<a href="javascript:void(0);" class="add-librarydataset">%s</a> \
+ <input type="hidden" name="%s" value="%s">' % ( text, self.name, escape( str(ldda), quote=True ) )
+
+ def get_display_text(self):
+ if self.ldda:
+ return self.ldda.name
+ else:
+ return 'None'
def get_suite():
"""Get unittest suite for this module"""
--- a/static/scripts/galaxy.base.js Mon Jul 18 15:02:37 2011 -0400
+++ b/static/scripts/galaxy.base.js Mon Jul 18 21:56:23 2011 -0400
@@ -725,4 +725,5 @@
}
return anchor;
});
+
});
--- a/static/scripts/galaxy.panels.js Mon Jul 18 15:02:37 2011 -0400
+++ b/static/scripts/galaxy.panels.js Mon Jul 18 21:56:23 2011 -0400
@@ -214,7 +214,7 @@
init_fn();
}
};
-
+
function show_in_overlay( options ) {
var width = options.width || '600';
var height = options.height || '400';
@@ -226,9 +226,9 @@
show_modal( null, $( "<div style='margin: -5px;'><img id='close_button' style='position:absolute;right:-17px;top:-15px;src='" + image_path + "/closebox.png'><iframe style='margin: 0; padding: 0;' src='" + options.url + "' width='" + width + "' height='" + height + "' scrolling='" + scroll + "' frameborder='0'></iframe></div>" ) );
$("#close_button").bind( "click", function() { hide_modal(); } );
}
-
+
// Tab management
-
+
$(function() {
$(".tab").each( function() {
var submenu = $(this).children( ".submenu" );
--- a/templates/base.mako Mon Jul 18 15:02:37 2011 -0400
+++ b/templates/base.mako Mon Jul 18 21:56:23 2011 -0400
@@ -1,15 +1,13 @@
<% _=n_ %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
-
-<head>
-<title>${self.title()}</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-${self.metas()}
-${self.stylesheets()}
-${self.javascripts()}
-</head>
-
+ <head>
+ <title>${self.title()}</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ ${self.metas()}
+ ${self.stylesheets()}
+ ${self.javascripts()}
+ </head><body>
${next.body()}
</body>
--- a/templates/base_panels.mako Mon Jul 18 15:02:37 2011 -0400
+++ b/templates/base_panels.mako Mon Jul 18 21:56:23 2011 -0400
@@ -155,13 +155,13 @@
## Override
</%def>
-<%def name="overlay( title='', content='' )">
+<%def name="overlay( title='', content='', visible=False )"><%def name="title()"></%def><%def name="content()"></%def><div id="overlay"
- %if not self.overlay_visible:
- style="display: none;"
+ %if not visible:
+ style="display: none;"
%endif
>
##
@@ -169,21 +169,21 @@
## Need a table here for centering in IE6
<table class="dialog-box-container" border="0" cellpadding="0" cellspacing="0"
- %if not self.overlay_visible:
+ %if not visible:
style="display: none;"
%endif
><tr><td><div class="dialog-box-wrapper"><div class="dialog-box">
- <div class="unified-panel-header">
- <div class="unified-panel-header-inner"><span class='title'>${title}</span></div>
- </div>
- <div class="body">${content}</div>
- <div>
- <div class="buttons" style="display: none; float: right;"></div>
- <div class="extra_buttons" style="display: none; padding: 5px;"></div>
- <div style="clear: both;"></div>
- </div>
+ <div class="unified-panel-header">
+ <div class="unified-panel-header-inner"><span class='title'>${title}</span></div>
+ </div>
+ <div class="body">${content}</div>
+ <div>
+ <div class="buttons" style="display: none; float: right;"></div>
+ <div class="extra_buttons" style="display: none; padding: 5px;"></div>
+ <div style="clear: both;"></div>
+ </div></div></div></td></tr></table>
@@ -198,45 +198,45 @@
<html>
${self.init()}
<head>
- <title>${self.title()}</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <meta name = "viewport" content = "maximum-scale=1.0">
- ${self.stylesheets()}
- ${self.javascripts()}
+ <title>${self.title()}</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta name = "viewport" content = "maximum-scale=1.0">
+ ${self.stylesheets()}
+ ${self.javascripts()}
</head><body scroll="no" class="${self.body_class}">
- <div id="everything" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; min-width: 600px;">
- ## Background displays first
- <div id="background"></div>
- ## Layer iframes over backgrounds
- <div id="masthead">
- ${self.masthead()}
- </div>
- <div id="messagebox" class="panel-${self.message_box_class}-message">
- %if self.message_box_visible:
- ${self.message_box_content()}
+ <div id="everything" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; min-width: 600px;">
+ ## Background displays first
+ <div id="background"></div>
+ ## Layer iframes over backgrounds
+ <div id="masthead">
+ ${self.masthead()}
+ </div>
+ <div id="messagebox" class="panel-${self.message_box_class}-message">
+ %if self.message_box_visible:
+ ${self.message_box_content()}
+ %endif
+ </div>
+ ${self.overlay(visible=self.overlay_visible)}
+ %if self.has_left_panel:
+ <div id="left">
+ ${self.left_panel()}
+ </div>
+ <div id="left-border">
+ <div id="left-border-inner" style="display: none;"></div>
+ </div>
+ %endif
+ <div id="center">
+ ${self.center_panel()}
+ </div>
+ %if self.has_right_panel:
+ <div id="right-border"><div id="right-border-inner" style="display: none;"></div></div>
+ <div id="right">
+ ${self.right_panel()}
+ </div>
%endif
</div>
- ${self.overlay()}
- %if self.has_left_panel:
- <div id="left">
- ${self.left_panel()}
- </div>
- <div id="left-border">
- <div id="left-border-inner" style="display: none;"></div>
- </div>
- %endif
- <div id="center">
- ${self.center_panel()}
- </div>
- %if self.has_right_panel:
- <div id="right-border"><div id="right-border-inner" style="display: none;"></div></div>
- <div id="right">
- ${self.right_panel()}
- </div>
- %endif
- </div>
## Allow other body level elements
</body>
## Scripts can be loaded later since they progressively add features to
--- a/templates/root/index.mako Mon Jul 18 15:02:37 2011 -0400
+++ b/templates/root/index.mako Mon Jul 18 21:56:23 2011 -0400
@@ -174,14 +174,14 @@
<%def name="init()"><%
- if trans.app.config.cloud_controller_instance:
- self.has_left_panel=False
- self.has_right_panel=False
- self.active_view="cloud"
- else:
- self.has_left_panel=True
- self.has_right_panel=True
- self.active_view="analysis"
+ if trans.app.config.cloud_controller_instance:
+ self.has_left_panel=False
+ self.has_right_panel=False
+ self.active_view="cloud"
+ else:
+ self.has_left_panel=True
+ self.has_right_panel=True
+ self.active_view="analysis"
%>
%if trans.app.config.require_login and not trans.user:
<script type="text/javascript">
@@ -219,7 +219,7 @@
elif m_c is not None:
center_url = h.url_for( controller=m_c, action=m_a )
elif trans.app.config.cloud_controller_instance:
- center_url = h.url_for( controller='cloud', action='list' )
+ center_url = h.url_for( controller='cloud', action='list' )
else:
center_url = h.url_for( '/static/welcome.html' )
%>
--- a/templates/tool_form.mako Mon Jul 18 15:02:37 2011 -0400
+++ b/templates/tool_form.mako Mon Jul 18 21:56:23 2011 -0400
@@ -1,203 +1,230 @@
-<!-- -->
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<%inherit file="/base.mako"/>
+<%namespace file="/base_panels.mako" import="overlay" />
-<%
-from galaxy.util.expressions import ExpressionContext
-%>
+<%def name="stylesheets()">
+ ${h.css( "autocomplete_tagging", "panel_layout", "base", "library" )}
+</%def>
-<html>
+<%def name="javascripts()">
+ ${h.js( "jquery", "galaxy.panels", "galaxy.base", "jquery.autocomplete", "jstorage" )}
+ <script type="text/javascript">
+ $(function() {
+ $(window).bind("refresh_on_change", function() {
+ $(':file').each( function() {
+ var file = $(this);
+ var file_value = file.val();
+ if (file_value) {
+ // disable file input, since we don't want to upload the file on refresh
+ var file_name = $(this).attr("name");
+ file.attr( { name: 'replaced_file_input_' + file_name, disabled: true } );
+ // create a new hidden field which stores the filename and has the original name of the file input
+ var new_file_input = $(document.createElement('input'));
+ new_file_input.attr( { "type": "hidden", "value": file_value, "name": file_name } );
+ file.after(new_file_input);
+ }
+ });
+ });
-<head>
-<title>Galaxy</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-${h.css( "base", "autocomplete_tagging" )}
-${h.js( "jquery", "galaxy.base", "jquery.autocomplete" )}
-<script type="text/javascript">
-$(function() {
- $(window).bind("refresh_on_change", function() {
- $(':file').each( function() {
- var file = $(this);
- var file_value = file.val();
- if (file_value) {
- // disable file input, since we don't want to upload the file on refresh
- var file_name = $(this).attr("name");
- file.attr( { name: 'replaced_file_input_' + file_name, disabled: true } );
- // create a new hidden field which stores the filename and has the original name of the file input
- var new_file_input = $(document.createElement('input'));
- new_file_input.attr( { "type": "hidden", "value": file_value, "name": file_name } );
- file.after(new_file_input);
+ // For drilldown parameters: add expand/collapse buttons and collapse initially-collapsed elements
+ $( 'li ul.toolParameterExpandableCollapsable' ).each( function() {
+ var el = $(this),
+ parent_li = el.parent('li'),
+ sub_ul = el.remove();
+
+ parent_li.find( 'span' ).wrapInner( '<a/>' ).find( 'a' ).click( function() {
+ sub_ul.toggle();
+ (this).html( sub_ul.is(":hidden") ? '[+]' : '[-]' );
+ });
+ parent_li.append( sub_ul );
+ });
+
+ $( 'ul ul.toolParameterExpandableCollapsable' ).each( function(i) {
+ var el = $(this);
+ if (el.attr("default_state") === "collapsed") {
+ el.hide();
}
});
+
+ function checkUncheckAll( name, check ) {
+ $("input[name='" + name + "'][type='checkbox']").attr('checked', !!check);
+ }
+
+ // Inserts the Select All / Unselect All buttons for checkboxes
+ $("div.checkUncheckAllPlaceholder").each( function() {
+ var check_name = $(this).attr("checkbox_name");
+ select_link = $("<a class='action-button'></a>").text("Select All").click(function() {
+ checkUncheckAll(check_name, true);
+ });
+ unselect_link = $("<a class='action-button'></a>").text("Unselect All").click(function() {
+ checkUncheckAll(check_name, false);
+ });
+ $(this).append(select_link).append(" ").append(unselect_link);
+ });
+
+ $(".add-librarydataset").live("click", function() {
+ var link = $(this);
+ $.ajax({
+ url: "/tracks/list_libraries",
+ error: function(xhr, ajaxOptions, thrownError) { alert( "Grid failed" ); console.log(xhr, ajaxOptions, thrownError); },
+ success: function(table_html) {
+ show_modal(
+ "Select Library Dataset",
+ table_html, {
+ "Cancel": function() {
+ hide_modal();
+ },
+ "Select": function() {
+ $('input[name=ldda_ids]:checked').each(function() {
+ var name = $.trim( $(this).siblings("div").find("a").text() );
+ var id = $(this).val();
+ link.text(name);
+ link.siblings("input[type=hidden]").val(id);
+ });
+ hide_modal();
+ }
+ }
+ );
+ }
+ });
+ });
});
-
- // For drilldown parameters: add expand/collapse buttons and collapse initially-collapsed elements
- $( 'li ul.toolParameterExpandableCollapsable' ).each( function() {
- var el = $(this),
- parent_li = el.parent('li'),
- sub_ul = el.remove();
-
- parent_li.find( 'span' ).wrapInner( '<a/>' ).find( 'a' ).click( function() {
- sub_ul.toggle();
- (this).html( sub_ul.is(":hidden") ? '[+]' : '[-]' );
- });
- parent_li.append( sub_ul );
- });
-
- $( 'ul ul.toolParameterExpandableCollapsable' ).each( function(i) {
- var el = $(this);
- if (el.attr("default_state") === "collapsed") {
- el.hide();
+
+ %if not add_frame.debug:
+ if( window.name != "galaxy_main" ) {
+ location.replace( '${h.url_for( controller='root', action='index', tool_id=tool.id )}' );
}
- });
-
- function checkUncheckAll( name, check ) {
- $("input[name='" + name + "'][type='checkbox']").attr('checked', !!check);
- }
-
- // Inserts the Select All / Unselect All buttons for checkboxes
- $("div.checkUncheckAllPlaceholder").each( function() {
- var check_name = $(this).attr("checkbox_name");
- select_link = $("<a class='action-button'></a>").text("Select All").click(function() {
- checkUncheckAll(check_name, true);
- });
- unselect_link = $("<a class='action-button'></a>").text("Unselect All").click(function() {
- checkUncheckAll(check_name, false);
- });
- $(this).append(select_link).append(" ").append(unselect_link);
- });
-});
+ %endif
-%if not add_frame.debug:
- if( window.name != "galaxy_main" ) {
- location.replace( '${h.url_for( controller='root', action='index', tool_id=tool.id )}' );
- }
-%endif
+ </script>
-</script>
-</head>
+</%def>
-<body>
- <%def name="do_inputs( inputs, tool_state, errors, prefix, other_values=None )">
- <% other_values = ExpressionContext( tool_state, other_values ) %>
- %for input_index, input in enumerate( inputs.itervalues() ):
- %if not input.visible:
- <% pass %>
- %elif input.type == "repeat":
- <div class="repeat-group">
- <div class="form-title-row"><b>${input.title_plural}</b></div>
- <% repeat_state = tool_state[input.name] %>
- %for i in range( len( repeat_state ) ):
- <div class="repeat-group-item">
- <%
- if input.name in errors:
- rep_errors = errors[input.name][i]
- else:
- rep_errors = dict()
- index = repeat_state[i]['__index__']
- %>
- <div class="form-title-row"><b>${input.title} ${i + 1}</b></div>
- ${do_inputs( input.inputs, repeat_state[i], rep_errors, prefix + input.name + "_" + str(index) + "|", other_values )}
- <div class="form-row"><input type="submit" name="${prefix}${input.name}_${index}_remove" value="Remove ${input.title} ${i+1}"></div>
- </div>
- %if rep_errors.has_key( '__index__' ):
- <div><img style="vertical-align: middle;" src="${h.url_for('/static/style/error_small.png')}"> <span style="vertical-align: middle;">${rep_errors['__index__']}</span></div>
- %endif
- %endfor
- <div class="form-row"><input type="submit" name="${prefix}${input.name}_add" value="Add new ${input.title}"></div>
- </div>
- %elif input.type == "conditional":
- <%
- group_state = tool_state[input.name]
- group_errors = errors.get( input.name, {} )
- current_case = group_state['__current_case__']
- group_prefix = prefix + input.name + "|"
- %>
- %if input.value_ref_in_group:
- ${row_for_param( group_prefix, input.test_param, group_state, group_errors, other_values )}
- %endif
- ${do_inputs( input.cases[current_case].inputs, group_state, group_errors, group_prefix, other_values )}
- %elif input.type == "upload_dataset":
- %if input.get_datatype( trans, other_values ).composite_type is None: #have non-composite upload appear as before
+<%def name="do_inputs( inputs, tool_state, errors, prefix, other_values=None )">
+ <%
+ from galaxy.util.expressions import ExpressionContext
+ other_values = ExpressionContext( tool_state, other_values )
+ %>
+ %for input_index, input in enumerate( inputs.itervalues() ):
+ %if not input.visible:
+ <% pass %>
+ %elif input.type == "repeat":
+ <div class="repeat-group">
+ <div class="form-title-row"><strong>${input.title_plural}</strong></div>
+ <% repeat_state = tool_state[input.name] %>
+ %for i in range( len( repeat_state ) ):
+ <div class="repeat-group-item"><%
if input.name in errors:
- rep_errors = errors[input.name][0]
+ rep_errors = errors[input.name][i]
else:
rep_errors = dict()
+ index = repeat_state[i]['__index__']
%>
- ${do_inputs( input.inputs, tool_state[input.name][0], rep_errors, prefix + input.name + "_" + str( 0 ) + "|", other_values )}
- %else:
- <div class="repeat-group">
- <div class="form-title-row"><b>${input.group_title( other_values )}</b></div>
- <%
- repeat_state = tool_state[input.name]
- %>
- %for i in range( len( repeat_state ) ):
- <div class="repeat-group-item">
- <%
- if input.name in errors:
- rep_errors = errors[input.name][i]
- else:
- rep_errors = dict()
- index = repeat_state[i]['__index__']
- %>
- <div class="form-title-row"><b>File Contents for ${input.title_by_index( trans, i, other_values )}</b></div>
- ${do_inputs( input.inputs, repeat_state[i], rep_errors, prefix + input.name + "_" + str(index) + "|", other_values )}
- ##<div class="form-row"><input type="submit" name="${prefix}${input.name}_${index}_remove" value="Remove ${input.title} ${i+1}"></div>
- </div>
- %endfor
- ##<div class="form-row"><input type="submit" name="${prefix}${input.name}_add" value="Add new ${input.title}"></div>
- </div>
+ <div class="form-title-row"><strong>${input.title} ${i + 1}</strong></div>
+ ${do_inputs( input.inputs, repeat_state[i], rep_errors, prefix + input.name + "_" + str(index) + "|", other_values )}
+ <div class="form-row"><input type="submit" name="${prefix}${input.name}_${index}_remove" value="Remove ${input.title} ${i+1}"></div>
+ </div>
+ %if rep_errors.has_key( '__index__' ):
+ <div><img style="vertical-align: middle;" src="${h.url_for('/static/style/error_small.png')}"> <span style="vertical-align: middle;">${rep_errors['__index__']}</span></div>
%endif
+ %endfor
+ <div class="form-row"><input type="submit" name="${prefix}${input.name}_add" value="Add new ${input.title}"></div>
+ </div>
+ %elif input.type == "conditional":
+ <%
+ group_state = tool_state[input.name]
+ group_errors = errors.get( input.name, {} )
+ current_case = group_state['__current_case__']
+ group_prefix = prefix + input.name + "|"
+ %>
+ %if input.value_ref_in_group:
+ ${row_for_param( group_prefix, input.test_param, group_state, group_errors, other_values )}
+ %endif
+ ${do_inputs( input.cases[current_case].inputs, group_state, group_errors, group_prefix, other_values )}
+ %elif input.type == "upload_dataset":
+ %if input.get_datatype( trans, other_values ).composite_type is None: #have non-composite upload appear as before
+ <%
+ if input.name in errors:
+ rep_errors = errors[input.name][0]
+ else:
+ rep_errors = dict()
+ %>
+ ${do_inputs( input.inputs, tool_state[input.name][0], rep_errors, prefix + input.name + "_" + str( 0 ) + "|", other_values )}
%else:
- ${row_for_param( prefix, input, tool_state, errors, other_values )}
- %endif
- %endfor
- </%def>
-
- <%def name="row_for_param( prefix, param, parent_state, parent_errors, other_values )">
- <%
- if parent_errors.has_key( param.name ):
- cls = "form-row form-row-error"
- else:
- cls = "form-row"
-
- label = param.get_label()
-
- field = param.get_html_field( trans, parent_state[ param.name ], other_values )
- field.refresh_on_change = param.refresh_on_change
-
- # Field may contain characters submitted by user and these characters may be unicode; handle non-ascii characters gracefully.
- field_html = field.get_html( prefix )
- if type( field_html ) is not unicode:
- field_html = unicode( field_html, 'utf-8' )
-
- if param.type == "hidden":
- return field_html
- %>
- <div class="${cls}">
- %if label:
- <label for="${param.name}">${label}:</label>
- %endif
- <div class="form-row-input">${field_html}</div>
- %if parent_errors.has_key( param.name ):
- <div class="form-row-error-message">
- <div><img style="vertical-align: middle;" src="${h.url_for('/static/style/error_small.png')}"> <span style="vertical-align: middle;">${parent_errors[param.name]}</span></div>
+ <div class="repeat-group">
+ <div class="form-title-row"><strong>${input.group_title( other_values )}</strong></div>
+ <%
+ repeat_state = tool_state[input.name]
+ %>
+ %for i in range( len( repeat_state ) ):
+ <div class="repeat-group-item">
+ <%
+ if input.name in errors:
+ rep_errors = errors[input.name][i]
+ else:
+ rep_errors = dict()
+ index = repeat_state[i]['__index__']
+ %>
+ <div class="form-title-row"><strong>File Contents for ${input.title_by_index( trans, i, other_values )}</strong></div>
+ ${do_inputs( input.inputs, repeat_state[i], rep_errors, prefix + input.name + "_" + str(index) + "|", other_values )}
+ ##<div class="form-row"><input type="submit" name="${prefix}${input.name}_${index}_remove" value="Remove ${input.title} ${i+1}"></div>
+ </div>
+ %endfor
+ ##<div class="form-row"><input type="submit" name="${prefix}${input.name}_add" value="Add new ${input.title}"></div></div>
%endif
-
- %if param.help:
- <div class="toolParamHelp" style="clear: both;">
- ${param.help}
- </div>
- %endif
-
- <div style="clear: both"></div>
-
- </div>
- </%def>
-
- %if add_frame.from_noframe:
- <div class="warningmessage">
+ %else:
+ ${row_for_param( prefix, input, tool_state, errors, other_values )}
+ %endif
+ %endfor
+</%def>
+
+<%def name="row_for_param( prefix, param, parent_state, parent_errors, other_values )">
+ <%
+ if parent_errors.has_key( param.name ):
+ cls = "form-row form-row-error"
+ else:
+ cls = "form-row"
+
+ label = param.get_label()
+
+ field = param.get_html_field( trans, parent_state[ param.name ], other_values )
+ field.refresh_on_change = param.refresh_on_change
+
+ # Field may contain characters submitted by user and these characters may be unicode; handle non-ascii characters gracefully.
+ field_html = field.get_html( prefix )
+ if type( field_html ) is not unicode:
+ field_html = unicode( field_html, 'utf-8' )
+
+ if param.type == "hidden":
+ return field_html
+ %>
+ <div class="${cls}">
+ %if label:
+ <label for="${param.name}">${label}:</label>
+ %endif
+ <div class="form-row-input">${field_html}</div>
+ %if parent_errors.has_key( param.name ):
+ <div class="form-row-error-message">
+ <div><img style="vertical-align: middle;" src="${h.url_for('/static/style/error_small.png')}"> <span style="vertical-align: middle;">${parent_errors[param.name]}</span></div>
+ </div>
+ %endif
+
+ %if param.help:
+ <div class="toolParamHelp" style="clear: both;">
+ ${param.help}
+ </div>
+ %endif
+
+ <div style="clear: both;"></div>
+
+ </div>
+</%def>
+
+<% overlay(visible=False) %>
+
+%if add_frame.from_noframe:
+ <div class="warningmessage"><strong>Welcome to Galaxy</strong><hr/>
It appears that you found this tool from a link outside of Galaxy.
@@ -205,60 +232,59 @@
<a href="${h.url_for( controller='root' )}" target="_top">welcome page</a>.
To learn more about what Galaxy is and what it can do for you, please visit
the <a href="$add_frame.wiki_url" target="_top">Galaxy wiki</a>.
- </div>
- <br/>
+ </div>
+ <br/>
+%endif
+
+## handle calculating the redict url for the special case where we have nginx proxy
+## upload and need to do url_for on the redirect portion of the tool action
+<%
+ try:
+ tool_url = h.url_for(tool.action)
+ except AttributeError:
+ assert len(tool.action) == 2
+ tool_url = tool.action[0] + h.url_for(tool.action[1])
+%>
+<div class="toolForm" id="${tool.id}">
+ %if tool.has_multiple_pages:
+ <div class="toolFormTitle">${tool.name} (step ${tool_state.page+1} of ${tool.npages})</div>
+ %else:
+ <div class="toolFormTitle">${tool.name}</div>
%endif
-
- ## handle calculating the redict url for the special case where we have nginx proxy
- ## upload and need to do url_for on the redirect portion of the tool action
- <%
- try:
- tool_url = h.url_for(tool.action)
- except AttributeError:
- assert len(tool.action) == 2
- tool_url = tool.action[0] + h.url_for(tool.action[1])
- %><div class="toolForm" id="${tool.id}">
- %if tool.has_multiple_pages:
- <div class="toolFormTitle">${tool.name} (step ${tool_state.page+1} of ${tool.npages})</div>
- %else:
- <div class="toolFormTitle">${tool.name}</div>
- %endif
- <div class="toolFormBody">
- <form id="tool_form" name="tool_form" action="${tool_url}" enctype="${tool.enctype}" target="${tool.target}" method="${tool.method}">
- <input type="hidden" name="tool_id" value="${tool.id}">
- <input type="hidden" name="tool_state" value="${util.object_to_string( tool_state.encode( tool, app ) )}">
- %if tool.display_by_page[tool_state.page]:
- ${trans.fill_template_string( tool.display_by_page[tool_state.page], context=tool.get_param_html_map( trans, tool_state.page, tool_state.inputs ) )}
- <input type="submit" class="primary-button" name="runtool_btn" value="Execute">
- %else:
- ${do_inputs( tool.inputs_by_page[ tool_state.page ], tool_state.inputs, errors, "" )}
- <div class="form-row">
- %if tool_state.page == tool.last_page:
- <input type="submit" class="primary-button" name="runtool_btn" value="Execute">
- %else:
- <input type="submit" class="primary-button" name="runtool_btn" value="Next step">
- %endif
- </div>
- %endif
- </form>
+ <div class="toolFormBody">
+ <form id="tool_form" name="tool_form" action="${tool_url}" enctype="${tool.enctype}" target="${tool.target}" method="${tool.method}">
+ <input type="hidden" name="tool_id" value="${tool.id}">
+ <input type="hidden" name="tool_state" value="${util.object_to_string( tool_state.encode( tool, app ) )}">
+ %if tool.display_by_page[tool_state.page]:
+ ${trans.fill_template_string( tool.display_by_page[tool_state.page], context=tool.get_param_html_map( trans, tool_state.page, tool_state.inputs ) )}
+ <input type="submit" class="primary-button" name="runtool_btn" value="Execute">
+ %else:
+ ${do_inputs( tool.inputs_by_page[ tool_state.page ], tool_state.inputs, errors, "" )}
+ <div class="form-row">
+ %if tool_state.page == tool.last_page:
+ <input type="submit" class="primary-button" name="runtool_btn" value="Execute">
+ %else:
+ <input type="submit" class="primary-button" name="runtool_btn" value="Next step">
+ %endif
+ </div>
+ %endif
+ </form>
+ </div>
+</div>
+%if tool.help:
+ <div class="toolHelp">
+ <div class="toolHelpBody">
+ <%
+ if tool.has_multiple_pages:
+ tool_help = tool.help_by_page[tool_state.page]
+ else:
+ tool_help = tool.help
+
+ # Convert to unicode to display non-ascii characters.
+ if type( tool_help ) is not unicode:
+ tool_help = unicode( tool_help, 'utf-8')
+ %>
+ ${tool_help}
</div></div>
- %if tool.help:
- <div class="toolHelp">
- <div class="toolHelpBody">
- <%
- if tool.has_multiple_pages:
- tool_help = tool.help_by_page[tool_state.page]
- else:
- tool_help = tool.help
-
- # Convert to unicode to display non-ascii characters.
- if type( tool_help ) is not unicode:
- tool_help = unicode( tool_help, 'utf-8')
- %>
- ${tool_help}
- </div>
- </div>
- %endif
-</body>
-</html>
+%endif
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dannon: Case sensitivity note for login not found error.
by Bitbucket 18 Jul '11
by Bitbucket 18 Jul '11
18 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/8e05f9425723/
changeset: 8e05f9425723
user: dannon
date: 2011-07-18 21:02:37
summary: Case sensitivity note for login not found error.
affected #: 3 files (129 bytes)
--- a/lib/galaxy/web/controllers/mobile.py Mon Jul 18 15:09:49 2011 +0200
+++ b/lib/galaxy/web/controllers/mobile.py Mon Jul 18 15:02:37 2011 -0400
@@ -47,7 +47,7 @@
error = password_error = None
user = trans.sa_session.query( model.User ).filter_by( email = email ).first()
if not user:
- error = "No such user"
+ error = "No such user (please note that login is case sensitive)"
elif user.deleted:
error = "This account has been marked deleted, contact your Galaxy administrator to restore the account."
elif user.external:
--- a/lib/galaxy/web/controllers/user.py Mon Jul 18 15:09:49 2011 +0200
+++ b/lib/galaxy/web/controllers/user.py Mon Jul 18 15:02:37 2011 -0400
@@ -394,7 +394,7 @@
success = False
user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email==email ).first()
if not user:
- message = "No such user"
+ message = "No such user (please note that login is case sensitive)"
status = 'error'
elif user.deleted:
message = "This account has been marked deleted, contact your Galaxy administrator to restore the account."
--- a/scripts/check_galaxy.py Mon Jul 18 15:09:49 2011 +0200
+++ b/scripts/check_galaxy.py Mon Jul 18 15:02:37 2011 -0400
@@ -292,7 +292,7 @@
self.in_span = False
def handle_data(self, data):
if self.in_span:
- if data == "No such user":
+ if data == "No such user (please note that login is case sensitive)":
self.no_user = True
elif data == "Invalid password":
self.bad_pw = True
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Trackster: show 'Add Datasets' button when there are no tracks in a visualization. Refactor and modularize add tracks code so that is can be used in multiple places.
by Bitbucket 18 Jul '11
by Bitbucket 18 Jul '11
18 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/27bac44e93f6/
changeset: 27bac44e93f6
user: jgoecks
date: 2011-07-18 15:09:49
summary: Trackster: show 'Add Datasets' button when there are no tracks in a visualization. Refactor and modularize add tracks code so that is can be used in multiple places.
affected #: 5 files (1.6 KB)
--- a/static/june_2007_style/blue/trackster.css Fri Jul 15 10:33:02 2011 -0400
+++ b/static/june_2007_style/blue/trackster.css Mon Jul 18 15:09:49 2011 +0200
@@ -54,3 +54,5 @@
.icon{display:inline-block;width:16px;height:16px;}
.icon.more-down{background:url('../images/fugue/arrow-transition-270-bw.png') no-repeat 0px 0px;}
.icon.more-across{background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;}
+.intro{padding:1em;}
+.intro>.action-button{background-color:#CCC;padding:1em;}
\ No newline at end of file
--- a/static/june_2007_style/trackster.css.tmpl Fri Jul 15 10:33:02 2011 -0400
+++ b/static/june_2007_style/trackster.css.tmpl Mon Jul 18 15:09:49 2011 +0200
@@ -301,8 +301,14 @@
.icon.more-down {
background:url('../images/fugue/arrow-transition-270-bw.png') no-repeat 0px 0px;
}
-.icon.more-across{
- background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;
+.icon.more-across {
+ background: url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;
+}
+.intro {
+ padding: 1em;
+}
+.intro > .action-button {
+ background-color: #CCC;
+ padding: 1em;
}
-
--- a/static/scripts/packed/trackster.js Fri Jul 15 10:33:02 2011 -0400
+++ b/static/scripts/packed/trackster.js Mon Jul 18 15:09:49 2011 +0200
@@ -1,1 +1,1 @@
-var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var trackster_module=function(f,T){var n=f("class").extend,p=f("slotting"),I=f("painters");var Z=function(aa,ab){this.document=aa;this.default_font=ab!==undefined?ab:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};n(Z.prototype,{load_pattern:function(aa,ae){var ab=this.patterns,ac=this.dummy_context,ad=new Image();ad.src=image_path+ae;ad.onload=function(){ab[aa]=ac.createPattern(ad,"repeat")}},get_pattern:function(aa){return this.patterns[aa]},new_canvas:function(){var aa=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(aa)}aa.manager=this;return aa}});var C=function(aa,ab){aa.bind("drag",{handle:ab,relative:true},function(af,ag){var ae=$(this).parent();var ad=ae.children();var ac;for(ac=0;ac<ad.length;ac++){if(ag.offsetY<$(ad.get(ac)).position().top){break}}if(ac===ad.length){if(this!==ad.get(ac-1)){ae.append(this)}}else{if(this!==ad.get(ac)){$(this).insertBefore(ad.get(ac))}}}).bind("dragstart",function(){$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css("border","0px")})};T.sortable=C;var D=9,A=18,O=D+2,w=100,F=12000,M=200,z=5,s=10,H=5000,t=100,m="There was an error in indexing this dataset. ",G="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",q="Currently indexing... please wait",v="Tool cannot be rerun: ",a="Loading data...",U="Ready for display",d=10,r=5,y=5;function u(aa){return Math.round(aa*1000)/1000}var c=function(aa){this.num_elements=aa;this.clear()};n(c.prototype,{get:function(ab){var aa=this.key_ary.indexOf(ab);if(aa!==-1){if(this.obj_cache[ab].stale){this.key_ary.splice(aa,1);delete this.obj_cache[ab]}else{this.move_key_to_end(ab,aa)}}return this.obj_cache[ab]},set:function(ab,ac){if(!this.obj_cache[ab]){if(this.key_ary.length>=this.num_elements){var aa=this.key_ary.shift();delete this.obj_cache[aa]}this.key_ary.push(ab)}this.obj_cache[ab]=ac;return ac},move_key_to_end:function(ab,aa){this.key_ary.splice(aa,1);this.key_ary.push(ab)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var N=function(ab,aa,ac){c.call(this,ab);this.track=aa;this.subset=(ac!==undefined?ac:true)};n(N.prototype,c.prototype,{load_data:function(aj,ae,ab,ag){var ai=this.track.view.chrom,ah=this.track.mode,ad={chrom:ai,low:aj,high:ae,mode:ah,resolution:ab,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ad,ag);if(this.track.filters_manager){var ak=[];var aa=this.track.filters_manager.filters;for(var af=0;af<aa.length;af++){ak[ak.length]=aa[af].name}ad.filter_cols=JSON.stringify(ak)}var ac=this;return $.getJSON(this.track.data_url,ad,function(al){ac.set_data(aj,ae,ah,al)})},get_data:function(aa,ae,ab,ad){var af=this.track.mode,ac=this.get_data_from_cache(aa,ae,af);if(ac){return ac}ac=this.load_data(aa,ae,ab,ad);this.set_data(aa,ae,af,ac);return ac},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ah,ac,ab,af,ad){var ag=this.track.mode,ai=this.get_data_from_cache(ah,ac,ag);if(!ai){console.log("ERROR: no current data for: ",this.track,ah,ac,ab,af);return}ai.stale=true;if(ad===this.DEEP_DATA_REQ){$.extend(af,{start_val:ai.data.length+1})}else{if(ad===this.BROAD_DATA_REQ){ah=ai.data[ai.length-1][2]+1}}var aa=this,ae=this.load_data(ah,ac,ab,af);new_data_available=$.Deferred();this.set_data(ah,ac,ag,new_data_available);$.when(ae).then(function(aj){if(aj.data){aj.data=ai.data.concat(aj.data)}aa.set_data(ah,ac,ag,aj);new_data_available.resolve(aj)});return new_data_available},get_data_from_cache:function(aa,ab,ac){return this.get(this.gen_key(aa,ab,ac))},set_data:function(ab,ac,ad,aa){return this.set(this.gen_key(ab,ac,ad),aa)},gen_key:function(aa,ac,ad){var ab=aa+"_"+ac+"_"+ad;return ab},split_key:function(aa){return aa.split("_")}});var E=function(ab,aa,ac){N.call(this,ab,aa,ac)};n(E.prototype,N.prototype,c.prototype,{load_data:function(ac,aa,ae,af,ab,ad){if(ab>1){return}return N.prototype.load_data.call(this,ac,aa,ae,af,ab,ad)}});var Y=function(aa,ad,ac,ab,ae){this.container=aa;this.chrom=null;this.vis_id=ac;this.dbkey=ab;this.title=ad;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(ae);this.canvas_manager=new Z(aa.get(0).ownerDocument);this.reset()};n(Y.prototype,{init:function(ad){var ac=this.container,aa=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ac);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ac);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ac);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ab=function(ae){if(ae.type==="focusout"||(ae.keyCode||ae.which)===13||(ae.keyCode||ae.which)===27){if((ae.keyCode||ae.which)!==27){aa.go_to($(this).val())}$(this).hide();$(this).val("");aa.location_span.show();aa.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ab).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){aa.location_span.hide();aa.chrom_select.hide();aa.nav_input.val(aa.chrom+":"+aa.low+"-"+aa.high);aa.nav_input.css("display","inline-block");aa.nav_input.select();aa.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){aa.zoom_out();aa.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){aa.zoom_in();aa.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},ad);this.chrom_select.bind("change",function(){aa.change_chrom(aa.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(ae){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(ae){aa.zoom_in(ae.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ae,af){this.current_x=af.offsetX}).bind("drag",function(ae,ag){var ah=ag.offsetX-this.current_x;this.current_x=ag.offsetX;var af=Math.round(ah/aa.viewport_container.width()*(aa.max_high-aa.max_low));aa.move_delta(-af)});this.overview_close.bind("click",function(){for(var af=0,ae=aa.tracks.length;af<ae;af++){aa.tracks[af].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",aa.overview_box.height());aa.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(ae,af){if(ae.clientX>aa.viewport_container.width()-16){return false}}).bind("dragstart",function(ae,af){af.original_low=aa.low;af.current_height=ae.clientY;af.current_x=af.offsetX}).bind("drag",function(ag,ai){var ae=$(this);var aj=ai.offsetX-ai.current_x;var af=ae.scrollTop()-(ag.clientY-ai.current_height);ae.scrollTop(af);ai.current_height=ag.clientY;ai.current_x=ai.offsetX;var ah=Math.round(aj/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}).bind("mousewheel",function(ag,ai,af,ae){if(af){var ah=Math.round(-af/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ah)}});this.top_labeltrack.bind("dragstart",function(ae,af){return $("<div />").css({height:aa.content_div.height()+aa.top_labeltrack.height()+aa.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ai,aj){$(aj.proxy).css({left:Math.min(ai.pageX,aj.startX),width:Math.abs(ai.pageX-aj.startX)});var af=Math.min(ai.pageX,aj.startX)-aa.container.offset().left,ae=Math.max(ai.pageX,aj.startX)-aa.container.offset().left,ah=(aa.high-aa.low),ag=aa.viewport_container.width();aa.update_location(Math.round(af/ag*ah)+aa.low,Math.round(ae/ag*ah)+aa.low)}).bind("dragend",function(aj,ak){var af=Math.min(aj.pageX,ak.startX),ae=Math.max(aj.pageX,ak.startX),ah=(aa.high-aa.low),ag=aa.viewport_container.width(),ai=aa.low;aa.low=Math.round(af/ag*ah)+ai;aa.high=Math.round(ae/ag*ah)+ai;$(ak.proxy).remove();aa.redraw()});this.add_label_track(new X(this,this.top_labeltrack));this.add_label_track(new X(this,this.nav_labeltrack));$(window).bind("resize",function(){aa.resize_window()});$(document).bind("redraw",function(){aa.redraw()});this.reset();$(window).trigger("resize")},update_location:function(aa,ab){this.location_span.text(commatize(aa)+" - "+commatize(ab));this.nav_input.val(this.chrom+":"+commatize(aa)+"-"+commatize(ab))},load_chroms:function(ab,ac){ab.num=t;$.extend(ab,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var aa=this;$.ajax({url:chrom_url,data:ab,dataType:"json",success:function(ae){if(ae.chrom_info.length===0){alert("Invalid chromosome: "+ab.chrom);return}if(ae.reference){aa.add_label_track(new x(aa))}aa.chrom_data=ae.chrom_info;var ah='<option value="">Select Chrom/Contig</option>';for(var ag=0,ad=aa.chrom_data.length;ag<ad;ag++){var af=aa.chrom_data[ag].chrom;ah+='<option value="'+af+'">'+af+"</option>"}if(ae.prev_chroms){ah+='<option value="previous">Previous '+t+"</option>"}if(ae.next_chroms){ah+='<option value="next">Next '+t+"</option>"}aa.chrom_select.html(ah);if(ac){ac()}aa.chrom_start_index=ae.start_index},error:function(){alert("Could not load chroms for this dbkey:",aa.dbkey)}})},change_chrom:function(ae,ab,ag){if(!ae||ae==="None"){return}var ad=this;if(ae==="previous"){ad.load_chroms({low:this.chrom_start_index-t});return}if(ae==="next"){ad.load_chroms({low:this.chrom_start_index+t});return}var af=$.grep(ad.chrom_data,function(ai,aj){return ai.chrom===ae})[0];if(af===undefined){ad.load_chroms({chrom:ae},function(){ad.change_chrom(ae,ab,ag)});return}else{if(ae!==ad.chrom){ad.chrom=ae;if(!ad.chrom){ad.intro_div.show()}else{ad.intro_div.hide()}ad.chrom_select.val(ad.chrom);ad.max_high=af.len-1;ad.reset();ad.redraw(true);for(var ah=0,aa=ad.tracks.length;ah<aa;ah++){var ac=ad.tracks[ah];if(ac.init){ac.init()}}}if(ab!==undefined&&ag!==undefined){ad.low=Math.max(ab,0);ad.high=Math.min(ag,ad.max_high)}ad.reset_overview();ad.redraw()}},go_to:function(ae){var ai=this,aa,ad,ab=ae.split(":"),ag=ab[0],ah=ab[1];if(ah!==undefined){try{var af=ah.split("-");aa=parseInt(af[0].replace(/,/g,""),10);ad=parseInt(af[1].replace(/,/g,""),10)}catch(ac){return false}}ai.change_chrom(ag,aa,ad)},move_fraction:function(ac){var aa=this;var ab=aa.high-aa.low;this.move_delta(ac*ab)},move_delta:function(ac){var aa=this;var ab=aa.high-aa.low;if(aa.low-ac<aa.max_low){aa.low=aa.max_low;aa.high=aa.max_low+ab}else{if(aa.high-ac>aa.max_high){aa.high=aa.max_high;aa.low=aa.max_high-ab}else{aa.high-=ac;aa.low-=ac}}aa.redraw()},add_track:function(aa){aa.view=this;aa.track_id=this.track_id_counter;this.tracks.push(aa);if(aa.init){aa.init()}aa.container_div.attr("id","track_"+aa.track_id);C(aa.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(aa){aa.view=this;this.label_tracks.push(aa)},remove_track:function(aa){this.has_changes=true;aa.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(aa)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ah){var ag=this.high-this.low,af=this.low,ab=this.high;if(af<this.max_low){af=this.max_low}if(ab>this.max_high){ab=this.max_high}if(this.high!==0&&ag<this.min_separation){ab=af+this.min_separation}this.low=Math.floor(af);this.high=Math.ceil(ab);this.resolution=Math.pow(z,Math.ceil(Math.log((this.high-this.low)/M)/Math.log(z)));this.zoom_res=Math.pow(s,Math.max(0,Math.ceil(Math.log(this.resolution,s)/Math.log(s))));var aa=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=13;this.overview_box.css({left:aa,width:Math.max(ai,ae)}).show();if(ae<ai){this.overview_box.css("left",aa-(ai-ae)/2)}if(this.overview_highlight){this.overview_highlight.css({left:aa,width:ae})}this.update_location(this.low,this.high);if(!ah){for(var ac=0,ad=this.tracks.length;ac<ad;ac++){if(this.tracks[ac]&&this.tracks[ac].enabled){this.tracks[ac].draw()}}for(ac=0,ad=this.label_tracks.length;ac<ad;ac++){this.label_tracks[ac].draw()}}},zoom_in:function(ab,ac){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ad=this.high-this.low,ae=ad/2+this.low,aa=(ad/this.zoom_factor)/2;if(ab){ae=ab/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ae-aa);this.high=Math.round(ae+aa);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var ab=this.high-this.low,ac=ab/2+this.low,aa=(ab*this.zoom_factor)/2;this.low=Math.round(ac-aa);this.high=Math.round(ac+aa);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var o=function(ac,ag){this.track=ac;this.name=ag.name;this.params=[];var an=ag.params;for(var ad=0;ad<an.length;ad++){var ai=an[ad],ab=ai.name,am=ai.label,ae=unescape(ai.html),ao=ai.value,ak=ai.type;if(ak==="number"){this.params[this.params.length]=new g(ab,am,ae,ao,ai.min,ai.max)}else{if(ak=="select"){this.params[this.params.length]=new K(ab,am,ae,ao)}else{console.log("WARNING: unrecognized tool parameter type:",ab,ak)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aq){aq.stopPropagation()}).bind("click",function(aq){aq.stopPropagation()}).bind("dblclick",function(aq){aq.stopPropagation()});var al=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aj=this.params;var ah=this;$.each(this.params,function(ar,av){var au=$("<div>").addClass("param-row").appendTo(ah.parent_div);var aq=$("<div>").addClass("param-label").text(av.label).appendTo(au);var at=$("<div/>").addClass("slider").html(av.html).appendTo(au);at.find(":input").val(av.value);$("<div style='clear: both;'/>").appendTo(au)});this.parent_div.find("input").click(function(){$(this).select()});var ap=$("<div>").addClass("param-row").appendTo(this.parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ap);var aa=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);var ah=this;aa.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()})};n(o.prototype,{get_param_values_dict:function(){var aa={};this.parent_div.find(":input").each(function(){var ab=$(this).attr("name"),ac=$(this).val();aa[ab]=JSON.stringify(ac)});return aa},get_param_values:function(){var ab=[];var aa={};this.parent_div.find(":input").each(function(){var ac=$(this).attr("name"),ad=$(this).val();if(ac){ab[ab.length]=ad}});return ab},run_on_dataset:function(){var aa=this;aa.run({dataset_id:this.track.original_dataset_id,tool_id:aa.name},function(ab){show_modal(aa.name+" is Running",aa.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var aa={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},ac=this.track,ab=aa.tool_id+ac.tool_region_and_parameters_str(aa.chrom,aa.low,aa.high),ad;if(ac instanceof e){ad=new Q(ab,view,ac.hda_ldda,undefined,{},{},ac);ad.change_mode(ac.mode)}this.track.add_track(ad);ad.content_div.text("Starting job.");this.run(aa,function(ae){ad.dataset_id=ae.dataset_id;ad.content_div.text("Running job.");ad.init()})},run:function(ab,ac){$.extend(ab,this.get_param_values_dict());var aa=function(){$.getJSON(rerun_tool_url,ab,function(ad){if(ad==="no converter"){new_track.container_div.addClass("error");new_track.content_div.text(G)}else{if(ad.error){new_track.container_div.addClass("error");new_track.content_div.text(v+ad.message)}else{if(ad==="pending"){new_track.container_div.addClass("pending");new_track.content_div.text("Converting input data so that it can be easily reused.");setTimeout(aa,2000)}else{ac(ad)}}}})};aa()}});var K=function(ab,aa,ac,ad){this.name=ab;this.label=aa;this.html=ac;this.value=ad};var g=function(ac,ab,ae,af,ad,aa){K.call(this,ac,ab,ae,af);this.min=ad;this.max=aa};var h=function(ab,aa,ac,ad){this.name=ab;this.index=aa;this.tool_id=ac;this.tool_exp_name=ad};var R=function(ab,aa,ac,ad){h.call(this,ab,aa,ac,ad);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};n(R.prototype,{applies_to:function(aa){if(aa.length>this.index){return true}return false},keep:function(aa){if(!this.applies_to(aa)){return true}var ab=parseInt(aa[this.index]);return(isNaN(ab)||(ab>=this.low&&ab<=this.high))},update_attrs:function(ab){var aa=false;if(!this.applies_to(ab)){return aa}if(ab[this.index]<this.min){this.min=Math.floor(ab[this.index]);aa=true}if(ab[this.index]>this.max){this.max=Math.ceil(ab[this.index]);aa=true}return aa},update_ui_elt:function(){var ac=function(af,ad){var ae=ad-af;return(ae<=2?0.01:1)};var ab=this.slider.slider("option","min"),aa=this.slider.slider("option","max");if(this.min<ab||this.max>aa){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ac(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var W=function(ac,al){this.track=ac;this.filters=[];for(var ag=0;ag<al.length;ag++){var aa=al[ag],ab=aa.name,ak=aa.type,ai=aa.index,an=aa.tool_id,ad=aa.tool_exp_name;if(ak==="int"||ak==="float"){this.filters[ag]=new R(ab,ai,an,ad)}else{console.log("ERROR: unsupported filter: ",ab,ak)}}var aj=function(ao,ap,aq){ao.click(function(){var ar=ap.text();max=parseFloat(aq.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aq.slider("option","values")){input_size=2*input_size+1;multi_value=true}ap.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",ar).appendTo(ap).focus().select().click(function(at){at.stopPropagation()}).blur(function(){$(this).remove();ap.text(ar)}).keyup(function(ax){if(ax.keyCode===27){$(this).trigger("blur")}else{if(ax.keyCode===13){var av=aq.slider("option","min"),at=aq.slider("option","max"),aw=function(ay){return(isNaN(ay)||ay>at||ay<av)},au=$(this).val();if(!multi_value){au=parseFloat(au);if(aw(au)){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}else{au=au.split("-");au=[parseFloat(au[0]),parseFloat(au[1])];if(aw(au[0])||aw(au[1])){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}aq.slider((multi_value?"values":"value"),au)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(ao){ao.stopPropagation()}).bind("click",function(ao){ao.stopPropagation()}).bind("dblclick",function(ao){ao.stopPropagation()}).bind("keydown",function(ao){ao.stopPropagation()});var ae=this;$.each(this.filters,function(av,ap){var ar=$("<div/>").addClass("slider-row").appendTo(ae.parent_div);var ao=$("<div/>").addClass("slider-label").appendTo(ar);var ax=$("<span/>").addClass("slider-name").text(ap.name+" ").appendTo(ao);var aq=$("<span/>");var at=$("<span/>").addClass("slider-value").appendTo(ao).append("[").append(aq).append("]");var aw=$("<div/>").addClass("slider").appendTo(ar);ap.control_element=$("<div/>").attr("id",ap.name+"-filter-control").appendTo(aw);var au=[0,0];ap.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ay,az){au=az.values;aq.text(az.values[0]+"-"+az.values[1]);setTimeout(function(){if(az.values[0]==au[0]&&az.values[1]==au[1]){var aA=az.values;aq.text(aA[0]+"-"+aA[1]);ap.low=aA[0];ap.high=aA[1];ae.track.draw(true,true)}},50)},change:function(ay,az){ap.control_element.slider("option","slide").call(ap.control_element,ay,az)}});ap.slider=ap.control_element;ap.slider_label=aq;aj(at,aq,ap.control_element);$("<div style='clear: both;'/>").appendTo(ar)});if(this.filters.length!=0){var am=$("<div>").addClass("param-row").appendTo(this.parent_div);var ah=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(am);var af=this;ah.click(function(){af.run_on_dataset()})}};n(W.prototype,{reset_filters:function(){for(var aa=0;aa<this.filters.length;aa++){filter=this.filters[aa];filter.slider.slider("option","values",[filter.min,filter.max])}},run_on_dataset:function(){var ai=function(am,ak,al){if(!(ak in am)){am[ak]=al}return am[ak]};var ac={},aa,ab,ad;for(var ae=0;ae<this.filters.length;ae++){aa=this.filters[ae];if(aa.tool_id){if(aa.min!=aa.low){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" >= "+aa.low}if(aa.max!=aa.high){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" <= "+aa.high}}}var ag=[];for(var aj in ac){ag[ag.length]=[aj,ac[aj]]}var ah=ag.length;(function af(aq,an){var al=an[0],am=al[0],ap=al[1],ao="("+ap.join(") and (")+")",ak={cond:ao,input:aq,target_dataset_id:aq,tool_id:am},an=an.slice(1);$.getJSON(run_tool_url,ak,function(ar){if(ar.error){show_modal("Filter Dataset","Error running tool "+am,{Close:hide_modal})}else{if(an.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{af(ar.dataset_id,an)}}})})(this.track.dataset_id,ag)}});var V=function(aa){this.track=aa.track;this.params=aa.params;this.values={};if(aa.saved_values){this.restore_values(aa.saved_values)}this.onchange=aa.onchange};n(V.prototype,{restore_values:function(aa){var ab=this;$.each(this.params,function(ac,ad){if(aa[ad.key]!==undefined){ab.values[ad.key]=aa[ad.key]}else{ab.values[ad.key]=ad.default_value}})},build_form:function(){var ab=this;var aa=$("<div />");$.each(this.params,function(af,ad){if(!ad.hidden){var ac="param_"+af;var ak=$("<div class='form-row' />").appendTo(aa);ak.append($("<label />").attr("for",ac).text(ad.label+":"));if(ad.type==="bool"){ak.append($('<input type="checkbox" />').attr("id",ac).attr("name",ac).attr("checked",ab.values[ad.key]))}else{if(ad.type==="color"){var ah=ab.values[ad.key];var ag=$("<input />").attr("id",ac).attr("name",ac).val(ah);var ai=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var ae=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ai);var aj=$("<div/>").appendTo(ae).farbtastic({width:100,height:100,callback:ag,color:ah});$("<div />").append(ag).append(ai).appendTo(ak).bind("click",function(al){ai.css({left:$(this).position().left+($(ag).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ai.hide();$(document).unbind("click.color-picker")});al.stopPropagation()})}else{ak.append($("<input />").attr("id",ac).attr("name",ac).val(ab.values[ad.key]))}}}});return aa},update_from_form:function(aa){var ac=this;var ab=false;$.each(this.params,function(ad,af){if(!af.hidden){var ag="param_"+ad;var ae=aa.find("#"+ag).val();if(af.type==="float"){ae=parseFloat(ae)}else{if(af.type==="int"){ae=parseInt(ae)}else{if(af.type==="bool"){ae=aa.find("#"+ag).is(":checked")}}}if(ae!==ac.values[af.key]){ac.values[af.key]=ae;ab=true}}});if(ab){this.onchange()}}});var b=function(ac,ab,aa){this.index=ac;this.low=ac*M*ab;this.high=(ac+1)*M*ab;this.resolution=ab;this.canvas=$("<div class='track-tile'/>").append(aa);this.stale=false};var l=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.max_val=ad};var L=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.message=ad};var j=function(ab,aa,ae,ac,ad){this.name=ab;this.view=aa;this.parent_element=ae;this.data_url=(ac?ac:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ad?ad:H);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};n(j.prototype,{get_type:function(){if(this instanceof X){return"LabelTrack"}else{if(this instanceof x){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof S){return"ReadTrack"}else{if(this instanceof Q){return"ToolDataFeatureTrack"}else{if(this instanceof P){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var aa=this;aa.enabled=false;aa.tile_cache.clear();aa.data_manager.clear();aa.initial_canvas=undefined;aa.content_div.css("height","auto");aa.container_div.removeClass("nodata error pending");if(!aa.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id,chrom:aa.view.chrom},function(ab){if(!ab||ab==="error"||ab.kind==="error"){aa.container_div.addClass("error");aa.content_div.text(m);if(ab.message){var ad=aa.view.tracks.indexOf(aa);var ac=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+ab.message+"</pre>",{Close:hide_modal})});aa.content_div.append(ac)}}else{if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(G)}else{if(ab==="no data"||(ab.data!==undefined&&(ab.data===null||ab.data.length===0))){aa.container_div.addClass("nodata");aa.content_div.text(B)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text(q);setTimeout(function(){aa.init()},aa.data_query_wait)}else{if(ab.status==="data"){if(ab.valid_chroms){aa.valid_chroms=ab.valid_chroms;aa.make_name_popup_menu()}aa.content_div.text(U);if(aa.view.chrom){aa.content_div.text("");aa.content_div.css("height",aa.height_px+"px");aa.enabled=true;$.when(aa.predraw_init()).done(function(){aa.container_div.removeClass("nodata error pending");aa.draw()})}}}}}}})},predraw_init:function(){},update_name:function(aa){this.old_name=this.name;this.name=aa;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var J=function(ah,af,ai){var ab=this,aj=ab.view;this.filters_manager=(ah!==undefined?new W(this,ah):undefined);this.filters_available=false;this.filters_visible=false;this.tool=(af!==undefined&&obj_length(af)>0?new o(this,af):undefined);this.parent_track=ai;this.child_tracks=[];if(ab.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}ab.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();ab.container_div.append(ab.child_tracks_container);if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}if(ab.display_modes!==undefined){if(ab.mode_div===undefined){ab.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ab.header_div);var ac=(ab.track_config&&ab.track_config.values.mode?ab.track_config.values.mode:ab.display_modes[0]);ab.mode=ac;ab.mode_div.text(ac);var aa={};for(var ad=0,ag=ab.display_modes.length;ad<ag;ad++){var ae=ab.display_modes[ad];aa[ae]=function(ak){return function(){ab.change_mode(ak)}}(ae)}make_popupmenu(ab.mode_div,aa)}else{ab.mode_div.hide()}}this.make_name_popup_menu()};n(J.prototype,j.prototype,{change_mode:function(ab){var aa=this;aa.mode_div.text(ab);aa.mode=ab;aa.track_config.values.mode=ab;aa.tile_cache.clear();aa.draw()},make_name_popup_menu:function(){var ab=this;var aa={};aa["Edit configuration"]=function(){var ah=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},af=function(){ab.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ag=function(ai){if((ai.keyCode||ai.which)===27){ah()}else{if((ai.keyCode||ai.which)===13){af()}}};$(window).bind("keypress.check_enter_esc",ag);show_modal("Configure Track",ab.track_config.build_form(),{Cancel:ah,OK:af})};if(ab.filters_available>0){var ae=(ab.filters_div.is(":visible")?"Hide filters":"Show filters");aa[ae]=function(){ab.filters_visible=(ab.filters_div.is(":visible"));if(ab.filters_visible){ab.filters_manager.reset_filters()}ab.filters_div.toggle();ab.make_name_popup_menu()}}if(ab.tool){var ae=(ab.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");aa[ae]=function(){if(!ab.dynamic_tool_div.is(":visible")){ab.update_name(ab.name+ab.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";ab.revert_name()}ab.dynamic_tool_div.toggle();ab.make_name_popup_menu()}}if(ab.valid_chroms){aa["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+ab.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var ac=view;var ad=function(){$("#no-tracks").show()};if(this.parent_track){ac=this.parent_track;ad=function(){}}aa.Remove=function(){ac.remove_track(ab);if(ac.num_tracks===0){ad()}};make_popupmenu(ab.name_div,aa)},draw:function(aa,ac){if(!this.dataset_id){return}var au=this.view.low,ag=this.view.high,ai=ag-au,ak=this.view.container.width(),ae=ak/ai,al=this.view.resolution,ad=$("<div style='position: relative;'></div>"),am=function(aw,ax,av){return aw+"_"+ax+"_"+av};if(!ac){this.content_div.children().remove()}this.content_div.append(ad);this.max_height=0;var ao=Math.floor(au/al/M);var af=[];var ap=0;while((ao*M*al)<ag){var at=am(ak,ae,ao);var ah=this.tile_cache.get(at);var aq=ao*M*this.view.resolution;var ab=aq+M*this.view.resolution;if(!aa&&ah){af[af.length]=ah;this.show_tile(ah,ad,ae)}else{this.delayed_draw(aa,at,ao,al,ad,ae,af)}ao+=1;ap++}var aj=this;var ar=setInterval(function(){if(af.length===ap){clearInterval(ar);if(ac){var aA=aj.content_div.children();var aB=false;for(var az=aA.length-1,aF=0;az>=aF;az--){var ay=$(aA[az]);if(aB){ay.remove()}else{if(ay.children().length!==0){aB=true}}}}if(aj instanceof e&&aj.mode=="Histogram"){var aE=-1;for(var az=0;az<af.length;az++){var aH=af[az].max_val;if(aH>aE){aE=aH}}for(var az=0;az<af.length;az++){if(af[az].max_val!==aE){var aG=af[az];aG.canvas.remove();aj.delayed_draw(true,am(ak,ae,aG.index),aG.index,aG.resolution,ad,ae,[],{max:aE})}}}if(aj.filters_manager){var ax=aj.filters_manager.filters;for(var aD=0;aD<ax.length;aD++){ax[aD].update_ui_elt()}var aC=false;if(aj.example_feature){for(var aD=0;aD<ax.length;aD++){if(ax[aD].applies_to(aj.example_feature)){aC=true;break}}}if(aj.filters_available!==aC){aj.filters_available=aC;if(!aj.filters_available){aj.filters_div.hide()}aj.make_name_popup_menu()}}var av=false;for(var aw=0;aw<af.length;aw++){if(af[aw].message){av=true;break}}if(av){for(var aw=0;aw<af.length;aw++){aG=af[aw];if(!aG.message){aG.canvas.css("padding-top",A)}}}}},50);for(var an=0;an<this.child_tracks.length;an++){this.child_tracks[an].draw(aa,ac)}},delayed_draw:function(ab,ai,ac,ae,aj,am,ak,af){var ad=this,ag=ac*M*ae,al=ag+M*ae;var ah=function(av,an,ap,ao,at,au,aq){var ar=ad.draw_tile(an,ap,ao,au,aq);ad.tile_cache.set(ai,ar);if(ar===undefined){return}ad.show_tile(ar,at,au);ak[ak.length]=ar};var aa=setTimeout(function(){if(ag<=ad.view.high&&al>=ad.view.low){var an=(ab?undefined:ad.tile_cache.get(ai));if(an){ad.show_tile(an,aj,am);ak[ak.length]=an}else{$.when(ad.data_manager.get_data(ag,al,ae,ad.data_url_extra_params)).then(function(ao){n(ao,af);if(view.reference_track&&am>view.canvas_manager.char_width_px){$.when(view.reference_track.data_manager.get_data(ag,al,ae,view.reference_track.data_url_extra_params)).then(function(ap){ah(aa,ao,ae,ac,aj,am,ap)})}else{ah(aa,ao,ae,ac,aj,am)}})}}},50)},show_tile:function(ag,ai,aj){var ab=this,aa=ag.canvas,ae=aa;if(ag.message){var ak=$("<div/>"),ah=$("<div/>").addClass("tile-message").text(ag.message).css({height:A-1,width:ag.canvas.width}).appendTo(ak),af=$("<div/>").text("Show more").addClass("action-button").css({"padding-top":0,"padding-bottom":0}).appendTo(ah);ak.append(aa);ae=ak;af.click(function(){ag.stale=true;ab.data_manager.get_more_data(ag.low,ag.high,ag.resolution,{},ab.data_manager.DEEP_DATA_REQ);ab.draw()}).dblclick(function(al){al.stopPropagation()})}var ad=this.view.high-this.view.low,ac=(ag.low-this.view.low)*aj;if(this.left_offset){ac-=this.left_offset}ae.css({position:"absolute",top:0,left:ac,height:""});ai.append(ae);ab.max_height=Math.max(ab.max_height,ae.height());ab.content_div.css("height",ab.max_height+"px");ai.children().css("height",ab.max_height+"px")},set_overview:function(){var aa=this.view;if(this.initial_canvas&&this.is_overview){aa.overview_close.show();aa.overview_viewport.append(this.initial_canvas);aa.overview_highlight.show().height(this.initial_canvas.height());aa.overview_viewport.height(this.initial_canvas.height()+aa.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(ac,aa,ad){var ab=this,ae=(ac!==undefined&&aa!==undefined&&ad!==undefined?ac+":"+aa+"-"+ad:"all");return" - region=["+ae+"], parameters=["+ab.tool.get_param_values().join(", ")+"]"},add_track:function(aa){aa.track_id=this.track_id+"_"+this.child_tracks.length;aa.container_div.attr("id","track_"+aa.track_id);this.child_tracks_container.append(aa.container_div);C(aa.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(aa);this.view.has_changes=true},remove_track:function(aa){aa.container_div.fadeOut("slow",function(){$(this).remove()})}});var X=function(aa,ab){this.hidden=true;j.call(this,null,aa,ab);this.container_div.addClass("label-track")};n(X.prototype,j.prototype,{draw:function(){var ac=this.view,ad=ac.high-ac.low,ag=Math.floor(Math.pow(10,Math.floor(Math.log(ad)/Math.log(10)))),aa=Math.floor(ac.low/ag)*ag,ae=this.view.container.width(),ab=$("<div style='position: relative; height: 1.3em;'></div>");while(aa<ac.high){var af=(aa-ac.low)/ad*ae;ab.append($("<div class='label'>"+commatize(aa)+"</div>").css({position:"absolute",left:af-1}));aa+=ag}this.content_div.children(":first").remove();this.content_div.append(ab)}});var x=function(aa){this.hidden=true;j.call(this,null,aa,aa.top_labeltrack);J.call(this);aa.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:aa.dbkey};this.data_manager=new E(y,this,false);this.tile_cache=new c(r)};n(x.prototype,J.prototype,{draw_tile:function(ai,af,ab,ak){var ae=this,ac=M*af;if(ak>this.view.canvas_manager.char_width_px){if(ai===null){ae.content_div.css("height","0px");return}var ad=this.view.canvas_manager.new_canvas();var aj=ad.getContext("2d");ad.width=Math.ceil(ac*ak+ae.left_offset);ad.height=ae.height_px;aj.font=aj.canvas.manager.default_font;aj.textAlign="center";for(var ag=0,ah=ai.length;ag<ah;ag++){var aa=Math.round(ag*ak);aj.fillText(ai[ag],aa+ae.left_offset,10)}return new b(ab,af,ad)}this.content_div.css("height","0px")}});var k=function(ae,ac,af,aa,ad){var ab=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,ae,ac,ac.viewport_container);J.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=af;this.dataset_id=aa;this.original_dataset_id=aa;this.data_manager=new N(y,this);this.tile_cache=new c(r);this.track_config=new V({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:ad,onchange:function(){ab.vertical_range=ab.prefs.max_value-ab.prefs.min_value;$("#linetrack_"+ab.track_id+"_minval").text(ab.prefs.min_value);$("#linetrack_"+ab.track_id+"_maxval").text(ab.prefs.max_value);ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};n(k.prototype,J.prototype,{add_resize_handle:function(){var aa=this;var ad=false;var ac=false;var ab=$("<div class='track-resize'>");$(aa.container_div).hover(function(){ad=true;ab.show()},function(){ad=false;if(!ac){ab.hide()}});ab.hide().bind("dragstart",function(ae,af){ac=true;af.original_height=$(aa.content_div).height()}).bind("drag",function(af,ag){var ae=Math.min(Math.max(ag.original_height+ag.deltaY,aa.min_height_px),aa.max_height_px);$(aa.content_div).css("height",ae);aa.height_px=ae;aa.draw(true)}).bind("dragend",function(ae,af){aa.tile_cache.clear();ac=false;if(!ad){ab.hide()}aa.track_config.values.height=aa.height_px}).appendTo(aa.container_div)},predraw_init:function(){var aa=this,ab=aa.view.tracks.indexOf(aa);aa.vertical_range=undefined;return $.getJSON(aa.data_url,{stats:true,chrom:aa.view.chrom,low:null,high:null,hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id},function(ac){aa.container_div.addClass("line-track");var ae=ac.data;if(isNaN(parseFloat(aa.prefs.min_value))||isNaN(parseFloat(aa.prefs.max_value))){aa.prefs.min_value=ae.min;aa.prefs.max_value=ae.max;$("#track_"+ab+"_minval").val(aa.prefs.min_value);$("#track_"+ab+"_maxval").val(aa.prefs.max_value)}aa.vertical_range=aa.prefs.max_value-aa.prefs.min_value;aa.total_frequency=ae.total_frequency;aa.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_minval").text(u(aa.prefs.min_value));var ad=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_maxval").text(u(aa.prefs.max_value));ad.css({position:"absolute",top:"24px",left:"10px"});ad.prependTo(aa.container_div);af.css({position:"absolute",bottom:"2px",left:"10px"});af.prependTo(aa.container_div)})},draw_tile:function(ak,ae,ab,aj){if(this.vertical_range===undefined){return}var af=ab*M*ae,ad=M*ae,aa=Math.ceil(ad*aj),ah=this.height_px;var ac=this.view.canvas_manager.new_canvas();ac.width=aa,ac.height=ah;var ai=ac.getContext("2d");var ag=new I.LinePainter(ak.data,af,af+ad,this.prefs,this.mode);ag.draw(ai,aa,ah);return new b(ab,ae,ac)}});var e=function(aa,af,ae,ai,ah,ac,ad,ag){var ab=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ah,onchange:function(){ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;j.call(this,aa,af,af.viewport_container);J.call(this,ac,ad,ag);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ae;this.dataset_id=ai;this.original_dataset_id=ai;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new N(20,this);this.left_offset=200;this.painter=I.LinkedFeaturePainter};n(e.prototype,J.prototype,{update_auto_mode:function(aa){if(this.mode=="Auto"){if(aa=="no_detail"){aa="feature spans"}else{if(aa=="summary_tree"){aa="coverage histogram"}}this.mode_div.text("Auto ("+aa+")")}},incremental_slots:function(ae,ab,ad){var ac=this.view.canvas_manager.dummy_context,aa=this.inc_slots[ae];if(!aa||(aa.mode!==ad)){aa=new (p.FeatureSlotter)(ae,ad==="Pack",w,function(af){return ac.measureText(af)});aa.mode=ad;this.inc_slots[ae]=aa}return aa.slot_features(ab)},get_summary_tree_data:function(ae,ah,ac,ap){if(ap>ac-ah){ap=ac-ah}var al=Math.floor((ac-ah)/ap),ao=[],ad=0;var af=0,ag=0,ak,an=0,ai=[],am,aj;var ab=function(at,ar,au,aq){at[0]=ar+au*aq;at[1]=ar+(au+1)*aq};while(an<ap&&af!==ae.length){var aa=false;for(;an<ap&&!aa;an++){ab(ai,ah,an,al);for(ag=af;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){aa=true;break}}if(aa){break}}data_start_index=ag;ao[ao.length]=am=[ai[0],0];for(;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){am[1]++}else{break}}if(am[1]>ad){ad=am[1]}an++}return{max:ad,delta:al,data:ao}},draw_tile:function(an,av,az,aj,ad){var ar=this,aB=az*M*av,ab=(az+1)*M*av,ap=ab-aB,at=Math.ceil(ap*aj),aq=this.mode,aF=25,ae=this.left_offset,ao,af;if(aq==="Auto"){if(an.dataset_type==="summary_tree"){aq=an.dataset_type}else{if(an.extra_info==="no_detail"){aq="no_detail"}else{var aE=an.data;if(this.view.high-this.view.low>F){aq="Squish"}else{aq="Pack"}}}this.update_auto_mode(aq)}if(aq==="summary_tree"||aq==="Histogram"){af=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var aa=$("<div />").addClass("yaxislabel");aa.text(an.max);aa.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});aa.prependTo(this.container_div);var ac=this.view.canvas_manager.new_canvas();ac.width=at+ae;ac.height=af+O;if(an.dataset_type!="summary_tree"){var ak=this.get_summary_tree_data(an.data,aB,ab,200);if(an.max){ak.max=an.max}an=ak}var aC=new I.SummaryTreePainter(an,aB,ab,this.prefs);var au=ac.getContext("2d");au.translate(ae,O);aC.draw(au,at,af);return new l(az,av,ac,an.max)}var ao,ah=1;if(aq==="no_detail"||aq==="Squish"||aq==="Pack"){ah=this.incremental_slots(aj,an.data,aq);ao=this.inc_slots[aj].slots}var ai=[];if(an.data){var al=this.filters_manager.filters;for(var aw=0,ay=an.data.length;aw<ay;aw++){var ag=an.data[aw];var ax=false;var am;for(var aA=0,aD=al.length;aA<aD;aA++){am=al[aA];am.update_attrs(ag);if(!am.keep(ag)){ax=true;break}}if(!ax){ai.push(ag)}}}var aC=new (this.painter)(ai,aB,ab,this.prefs,aq,ad);var af=aC.get_required_height(ah);var ac=this.view.canvas_manager.new_canvas();ac.width=at+ae;ac.height=af;var au=ac.getContext("2d");au.fillStyle=this.prefs.block_color;au.font=au.canvas.manager.default_font;au.textAlign="right";this.container_div.find(".yaxislabel").remove();if(an.data){this.example_feature=(an.data.length?an.data[0]:undefined);au.translate(ae,0);aC.draw(au,at,af,ao)}return new L(az,av,ac,an.message)}});var P=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.painter=I.VariantPainter};n(P.prototype,J.prototype,e.prototype);var S=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ac,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.painter=I.ReadPainter;this.make_name_popup_menu()};n(S.prototype,J.prototype,e.prototype);var Q=function(ae,ac,ag,aa,ad,af,ab){e.call(this,ae,ac,ag,aa,ad,af,{},ab);this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};n(Q.prototype,J.prototype,e.prototype,{predraw_init:function(){var ab=this;var aa=function(){if(ab.data_manager.size()===0){setTimeout(aa,300)}else{ab.data_url=default_data_url;ab.data_query_wait=H;ab.dataset_state_url=converted_datasets_state_url;$.getJSON(ab.dataset_state_url,{dataset_id:ab.dataset_id,hda_ldda:ab.hda_ldda},function(ac){})}};aa()}});T.View=Y;T.LineTrack=k;T.FeatureTrack=e;T.ReadTrack=S};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(j,w){var t=j("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var m=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};m.prototype.default_prefs={};var u=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(x,B,D,E,z){m.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var n=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,A,I,F){var D=this.data,G=this.view_start,K=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var N=this.view_end-this.view_start,M=A/N,z=this.get_row_height();for(var C=0,E=D.length;C<E;C++){var L=D[C],B=L[0],x=L[1],y=L[2],H=(F&&F[B]!==undefined?F[B]:null);if((x<K&&y>G)&&(this.mode=="Dense"||H!==null)){this.draw_element(J,this.mode,L,H,G,K,M,z,A)}}J.restore()}});var d=10,h=3,l=5,v=10,f=1,r=3,e=3,a=9,k=2,g="#ccc";var q=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=d}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=l}else{x=v}}}return x},draw_element:function(J,C,R,E,L,ab,af,ag,x){var O=R[0],ad=R[1],V=R[2],M=R[3],W=Math.floor(Math.max(0,(ad-L)*af)),K=Math.ceil(Math.min(x,Math.max(0,(V-L)*af))),U=(C==="Dense"?0:(0+E))*ag,I,Z,N=null,ah=null,A=this.prefs.block_color,Y=this.prefs.label_color;if(C=="Dense"){E=1}if(C==="no_detail"){J.fillStyle=A;J.fillRect(W,U+5,K-W,f)}else{var H=R[4],T=R[5],X=R[6],B=R[7];if(T&&X){N=Math.floor(Math.max(0,(T-L)*af));ah=Math.ceil(Math.min(x,Math.max(0,(X-L)*af)))}var ae,P;if(C==="Squish"||C==="Dense"){ae=1;P=e}else{ae=5;P=a}if(!B){if(R.strand){if(R.strand==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(R.strand==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}}else{J.fillStyle=A}J.fillRect(W,U,K-W,P)}else{var G,Q;if(C==="Squish"||C==="Dense"){J.fillStyle=g;G=U+Math.floor(e/2)+1;Q=1}else{if(H){var G=U;var Q=P;if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand")}}}else{J.fillStyle=g;G+=(e/2)+1;Q=1}}J.fillRect(W,G,K-W,Q);for(var ac=0,z=B.length;ac<z;ac++){var D=B[ac],y=Math.floor(Math.max(0,(D[0]-L)*af)),S=Math.ceil(Math.min(x,Math.max((D[1]-L)*af)));if(y>S){continue}J.fillStyle=A;J.fillRect(y,U+(P-ae)/2+1,S-y,ae);if(N!==undefined&&X>T&&!(y>ah||S<N)){var aa=Math.max(y,N),F=Math.min(S,ah);J.fillRect(aa,U+1,F-aa,P);if(B.length==1&&C=="Pack"){if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}if(aa+14<F){aa+=2;F-=2}J.fillRect(aa,U+1,F-aa,P)}}}}if(C==="Pack"&&ad>L){J.fillStyle=Y;if(L===0&&W-J.measureText(M).width<0){J.textAlign="left";J.fillText(M,K+k,U+8)}else{J.textAlign="right";J.fillText(M,W-k,U+8)}J.fillStyle=A}}}});var b=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(b.prototype,n.prototype,{draw_element:function(Q,L,F,B,T,z,I,R,O){var F=data[i],H=F[0],P=F[1],A=F[2],K=F[3],D=Math.floor(Math.max(0,(P-T)*I)),G=Math.ceil(Math.min(O,Math.max(0,(A-T)*I))),C=(L==="Dense"?0:(0+B))*R,x,U,y=null,J=null;if(no_label){Q.fillStyle=block_color;Q.fillRect(D+left_offset,C+5,G-D,1)}else{var S=F[4],N=F[5],E=F[6];x=9;U=1;Q.fillRect(D+left_offset,C,G-D,x);if(L!=="Dense"&&K!==undefined&&P>T){Q.fillStyle=label_color;if(T===0&&D-Q.measureText(K).width<0){Q.textAlign="left";Q.fillText(K,G+2+left_offset,C+8)}else{Q.textAlign="right";Q.fillText(K,D-2+left_offset,C+8)}Q.fillStyle=block_color}var M=S+" / "+N;if(P>T&&Q.measureText(M).width<(G-D)){Q.fillStyle="white";Q.textAlign="center";Q.fillText(M,left_offset+D+(G-D)/2,C+8);Q.fillStyle=block_color}}}});var s=function(A,C,x,z,B,y){n.call(this,A,C,x,z,B);this.ref_seq=y};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=d}else{if(y==="Squish"){x=l}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(T,O,K,Y,z,S,H,E,D){T.textAlign="center";var R=this,y=[Y,z],N=0,U=0,Q=0;ref_seq=this.ref_seq,char_width_px=T.canvas.manager.char_width_px;var ad=[];if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){Q=Math.round(K/2)}if(!H){H=[[0,E.length]]}for(var L=0,W=H.length;L<W;L++){var I=H[L],A="MIDNSHP=X"[I[0]],M=I[1];if(A==="H"||A==="S"){N-=M}var F=S+N,ac=Math.floor(Math.max(0,(F-Y)*K)),G=Math.floor(Math.max(0,(F+M-Y)*K));if(ac===G){G+=1}switch(A){case"H":break;case"S":case"M":case"=":if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(Q>0){T.fillStyle=this.prefs.block_color;T.fillRect(ac-Q,D+1,G-ac,9);T.fillStyle=g;for(var aa=0,x=P.length;aa<x;aa++){if(this.prefs.show_differences&&ref_seq){var J=ref_seq[F-Y+aa];if(!J||J.toLowerCase()===P[aa].toLowerCase()){continue}}if(F+aa>=Y&&F+aa<=z){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab,D+9)}}}else{T.fillStyle=this.prefs.block_color;T.fillRect(ac,D+4,G-ac,e)}}U+=M;N+=M;break;case"N":T.fillStyle=g;T.fillRect(ac-Q,D+5,G-ac,1);N+=M;break;case"D":T.fillStyle="red";T.fillRect(ac-Q,D+4,G-ac,3);N+=M;break;case"P":break;case"I":var X=ac-Q;if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(this.prefs.show_insertions){var C=ac-(G-ac)/2;if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){T.fillStyle="yellow";T.fillRect(C-Q,D-9,G-ac,9);ad[ad.length]={type:"triangle",data:[X,D+4,5]};T.fillStyle=g;switch(seq_tile_overlap){case (OVERLAP_START):P=P.slice(Y-F);break;case (OVERLAP_END):P=P.slice(0,F-z);break;case (CONTAINED_BY):break;case (CONTAINS):P=P.slice(Y-F,F-z);break}for(var aa=0,x=P.length;aa<x;aa++){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab-(G-ac)/2,D)}}else{T.fillStyle="yellow";T.fillRect(C,D+(this.mode!=="Dense"?2:5),G-ac,(O!=="Dense"?e:r))}}else{if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){ad[ad.length]={type:"text",data:[P.length,X,D+9]}}else{}}}U+=M;break;case"X":U+=M;break}}T.fillStyle="yellow";var Z,B,ae;for(var V=0;V<ad.length;V++){Z=ad[V];B=Z.type;ae=Z.data;if(B==="text"){T.save();T.font="bold "+T.font;T.fillText(ae[0],ae[1],ae[2]);T.restore()}else{if(B=="triangle"){p(T,ae[0],ae[1],ae[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+k-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-k-N,B+8)}Q.fillStyle=U}}});w.SummaryTreePainter=u;w.LinePainter=c;w.LinkedFeaturePainter=q;w.ReadPainter=s;w.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
+var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var trackster_module=function(f,T){var n=f("class").extend,p=f("slotting"),I=f("painters");var Z=function(aa,ab){this.document=aa;this.default_font=ab!==undefined?ab:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};n(Z.prototype,{load_pattern:function(aa,ae){var ab=this.patterns,ac=this.dummy_context,ad=new Image();ad.src=image_path+ae;ad.onload=function(){ab[aa]=ac.createPattern(ad,"repeat")}},get_pattern:function(aa){return this.patterns[aa]},new_canvas:function(){var aa=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(aa)}aa.manager=this;return aa}});var C=function(aa,ab){aa.bind("drag",{handle:ab,relative:true},function(af,ag){var ae=$(this).parent();var ad=ae.children();var ac;for(ac=0;ac<ad.length;ac++){if(ag.offsetY<$(ad.get(ac)).position().top){break}}if(ac===ad.length){if(this!==ad.get(ac-1)){ae.append(this)}}else{if(this!==ad.get(ac)){$(this).insertBefore(ad.get(ac))}}}).bind("dragstart",function(){$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css("border","0px")})};T.sortable=C;var D=9,A=20,O=D+2,w=100,F=12000,M=200,z=5,s=10,H=5000,t=100,m="There was an error in indexing this dataset. ",G="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",q="Currently indexing... please wait",v="Tool cannot be rerun: ",a="Loading data...",U="Ready for display",d=10,r=5,y=5;function u(aa){return Math.round(aa*1000)/1000}var c=function(aa){this.num_elements=aa;this.clear()};n(c.prototype,{get:function(ab){var aa=this.key_ary.indexOf(ab);if(aa!==-1){if(this.obj_cache[ab].stale){this.key_ary.splice(aa,1);delete this.obj_cache[ab]}else{this.move_key_to_end(ab,aa)}}return this.obj_cache[ab]},set:function(ab,ac){if(!this.obj_cache[ab]){if(this.key_ary.length>=this.num_elements){var aa=this.key_ary.shift();delete this.obj_cache[aa]}this.key_ary.push(ab)}this.obj_cache[ab]=ac;return ac},move_key_to_end:function(ab,aa){this.key_ary.splice(aa,1);this.key_ary.push(ab)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var N=function(ab,aa,ac){c.call(this,ab);this.track=aa;this.subset=(ac!==undefined?ac:true)};n(N.prototype,c.prototype,{load_data:function(aj,ae,ab,ag){var ai=this.track.view.chrom,ah=this.track.mode,ad={chrom:ai,low:aj,high:ae,mode:ah,resolution:ab,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ad,ag);if(this.track.filters_manager){var ak=[];var aa=this.track.filters_manager.filters;for(var af=0;af<aa.length;af++){ak[ak.length]=aa[af].name}ad.filter_cols=JSON.stringify(ak)}var ac=this;return $.getJSON(this.track.data_url,ad,function(al){ac.set_data(aj,ae,ah,al)})},get_data:function(aa,ae,ab,ad){var af=this.track.mode,ac=this.get_data_from_cache(aa,ae,af);if(ac){return ac}ac=this.load_data(aa,ae,ab,ad);this.set_data(aa,ae,af,ac);return ac},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ai,ad,ac,ag,ae){var ah=this.track.mode,aj=this.get_data_from_cache(ai,ad,ah);if(!aj){console.log("ERROR: no current data for: ",this.track,ai,ad,ac,ag);return}aj.stale=true;var ab=ai;if(ae===this.DEEP_DATA_REQ){$.extend(ag,{start_val:aj.data.length+1})}else{if(ae===this.BROAD_DATA_REQ){ab=aj.data[aj.data.length-1][2]+1}}var aa=this,af=this.load_data(ab,ad,ac,ag);new_data_available=$.Deferred();this.set_data(ai,ad,ah,new_data_available);$.when(af).then(function(ak){if(ak.data){ak.data=aj.data.concat(ak.data);if(ak.message){ak.message=ak.message.replace(/[0-9]+/,ak.data.length)}}aa.set_data(ai,ad,ah,ak);new_data_available.resolve(ak)});return new_data_available},get_data_from_cache:function(aa,ab,ac){return this.get(this.gen_key(aa,ab,ac))},set_data:function(ab,ac,ad,aa){return this.set(this.gen_key(ab,ac,ad),aa)},gen_key:function(aa,ac,ad){var ab=aa+"_"+ac+"_"+ad;return ab},split_key:function(aa){return aa.split("_")}});var E=function(ab,aa,ac){N.call(this,ab,aa,ac)};n(E.prototype,N.prototype,c.prototype,{load_data:function(ac,aa,ae,af,ab,ad){if(ab>1){return}return N.prototype.load_data.call(this,ac,aa,ae,af,ab,ad)}});var Y=function(aa,ad,ac,ab,ae){this.container=aa;this.chrom=null;this.vis_id=ac;this.dbkey=ab;this.title=ad;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(ae);this.canvas_manager=new Z(aa.get(0).ownerDocument);this.reset()};n(Y.prototype,{init:function(ae){var ac=this.container,aa=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ac);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ac);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ac);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").appendTo(this.viewport_container).hide();var ad=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ab=function(af){if(af.type==="focusout"||(af.keyCode||af.which)===13||(af.keyCode||af.which)===27){if((af.keyCode||af.which)!==27){aa.go_to($(this).val())}$(this).hide();$(this).val("");aa.location_span.show();aa.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ab).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){aa.location_span.hide();aa.chrom_select.hide();aa.nav_input.val(aa.chrom+":"+aa.low+"-"+aa.high);aa.nav_input.css("display","inline-block");aa.nav_input.select();aa.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){aa.zoom_out();aa.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){aa.zoom_in();aa.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},ae);this.chrom_select.bind("change",function(){aa.change_chrom(aa.chrom_select.val())});this.content_div.bind("click",function(af){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(af){aa.zoom_in(af.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(af,ag){this.current_x=ag.offsetX}).bind("drag",function(af,ah){var ai=ah.offsetX-this.current_x;this.current_x=ah.offsetX;var ag=Math.round(ai/aa.viewport_container.width()*(aa.max_high-aa.max_low));aa.move_delta(-ag)});this.overview_close.bind("click",function(){for(var ag=0,af=aa.tracks.length;ag<af;ag++){aa.tracks[ag].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",aa.overview_box.height());aa.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(af,ag){if(af.clientX>aa.viewport_container.width()-16){return false}}).bind("dragstart",function(af,ag){ag.original_low=aa.low;ag.current_height=af.clientY;ag.current_x=ag.offsetX}).bind("drag",function(ah,aj){var af=$(this);var ak=aj.offsetX-aj.current_x;var ag=af.scrollTop()-(ah.clientY-aj.current_height);af.scrollTop(ag);aj.current_height=ah.clientY;aj.current_x=aj.offsetX;var ai=Math.round(ak/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ai)}).bind("mousewheel",function(ah,aj,ag,af){if(ag){var ai=Math.round(-ag/aa.viewport_container.width()*(aa.high-aa.low));aa.move_delta(ai)}});this.top_labeltrack.bind("dragstart",function(af,ag){return $("<div />").css({height:aa.content_div.height()+aa.top_labeltrack.height()+aa.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(aj,ak){$(ak.proxy).css({left:Math.min(aj.pageX,ak.startX),width:Math.abs(aj.pageX-ak.startX)});var ag=Math.min(aj.pageX,ak.startX)-aa.container.offset().left,af=Math.max(aj.pageX,ak.startX)-aa.container.offset().left,ai=(aa.high-aa.low),ah=aa.viewport_container.width();aa.update_location(Math.round(ag/ah*ai)+aa.low,Math.round(af/ah*ai)+aa.low)}).bind("dragend",function(ak,al){var ag=Math.min(ak.pageX,al.startX),af=Math.max(ak.pageX,al.startX),ai=(aa.high-aa.low),ah=aa.viewport_container.width(),aj=aa.low;aa.low=Math.round(ag/ah*ai)+aj;aa.high=Math.round(af/ah*ai)+aj;$(al.proxy).remove();aa.redraw()});this.add_label_track(new X(this,this.top_labeltrack));this.add_label_track(new X(this,this.nav_labeltrack));$(window).bind("resize",function(){aa.resize_window()});$(document).bind("redraw",function(){aa.redraw()});this.reset();$(window).trigger("resize");this.update_intro_div()},update_intro_div:function(){if(this.num_tracks===0){this.intro_div.show()}else{this.intro_div.hide()}},update_location:function(aa,ab){this.location_span.text(commatize(aa)+" - "+commatize(ab));this.nav_input.val(this.chrom+":"+commatize(aa)+"-"+commatize(ab))},load_chroms:function(ab,ac){ab.num=t;$.extend(ab,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var aa=this;$.ajax({url:chrom_url,data:ab,dataType:"json",success:function(ae){if(ae.chrom_info.length===0){alert("Invalid chromosome: "+ab.chrom);return}if(ae.reference){aa.add_label_track(new x(aa))}aa.chrom_data=ae.chrom_info;var ah='<option value="">Select Chrom/Contig</option>';for(var ag=0,ad=aa.chrom_data.length;ag<ad;ag++){var af=aa.chrom_data[ag].chrom;ah+='<option value="'+af+'">'+af+"</option>"}if(ae.prev_chroms){ah+='<option value="previous">Previous '+t+"</option>"}if(ae.next_chroms){ah+='<option value="next">Next '+t+"</option>"}aa.chrom_select.html(ah);if(ac){ac()}aa.chrom_start_index=ae.start_index},error:function(){alert("Could not load chroms for this dbkey:",aa.dbkey)}})},change_chrom:function(ae,ab,ag){if(!ae||ae==="None"){return}var ad=this;if(ae==="previous"){ad.load_chroms({low:this.chrom_start_index-t});return}if(ae==="next"){ad.load_chroms({low:this.chrom_start_index+t});return}var af=$.grep(ad.chrom_data,function(ai,aj){return ai.chrom===ae})[0];if(af===undefined){ad.load_chroms({chrom:ae},function(){ad.change_chrom(ae,ab,ag)});return}else{if(ae!==ad.chrom){ad.chrom=ae;ad.chrom_select.val(ad.chrom);ad.max_high=af.len-1;ad.reset();ad.redraw(true);for(var ah=0,aa=ad.tracks.length;ah<aa;ah++){var ac=ad.tracks[ah];if(ac.init){ac.init()}}}if(ab!==undefined&&ag!==undefined){ad.low=Math.max(ab,0);ad.high=Math.min(ag,ad.max_high)}ad.reset_overview();ad.redraw()}},go_to:function(ae){var ai=this,aa,ad,ab=ae.split(":"),ag=ab[0],ah=ab[1];if(ah!==undefined){try{var af=ah.split("-");aa=parseInt(af[0].replace(/,/g,""),10);ad=parseInt(af[1].replace(/,/g,""),10)}catch(ac){return false}}ai.change_chrom(ag,aa,ad)},move_fraction:function(ac){var aa=this;var ab=aa.high-aa.low;this.move_delta(ac*ab)},move_delta:function(ac){var aa=this;var ab=aa.high-aa.low;if(aa.low-ac<aa.max_low){aa.low=aa.max_low;aa.high=aa.max_low+ab}else{if(aa.high-ac>aa.max_high){aa.high=aa.max_high;aa.low=aa.max_high-ab}else{aa.high-=ac;aa.low-=ac}}aa.redraw()},add_track:function(aa){aa.view=this;aa.track_id=this.track_id_counter;this.tracks.push(aa);if(aa.init){aa.init()}aa.container_div.attr("id","track_"+aa.track_id);C(aa.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1;this.update_intro_div()},add_label_track:function(aa){aa.view=this;this.label_tracks.push(aa)},remove_track:function(ab){this.has_changes=true;delete this.tracks[this.tracks.indexOf(ab)];this.num_tracks-=1;var aa=this;ab.container_div.fadeOut("slow",function(){$(this).remove();aa.update_intro_div()})},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ah){var ag=this.high-this.low,af=this.low,ab=this.high;if(af<this.max_low){af=this.max_low}if(ab>this.max_high){ab=this.max_high}if(this.high!==0&&ag<this.min_separation){ab=af+this.min_separation}this.low=Math.floor(af);this.high=Math.ceil(ab);this.resolution=Math.pow(z,Math.ceil(Math.log((this.high-this.low)/M)/Math.log(z)));this.zoom_res=Math.pow(s,Math.max(0,Math.ceil(Math.log(this.resolution,s)/Math.log(s))));var aa=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=13;this.overview_box.css({left:aa,width:Math.max(ai,ae)}).show();if(ae<ai){this.overview_box.css("left",aa-(ai-ae)/2)}if(this.overview_highlight){this.overview_highlight.css({left:aa,width:ae})}this.update_location(this.low,this.high);if(!ah){for(var ac=0,ad=this.tracks.length;ac<ad;ac++){if(this.tracks[ac]&&this.tracks[ac].enabled){this.tracks[ac].draw()}}for(ac=0,ad=this.label_tracks.length;ac<ad;ac++){this.label_tracks[ac].draw()}}},zoom_in:function(ab,ac){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ad=this.high-this.low,ae=ad/2+this.low,aa=(ad/this.zoom_factor)/2;if(ab){ae=ab/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ae-aa);this.high=Math.round(ae+aa);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var ab=this.high-this.low,ac=ab/2+this.low,aa=(ab*this.zoom_factor)/2;this.low=Math.round(ac-aa);this.high=Math.round(ac+aa);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var o=function(ac,ag){this.track=ac;this.name=ag.name;this.params=[];var an=ag.params;for(var ad=0;ad<an.length;ad++){var ai=an[ad],ab=ai.name,am=ai.label,ae=unescape(ai.html),ao=ai.value,ak=ai.type;if(ak==="number"){this.params[this.params.length]=new g(ab,am,ae,ao,ai.min,ai.max)}else{if(ak=="select"){this.params[this.params.length]=new K(ab,am,ae,ao)}else{console.log("WARNING: unrecognized tool parameter type:",ab,ak)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aq){aq.stopPropagation()}).bind("click",function(aq){aq.stopPropagation()}).bind("dblclick",function(aq){aq.stopPropagation()});var al=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aj=this.params;var ah=this;$.each(this.params,function(ar,av){var au=$("<div>").addClass("param-row").appendTo(ah.parent_div);var aq=$("<div>").addClass("param-label").text(av.label).appendTo(au);var at=$("<div/>").addClass("slider").html(av.html).appendTo(au);at.find(":input").val(av.value);$("<div style='clear: both;'/>").appendTo(au)});this.parent_div.find("input").click(function(){$(this).select()});var ap=$("<div>").addClass("param-row").appendTo(this.parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ap);var aa=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);var ah=this;aa.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()})};n(o.prototype,{get_param_values_dict:function(){var aa={};this.parent_div.find(":input").each(function(){var ab=$(this).attr("name"),ac=$(this).val();aa[ab]=JSON.stringify(ac)});return aa},get_param_values:function(){var ab=[];var aa={};this.parent_div.find(":input").each(function(){var ac=$(this).attr("name"),ad=$(this).val();if(ac){ab[ab.length]=ad}});return ab},run_on_dataset:function(){var aa=this;aa.run({dataset_id:this.track.original_dataset_id,tool_id:aa.name},function(ab){show_modal(aa.name+" is Running",aa.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var aa={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},ac=this.track,ab=aa.tool_id+ac.tool_region_and_parameters_str(aa.chrom,aa.low,aa.high),ad;if(ac instanceof e){ad=new Q(ab,view,ac.hda_ldda,undefined,{},{},ac);ad.change_mode(ac.mode)}this.track.add_track(ad);ad.content_div.text("Starting job.");this.run(aa,function(ae){ad.dataset_id=ae.dataset_id;ad.content_div.text("Running job.");ad.init()})},run:function(ab,ac){$.extend(ab,this.get_param_values_dict());var aa=function(){$.getJSON(rerun_tool_url,ab,function(ad){if(ad==="no converter"){new_track.container_div.addClass("error");new_track.content_div.text(G)}else{if(ad.error){new_track.container_div.addClass("error");new_track.content_div.text(v+ad.message)}else{if(ad==="pending"){new_track.container_div.addClass("pending");new_track.content_div.text("Converting input data so that it can be easily reused.");setTimeout(aa,2000)}else{ac(ad)}}}})};aa()}});var K=function(ab,aa,ac,ad){this.name=ab;this.label=aa;this.html=ac;this.value=ad};var g=function(ac,ab,ae,af,ad,aa){K.call(this,ac,ab,ae,af);this.min=ad;this.max=aa};var h=function(ab,aa,ac,ad){this.name=ab;this.index=aa;this.tool_id=ac;this.tool_exp_name=ad};var R=function(ab,aa,ac,ad){h.call(this,ab,aa,ac,ad);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};n(R.prototype,{applies_to:function(aa){if(aa.length>this.index){return true}return false},keep:function(aa){if(!this.applies_to(aa)){return true}var ab=parseInt(aa[this.index]);return(isNaN(ab)||(ab>=this.low&&ab<=this.high))},update_attrs:function(ab){var aa=false;if(!this.applies_to(ab)){return aa}if(ab[this.index]<this.min){this.min=Math.floor(ab[this.index]);aa=true}if(ab[this.index]>this.max){this.max=Math.ceil(ab[this.index]);aa=true}return aa},update_ui_elt:function(){var ac=function(af,ad){var ae=ad-af;return(ae<=2?0.01:1)};var ab=this.slider.slider("option","min"),aa=this.slider.slider("option","max");if(this.min<ab||this.max>aa){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ac(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var W=function(ac,al){this.track=ac;this.filters=[];for(var ag=0;ag<al.length;ag++){var aa=al[ag],ab=aa.name,ak=aa.type,ai=aa.index,an=aa.tool_id,ad=aa.tool_exp_name;if(ak==="int"||ak==="float"){this.filters[ag]=new R(ab,ai,an,ad)}else{console.log("ERROR: unsupported filter: ",ab,ak)}}var aj=function(ao,ap,aq){ao.click(function(){var ar=ap.text();max=parseFloat(aq.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aq.slider("option","values")){input_size=2*input_size+1;multi_value=true}ap.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",ar).appendTo(ap).focus().select().click(function(at){at.stopPropagation()}).blur(function(){$(this).remove();ap.text(ar)}).keyup(function(ax){if(ax.keyCode===27){$(this).trigger("blur")}else{if(ax.keyCode===13){var av=aq.slider("option","min"),at=aq.slider("option","max"),aw=function(ay){return(isNaN(ay)||ay>at||ay<av)},au=$(this).val();if(!multi_value){au=parseFloat(au);if(aw(au)){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}else{au=au.split("-");au=[parseFloat(au[0]),parseFloat(au[1])];if(aw(au[0])||aw(au[1])){alert("Parameter value must be in the range ["+av+"-"+at+"]");return $(this)}}aq.slider((multi_value?"values":"value"),au)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(ao){ao.stopPropagation()}).bind("click",function(ao){ao.stopPropagation()}).bind("dblclick",function(ao){ao.stopPropagation()}).bind("keydown",function(ao){ao.stopPropagation()});var ae=this;$.each(this.filters,function(av,ap){var ar=$("<div/>").addClass("slider-row").appendTo(ae.parent_div);var ao=$("<div/>").addClass("slider-label").appendTo(ar);var ax=$("<span/>").addClass("slider-name").text(ap.name+" ").appendTo(ao);var aq=$("<span/>");var at=$("<span/>").addClass("slider-value").appendTo(ao).append("[").append(aq).append("]");var aw=$("<div/>").addClass("slider").appendTo(ar);ap.control_element=$("<div/>").attr("id",ap.name+"-filter-control").appendTo(aw);var au=[0,0];ap.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ay,az){au=az.values;aq.text(az.values[0]+"-"+az.values[1]);setTimeout(function(){if(az.values[0]==au[0]&&az.values[1]==au[1]){var aA=az.values;aq.text(aA[0]+"-"+aA[1]);ap.low=aA[0];ap.high=aA[1];ae.track.draw(true,true)}},50)},change:function(ay,az){ap.control_element.slider("option","slide").call(ap.control_element,ay,az)}});ap.slider=ap.control_element;ap.slider_label=aq;aj(at,aq,ap.control_element);$("<div style='clear: both;'/>").appendTo(ar)});if(this.filters.length!=0){var am=$("<div>").addClass("param-row").appendTo(this.parent_div);var ah=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(am);var af=this;ah.click(function(){af.run_on_dataset()})}};n(W.prototype,{reset_filters:function(){for(var aa=0;aa<this.filters.length;aa++){filter=this.filters[aa];filter.slider.slider("option","values",[filter.min,filter.max])}},run_on_dataset:function(){var ai=function(am,ak,al){if(!(ak in am)){am[ak]=al}return am[ak]};var ac={},aa,ab,ad;for(var ae=0;ae<this.filters.length;ae++){aa=this.filters[ae];if(aa.tool_id){if(aa.min!=aa.low){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" >= "+aa.low}if(aa.max!=aa.high){ab=ai(ac,aa.tool_id,[]);ab[ab.length]=aa.tool_exp_name+" <= "+aa.high}}}var ag=[];for(var aj in ac){ag[ag.length]=[aj,ac[aj]]}var ah=ag.length;(function af(aq,an){var al=an[0],am=al[0],ap=al[1],ao="("+ap.join(") and (")+")",ak={cond:ao,input:aq,target_dataset_id:aq,tool_id:am},an=an.slice(1);$.getJSON(run_tool_url,ak,function(ar){if(ar.error){show_modal("Filter Dataset","Error running tool "+am,{Close:hide_modal})}else{if(an.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{af(ar.dataset_id,an)}}})})(this.track.dataset_id,ag)}});var V=function(aa){this.track=aa.track;this.params=aa.params;this.values={};if(aa.saved_values){this.restore_values(aa.saved_values)}this.onchange=aa.onchange};n(V.prototype,{restore_values:function(aa){var ab=this;$.each(this.params,function(ac,ad){if(aa[ad.key]!==undefined){ab.values[ad.key]=aa[ad.key]}else{ab.values[ad.key]=ad.default_value}})},build_form:function(){var ab=this;var aa=$("<div />");$.each(this.params,function(af,ad){if(!ad.hidden){var ac="param_"+af;var ak=$("<div class='form-row' />").appendTo(aa);ak.append($("<label />").attr("for",ac).text(ad.label+":"));if(ad.type==="bool"){ak.append($('<input type="checkbox" />').attr("id",ac).attr("name",ac).attr("checked",ab.values[ad.key]))}else{if(ad.type==="color"){var ah=ab.values[ad.key];var ag=$("<input />").attr("id",ac).attr("name",ac).val(ah);var ai=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var ae=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ai);var aj=$("<div/>").appendTo(ae).farbtastic({width:100,height:100,callback:ag,color:ah});$("<div />").append(ag).append(ai).appendTo(ak).bind("click",function(al){ai.css({left:$(this).position().left+($(ag).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ai.hide();$(document).unbind("click.color-picker")});al.stopPropagation()})}else{ak.append($("<input />").attr("id",ac).attr("name",ac).val(ab.values[ad.key]))}}}});return aa},update_from_form:function(aa){var ac=this;var ab=false;$.each(this.params,function(ad,af){if(!af.hidden){var ag="param_"+ad;var ae=aa.find("#"+ag).val();if(af.type==="float"){ae=parseFloat(ae)}else{if(af.type==="int"){ae=parseInt(ae)}else{if(af.type==="bool"){ae=aa.find("#"+ag).is(":checked")}}}if(ae!==ac.values[af.key]){ac.values[af.key]=ae;ab=true}}});if(ab){this.onchange()}}});var b=function(ac,ab,aa){this.index=ac;this.low=ac*M*ab;this.high=(ac+1)*M*ab;this.resolution=ab;this.canvas=$("<div class='track-tile'/>").append(aa);this.stale=false};var l=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.max_val=ad};var L=function(ac,ab,aa,ad){b.call(this,ac,ab,aa);this.message=ad};var j=function(ab,aa,ae,ac,ad){this.name=ab;this.view=aa;this.parent_element=ae;this.data_url=(ac?ac:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ad?ad:H);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};n(j.prototype,{get_type:function(){if(this instanceof X){return"LabelTrack"}else{if(this instanceof x){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof S){return"ReadTrack"}else{if(this instanceof Q){return"ToolDataFeatureTrack"}else{if(this instanceof P){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var aa=this;aa.enabled=false;aa.tile_cache.clear();aa.data_manager.clear();aa.initial_canvas=undefined;aa.content_div.css("height","auto");aa.container_div.removeClass("nodata error pending");if(!aa.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id,chrom:aa.view.chrom},function(ab){if(!ab||ab==="error"||ab.kind==="error"){aa.container_div.addClass("error");aa.content_div.text(m);if(ab.message){var ad=aa.view.tracks.indexOf(aa);var ac=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+ab.message+"</pre>",{Close:hide_modal})});aa.content_div.append(ac)}}else{if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(G)}else{if(ab==="no data"||(ab.data!==undefined&&(ab.data===null||ab.data.length===0))){aa.container_div.addClass("nodata");aa.content_div.text(B)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text(q);setTimeout(function(){aa.init()},aa.data_query_wait)}else{if(ab.status==="data"){if(ab.valid_chroms){aa.valid_chroms=ab.valid_chroms;aa.make_name_popup_menu()}aa.content_div.text(U);if(aa.view.chrom){aa.content_div.text("");aa.content_div.css("height",aa.height_px+"px");aa.enabled=true;$.when(aa.predraw_init()).done(function(){aa.container_div.removeClass("nodata error pending");aa.draw()})}}}}}}})},predraw_init:function(){},update_name:function(aa){this.old_name=this.name;this.name=aa;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var J=function(ah,af,ai){var ab=this,aj=ab.view;this.filters_manager=(ah!==undefined?new W(this,ah):undefined);this.filters_available=false;this.filters_visible=false;this.tool=(af!==undefined&&obj_length(af)>0?new o(this,af):undefined);this.parent_track=ai;this.child_tracks=[];if(ab.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}ab.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();ab.container_div.append(ab.child_tracks_container);if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}if(ab.display_modes!==undefined){if(ab.mode_div===undefined){ab.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ab.header_div);var ac=(ab.track_config&&ab.track_config.values.mode?ab.track_config.values.mode:ab.display_modes[0]);ab.mode=ac;ab.mode_div.text(ac);var aa={};for(var ad=0,ag=ab.display_modes.length;ad<ag;ad++){var ae=ab.display_modes[ad];aa[ae]=function(ak){return function(){ab.change_mode(ak)}}(ae)}make_popupmenu(ab.mode_div,aa)}else{ab.mode_div.hide()}}this.make_name_popup_menu()};n(J.prototype,j.prototype,{change_mode:function(ab){var aa=this;aa.mode_div.text(ab);aa.mode=ab;aa.track_config.values.mode=ab;aa.tile_cache.clear();aa.draw()},make_name_popup_menu:function(){var ab=this;var aa={};aa["Edit configuration"]=function(){var ah=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},af=function(){ab.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ag=function(ai){if((ai.keyCode||ai.which)===27){ah()}else{if((ai.keyCode||ai.which)===13){af()}}};$(window).bind("keypress.check_enter_esc",ag);show_modal("Configure Track",ab.track_config.build_form(),{Cancel:ah,OK:af})};if(ab.filters_available>0){var ae=(ab.filters_div.is(":visible")?"Hide filters":"Show filters");aa[ae]=function(){ab.filters_visible=(ab.filters_div.is(":visible"));if(ab.filters_visible){ab.filters_manager.reset_filters()}ab.filters_div.toggle();ab.make_name_popup_menu()}}if(ab.tool){var ae=(ab.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");aa[ae]=function(){if(!ab.dynamic_tool_div.is(":visible")){ab.update_name(ab.name+ab.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";ab.revert_name()}ab.dynamic_tool_div.toggle();ab.make_name_popup_menu()}}if(ab.valid_chroms){aa["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+ab.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var ac=view;var ad=function(){$("#no-tracks").show()};if(this.parent_track){ac=this.parent_track;ad=function(){}}aa.Remove=function(){ac.remove_track(ab);if(ac.num_tracks===0){ad()}};make_popupmenu(ab.name_div,aa)},draw:function(aa,ac){if(!this.dataset_id){return}var au=this.view.low,ag=this.view.high,ai=ag-au,ak=this.view.container.width(),ae=ak/ai,al=this.view.resolution,ad=$("<div style='position: relative;'></div>"),am=function(aw,ax,av){return aw+"_"+ax+"_"+av};if(!ac){this.content_div.children().remove()}this.content_div.append(ad);this.max_height=0;var ao=Math.floor(au/al/M);var af=[];var ap=0;while((ao*M*al)<ag){var at=am(ak,ae,ao);var ah=this.tile_cache.get(at);var aq=ao*M*this.view.resolution;var ab=aq+M*this.view.resolution;if(!aa&&ah){af[af.length]=ah;this.show_tile(ah,ad,ae)}else{this.delayed_draw(aa,at,ao,al,ad,ae,af)}ao+=1;ap++}var aj=this;var ar=setInterval(function(){if(af.length===ap){clearInterval(ar);if(ac){var aA=aj.content_div.children();var aB=false;for(var az=aA.length-1,aF=0;az>=aF;az--){var ay=$(aA[az]);if(aB){ay.remove()}else{if(ay.children().length!==0){aB=true}}}}if(aj instanceof e&&aj.mode=="Histogram"){var aE=-1;for(var az=0;az<af.length;az++){var aH=af[az].max_val;if(aH>aE){aE=aH}}for(var az=0;az<af.length;az++){if(af[az].max_val!==aE){var aG=af[az];aG.canvas.remove();aj.delayed_draw(true,am(ak,ae,aG.index),aG.index,aG.resolution,ad,ae,[],{max:aE})}}}if(aj.filters_manager){var ax=aj.filters_manager.filters;for(var aD=0;aD<ax.length;aD++){ax[aD].update_ui_elt()}var aC=false;if(aj.example_feature){for(var aD=0;aD<ax.length;aD++){if(ax[aD].applies_to(aj.example_feature)){aC=true;break}}}if(aj.filters_available!==aC){aj.filters_available=aC;if(!aj.filters_available){aj.filters_div.hide()}aj.make_name_popup_menu()}}var av=false;for(var aw=0;aw<af.length;aw++){if(af[aw].message){av=true;break}}if(av){for(var aw=0;aw<af.length;aw++){aG=af[aw];if(!aG.message){aG.canvas.css("padding-top",A)}}}}},50);for(var an=0;an<this.child_tracks.length;an++){this.child_tracks[an].draw(aa,ac)}},delayed_draw:function(ab,ai,ac,ae,aj,am,ak,af){var ad=this,ag=ac*M*ae,al=ag+M*ae;var ah=function(av,an,ap,ao,at,au,aq){var ar=ad.draw_tile(an,ap,ao,au,aq);ad.tile_cache.set(ai,ar);if(ar===undefined){return}ad.show_tile(ar,at,au);ak[ak.length]=ar};var aa=setTimeout(function(){if(ag<=ad.view.high&&al>=ad.view.low){var an=(ab?undefined:ad.tile_cache.get(ai));if(an){ad.show_tile(an,aj,am);ak[ak.length]=an}else{$.when(ad.data_manager.get_data(ag,al,ae,ad.data_url_extra_params)).then(function(ao){n(ao,af);if(view.reference_track&&am>view.canvas_manager.char_width_px){$.when(view.reference_track.data_manager.get_data(ag,al,ae,view.reference_track.data_url_extra_params)).then(function(ap){ah(aa,ao,ae,ac,aj,am,ap)})}else{ah(aa,ao,ae,ac,aj,am)}})}}},50)},show_tile:function(ah,aj,ak){var ac=this,ab=ah.canvas,ag=ab;if(ah.message){var al=$("<div/>"),ai=$("<div/>").addClass("tile-message").text(ah.message).css({height:A-1,width:ah.canvas.width}).appendTo(al),ae=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(ai),aa=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(ai);al.append(ab);ag=al;ae.click(function(){ah.stale=true;ac.data_manager.get_more_data(ah.low,ah.high,ah.resolution,{},ac.data_manager.DEEP_DATA_REQ);ac.draw()}).dblclick(function(am){am.stopPropagation()});aa.click(function(){ah.stale=true;ac.data_manager.get_more_data(ah.low,ah.high,ah.resolution,{},ac.data_manager.BROAD_DATA_REQ);ac.draw()}).dblclick(function(am){am.stopPropagation()})}var af=this.view.high-this.view.low,ad=(ah.low-this.view.low)*ak;if(this.left_offset){ad-=this.left_offset}ag.css({position:"absolute",top:0,left:ad,height:""});aj.append(ag);ac.max_height=Math.max(ac.max_height,ag.height());ac.content_div.css("height",ac.max_height+"px");aj.children().css("height",ac.max_height+"px")},set_overview:function(){var aa=this.view;if(this.initial_canvas&&this.is_overview){aa.overview_close.show();aa.overview_viewport.append(this.initial_canvas);aa.overview_highlight.show().height(this.initial_canvas.height());aa.overview_viewport.height(this.initial_canvas.height()+aa.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(ac,aa,ad){var ab=this,ae=(ac!==undefined&&aa!==undefined&&ad!==undefined?ac+":"+aa+"-"+ad:"all");return" - region=["+ae+"], parameters=["+ab.tool.get_param_values().join(", ")+"]"},add_track:function(aa){aa.track_id=this.track_id+"_"+this.child_tracks.length;aa.container_div.attr("id","track_"+aa.track_id);this.child_tracks_container.append(aa.container_div);C(aa.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(aa);this.view.has_changes=true},remove_track:function(aa){aa.container_div.fadeOut("slow",function(){$(this).remove()})}});var X=function(aa,ab){this.hidden=true;j.call(this,null,aa,ab);this.container_div.addClass("label-track")};n(X.prototype,j.prototype,{draw:function(){var ac=this.view,ad=ac.high-ac.low,ag=Math.floor(Math.pow(10,Math.floor(Math.log(ad)/Math.log(10)))),aa=Math.floor(ac.low/ag)*ag,ae=this.view.container.width(),ab=$("<div style='position: relative; height: 1.3em;'></div>");while(aa<ac.high){var af=(aa-ac.low)/ad*ae;ab.append($("<div class='label'>"+commatize(aa)+"</div>").css({position:"absolute",left:af-1}));aa+=ag}this.content_div.children(":first").remove();this.content_div.append(ab)}});var x=function(aa){this.hidden=true;j.call(this,null,aa,aa.top_labeltrack);J.call(this);aa.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:aa.dbkey};this.data_manager=new E(y,this,false);this.tile_cache=new c(r)};n(x.prototype,J.prototype,{draw_tile:function(ai,af,ab,ak){var ae=this,ac=M*af;if(ak>this.view.canvas_manager.char_width_px){if(ai===null){ae.content_div.css("height","0px");return}var ad=this.view.canvas_manager.new_canvas();var aj=ad.getContext("2d");ad.width=Math.ceil(ac*ak+ae.left_offset);ad.height=ae.height_px;aj.font=aj.canvas.manager.default_font;aj.textAlign="center";for(var ag=0,ah=ai.length;ag<ah;ag++){var aa=Math.round(ag*ak);aj.fillText(ai[ag],aa+ae.left_offset,10)}return new b(ab,af,ad)}this.content_div.css("height","0px")}});var k=function(ae,ac,af,aa,ad){var ab=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,ae,ac,ac.viewport_container);J.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=af;this.dataset_id=aa;this.original_dataset_id=aa;this.data_manager=new N(y,this);this.tile_cache=new c(r);this.track_config=new V({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:ad,onchange:function(){ab.vertical_range=ab.prefs.max_value-ab.prefs.min_value;$("#linetrack_"+ab.track_id+"_minval").text(ab.prefs.min_value);$("#linetrack_"+ab.track_id+"_maxval").text(ab.prefs.max_value);ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};n(k.prototype,J.prototype,{add_resize_handle:function(){var aa=this;var ad=false;var ac=false;var ab=$("<div class='track-resize'>");$(aa.container_div).hover(function(){ad=true;ab.show()},function(){ad=false;if(!ac){ab.hide()}});ab.hide().bind("dragstart",function(ae,af){ac=true;af.original_height=$(aa.content_div).height()}).bind("drag",function(af,ag){var ae=Math.min(Math.max(ag.original_height+ag.deltaY,aa.min_height_px),aa.max_height_px);$(aa.content_div).css("height",ae);aa.height_px=ae;aa.draw(true)}).bind("dragend",function(ae,af){aa.tile_cache.clear();ac=false;if(!ad){ab.hide()}aa.track_config.values.height=aa.height_px}).appendTo(aa.container_div)},predraw_init:function(){var aa=this,ab=aa.view.tracks.indexOf(aa);aa.vertical_range=undefined;return $.getJSON(aa.data_url,{stats:true,chrom:aa.view.chrom,low:null,high:null,hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id},function(ac){aa.container_div.addClass("line-track");var ae=ac.data;if(isNaN(parseFloat(aa.prefs.min_value))||isNaN(parseFloat(aa.prefs.max_value))){aa.prefs.min_value=ae.min;aa.prefs.max_value=ae.max;$("#track_"+ab+"_minval").val(aa.prefs.min_value);$("#track_"+ab+"_maxval").val(aa.prefs.max_value)}aa.vertical_range=aa.prefs.max_value-aa.prefs.min_value;aa.total_frequency=ae.total_frequency;aa.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_minval").text(u(aa.prefs.min_value));var ad=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ab+"_maxval").text(u(aa.prefs.max_value));ad.css({position:"absolute",top:"24px",left:"10px"});ad.prependTo(aa.container_div);af.css({position:"absolute",bottom:"2px",left:"10px"});af.prependTo(aa.container_div)})},draw_tile:function(ak,ae,ab,aj){if(this.vertical_range===undefined){return}var af=ab*M*ae,ad=M*ae,aa=Math.ceil(ad*aj),ah=this.height_px;var ac=this.view.canvas_manager.new_canvas();ac.width=aa,ac.height=ah;var ai=ac.getContext("2d");var ag=new I.LinePainter(ak.data,af,af+ad,this.prefs,this.mode);ag.draw(ai,aa,ah);return new b(ab,ae,ac)}});var e=function(aa,af,ae,ai,ah,ac,ad,ag){var ab=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ah,onchange:function(){ab.tile_cache.clear();ab.draw()}});this.prefs=this.track_config.values;j.call(this,aa,af,af.viewport_container);J.call(this,ac,ad,ag);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ae;this.dataset_id=ai;this.original_dataset_id=ai;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new N(20,this);this.left_offset=200;this.painter=I.LinkedFeaturePainter};n(e.prototype,J.prototype,{update_auto_mode:function(aa){if(this.mode=="Auto"){if(aa=="no_detail"){aa="feature spans"}else{if(aa=="summary_tree"){aa="coverage histogram"}}this.mode_div.text("Auto ("+aa+")")}},incremental_slots:function(ae,ab,ad){var ac=this.view.canvas_manager.dummy_context,aa=this.inc_slots[ae];if(!aa||(aa.mode!==ad)){aa=new (p.FeatureSlotter)(ae,ad==="Pack",w,function(af){return ac.measureText(af)});aa.mode=ad;this.inc_slots[ae]=aa}return aa.slot_features(ab)},get_summary_tree_data:function(ae,ah,ac,ap){if(ap>ac-ah){ap=ac-ah}var al=Math.floor((ac-ah)/ap),ao=[],ad=0;var af=0,ag=0,ak,an=0,ai=[],am,aj;var ab=function(at,ar,au,aq){at[0]=ar+au*aq;at[1]=ar+(au+1)*aq};while(an<ap&&af!==ae.length){var aa=false;for(;an<ap&&!aa;an++){ab(ai,ah,an,al);for(ag=af;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){aa=true;break}}if(aa){break}}data_start_index=ag;ao[ao.length]=am=[ai[0],0];for(;ag<ae.length;ag++){ak=ae[ag].slice(1,3);if(is_overlap(ak,ai)){am[1]++}else{break}}if(am[1]>ad){ad=am[1]}an++}return{max:ad,delta:al,data:ao}},draw_tile:function(an,av,az,aj,ad){var ar=this,aB=az*M*av,ab=(az+1)*M*av,ap=ab-aB,at=Math.ceil(ap*aj),aq=this.mode,aF=25,ae=this.left_offset,ao,af;if(aq==="Auto"){if(an.dataset_type==="summary_tree"){aq=an.dataset_type}else{if(an.extra_info==="no_detail"){aq="no_detail"}else{var aE=an.data;if(this.view.high-this.view.low>F){aq="Squish"}else{aq="Pack"}}}this.update_auto_mode(aq)}if(aq==="summary_tree"||aq==="Histogram"){af=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var aa=$("<div />").addClass("yaxislabel");aa.text(an.max);aa.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});aa.prependTo(this.container_div);var ac=this.view.canvas_manager.new_canvas();ac.width=at+ae;ac.height=af+O;if(an.dataset_type!="summary_tree"){var ak=this.get_summary_tree_data(an.data,aB,ab,200);if(an.max){ak.max=an.max}an=ak}var aC=new I.SummaryTreePainter(an,aB,ab,this.prefs);var au=ac.getContext("2d");au.translate(ae,O);aC.draw(au,at,af);return new l(az,av,ac,an.max)}var ao,ah=1;if(aq==="no_detail"||aq==="Squish"||aq==="Pack"){ah=this.incremental_slots(aj,an.data,aq);ao=this.inc_slots[aj].slots}var ai=[];if(an.data){var al=this.filters_manager.filters;for(var aw=0,ay=an.data.length;aw<ay;aw++){var ag=an.data[aw];var ax=false;var am;for(var aA=0,aD=al.length;aA<aD;aA++){am=al[aA];am.update_attrs(ag);if(!am.keep(ag)){ax=true;break}}if(!ax){ai.push(ag)}}}var aC=new (this.painter)(ai,aB,ab,this.prefs,aq,ad);var af=aC.get_required_height(ah);var ac=this.view.canvas_manager.new_canvas();ac.width=at+ae;ac.height=af;var au=ac.getContext("2d");au.fillStyle=this.prefs.block_color;au.font=au.canvas.manager.default_font;au.textAlign="right";this.container_div.find(".yaxislabel").remove();if(an.data){this.example_feature=(an.data.length?an.data[0]:undefined);au.translate(ae,0);aC.draw(au,at,af,ao)}return new L(az,av,ac,an.message)}});var P=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.painter=I.VariantPainter};n(P.prototype,J.prototype,e.prototype);var S=function(ad,ab,af,aa,ac,ae){e.call(this,ad,ab,af,aa,ac,ae);this.track_config=new V({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ac,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.painter=I.ReadPainter;this.make_name_popup_menu()};n(S.prototype,J.prototype,e.prototype);var Q=function(ae,ac,ag,aa,ad,af,ab){e.call(this,ae,ac,ag,aa,ad,af,{},ab);this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};n(Q.prototype,J.prototype,e.prototype,{predraw_init:function(){var ab=this;var aa=function(){if(ab.data_manager.size()===0){setTimeout(aa,300)}else{ab.data_url=default_data_url;ab.data_query_wait=H;ab.dataset_state_url=converted_datasets_state_url;$.getJSON(ab.dataset_state_url,{dataset_id:ab.dataset_id,hda_ldda:ab.hda_ldda},function(ac){})}};aa()}});T.View=Y;T.LineTrack=k;T.FeatureTrack=e;T.ReadTrack=S};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(j,w){var t=j("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var m=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};m.prototype.default_prefs={};var u=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(x,B,D,E,z){m.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var n=function(z,B,x,y,A){m.call(this,z,B,x,y,A)};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,A,I,F){var D=this.data,G=this.view_start,K=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var N=this.view_end-this.view_start,M=A/N,z=this.get_row_height();for(var C=0,E=D.length;C<E;C++){var L=D[C],B=L[0],x=L[1],y=L[2],H=(F&&F[B]!==undefined?F[B]:null);if((x<K&&y>G)&&(this.mode=="Dense"||H!==null)){this.draw_element(J,this.mode,L,H,G,K,M,z,A)}}J.restore()},draw_element:function(D,z,F,B,A,C,E,y,x){}});var d=10,h=3,l=5,v=10,f=1,r=3,e=3,a=9,k=2,g="#ccc";var q=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=d}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=l}else{x=v}}}return x},draw_element:function(J,C,R,E,L,ab,af,ag,x){var O=R[0],ad=R[1],V=R[2],M=R[3],W=Math.floor(Math.max(0,(ad-L)*af)),K=Math.ceil(Math.min(x,Math.max(0,(V-L)*af))),U=(C==="Dense"?0:(0+E))*ag,I,Z,N=null,ah=null,A=this.prefs.block_color,Y=this.prefs.label_color;if(C=="Dense"){E=1}if(C==="no_detail"){J.fillStyle=A;J.fillRect(W,U+5,K-W,f)}else{var H=R[4],T=R[5],X=R[6],B=R[7];if(T&&X){N=Math.floor(Math.max(0,(T-L)*af));ah=Math.ceil(Math.min(x,Math.max(0,(X-L)*af)))}var ae,P;if(C==="Squish"||C==="Dense"){ae=1;P=e}else{ae=5;P=a}if(!B){if(R.strand){if(R.strand==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(R.strand==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}}else{J.fillStyle=A}J.fillRect(W,U,K-W,P)}else{var G,Q;if(C==="Squish"||C==="Dense"){J.fillStyle=g;G=U+Math.floor(e/2)+1;Q=1}else{if(H){var G=U;var Q=P;if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand")}}}else{J.fillStyle=g;G+=(e/2)+1;Q=1}}J.fillRect(W,G,K-W,Q);for(var ac=0,z=B.length;ac<z;ac++){var D=B[ac],y=Math.floor(Math.max(0,(D[0]-L)*af)),S=Math.ceil(Math.min(x,Math.max((D[1]-L)*af)));if(y>S){continue}J.fillStyle=A;J.fillRect(y,U+(P-ae)/2+1,S-y,ae);if(N!==undefined&&X>T&&!(y>ah||S<N)){var aa=Math.max(y,N),F=Math.min(S,ah);J.fillRect(aa,U+1,F-aa,P);if(B.length==1&&C=="Pack"){if(H==="+"){J.fillStyle=J.canvas.manager.get_pattern("right_strand_inv")}else{if(H==="-"){J.fillStyle=J.canvas.manager.get_pattern("left_strand_inv")}}if(aa+14<F){aa+=2;F-=2}J.fillRect(aa,U+1,F-aa,P)}}}}if(C==="Pack"&&ad>L){J.fillStyle=Y;if(L===0&&W-J.measureText(M).width<0){J.textAlign="left";J.fillText(M,K+k,U+8)}else{J.textAlign="right";J.fillText(M,W-k,U+8)}J.fillStyle=A}}}});var b=function(z,B,x,y,A){n.call(this,z,B,x,y,A)};t(b.prototype,n.prototype,{draw_element:function(Q,L,F,B,T,z,I,R,O){var F=data[i],H=F[0],P=F[1],A=F[2],K=F[3],D=Math.floor(Math.max(0,(P-T)*I)),G=Math.ceil(Math.min(O,Math.max(0,(A-T)*I))),C=(L==="Dense"?0:(0+B))*R,x,U,y=null,J=null;if(no_label){Q.fillStyle=block_color;Q.fillRect(D+left_offset,C+5,G-D,1)}else{var S=F[4],N=F[5],E=F[6];x=9;U=1;Q.fillRect(D+left_offset,C,G-D,x);if(L!=="Dense"&&K!==undefined&&P>T){Q.fillStyle=label_color;if(T===0&&D-Q.measureText(K).width<0){Q.textAlign="left";Q.fillText(K,G+2+left_offset,C+8)}else{Q.textAlign="right";Q.fillText(K,D-2+left_offset,C+8)}Q.fillStyle=block_color}var M=S+" / "+N;if(P>T&&Q.measureText(M).width<(G-D)){Q.fillStyle="white";Q.textAlign="center";Q.fillText(M,left_offset+D+(G-D)/2,C+8);Q.fillStyle=block_color}}}});var s=function(A,C,x,z,B,y){n.call(this,A,C,x,z,B);this.ref_seq=y};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=d}else{if(y==="Squish"){x=l}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(T,O,K,Y,z,S,H,E,D){T.textAlign="center";var R=this,y=[Y,z],N=0,U=0,Q=0;ref_seq=this.ref_seq,char_width_px=T.canvas.manager.char_width_px;var ad=[];if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){Q=Math.round(K/2)}if(!H){H=[[0,E.length]]}for(var L=0,W=H.length;L<W;L++){var I=H[L],A="MIDNSHP=X"[I[0]],M=I[1];if(A==="H"||A==="S"){N-=M}var F=S+N,ac=Math.floor(Math.max(0,(F-Y)*K)),G=Math.floor(Math.max(0,(F+M-Y)*K));if(ac===G){G+=1}switch(A){case"H":break;case"S":case"M":case"=":if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(Q>0){T.fillStyle=this.prefs.block_color;T.fillRect(ac-Q,D+1,G-ac,9);T.fillStyle=g;for(var aa=0,x=P.length;aa<x;aa++){if(this.prefs.show_differences&&ref_seq){var J=ref_seq[F-Y+aa];if(!J||J.toLowerCase()===P[aa].toLowerCase()){continue}}if(F+aa>=Y&&F+aa<=z){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab,D+9)}}}else{T.fillStyle=this.prefs.block_color;T.fillRect(ac,D+4,G-ac,e)}}U+=M;N+=M;break;case"N":T.fillStyle=g;T.fillRect(ac-Q,D+5,G-ac,1);N+=M;break;case"D":T.fillStyle="red";T.fillRect(ac-Q,D+4,G-ac,3);N+=M;break;case"P":break;case"I":var X=ac-Q;if(is_overlap([F,F+M],y)){var P=E.slice(U,U+M);if(this.prefs.show_insertions){var C=ac-(G-ac)/2;if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){T.fillStyle="yellow";T.fillRect(C-Q,D-9,G-ac,9);ad[ad.length]={type:"triangle",data:[X,D+4,5]};T.fillStyle=g;switch(seq_tile_overlap){case (OVERLAP_START):P=P.slice(Y-F);break;case (OVERLAP_END):P=P.slice(0,F-z);break;case (CONTAINED_BY):break;case (CONTAINS):P=P.slice(Y-F,F-z);break}for(var aa=0,x=P.length;aa<x;aa++){var ab=Math.floor(Math.max(0,(F+aa-Y)*K));T.fillText(P[aa],ab-(G-ac)/2,D)}}else{T.fillStyle="yellow";T.fillRect(C,D+(this.mode!=="Dense"?2:5),G-ac,(O!=="Dense"?e:r))}}else{if((O==="Pack"||this.mode==="Auto")&&E!==undefined&&K>char_width_px){ad[ad.length]={type:"text",data:[P.length,X,D+9]}}else{}}}U+=M;break;case"X":U+=M;break}}T.fillStyle="yellow";var Z,B,ae;for(var V=0;V<ad.length;V++){Z=ad[V];B=Z.type;ae=Z.data;if(B==="text"){T.save();T.font="bold "+T.font;T.fillText(ae[0],ae[1],ae[2]);T.restore()}else{if(B=="triangle"){p(T,ae[0],ae[1],ae[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+k-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-k-N,B+8)}Q.fillStyle=U}}});w.SummaryTreePainter=u;w.LinePainter=c;w.LinkedFeaturePainter=q;w.ReadPainter=s;w.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
--- a/static/scripts/trackster.js Fri Jul 15 10:33:02 2011 -0400
+++ b/static/scripts/trackster.js Mon Jul 18 15:09:49 2011 +0200
@@ -486,8 +486,11 @@
this.top_labeltrack = $("<div/>").addClass("top-labeltrack").appendTo(this.top_container);
// Viewport for dragging tracks in center
this.viewport_container = $("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);
- // Future overlay?
- this.intro_div = $("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();
+ // Introduction div shown when there are no tracks.
+ this.intro_div = $("<div/>").addClass("intro").appendTo(this.viewport_container).hide();
+ var add_tracks_button = $("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function () {
+ add_tracks();
+ });
// Another label track at bottom
this.nav_labeltrack = $("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);
// Navigation at top
@@ -536,7 +539,6 @@
this.chrom_select.bind("change", function() {
view.change_chrom(view.chrom_select.val());
});
- this.intro_div.show();
/*
this.content_div.bind("mousewheel", function( e, delta ) {
@@ -651,6 +653,16 @@
this.reset();
$(window).trigger("resize");
+ this.update_intro_div();
+ },
+ /** Show or hide intro div depending on view state. */
+ update_intro_div: function() {
+ if (this.num_tracks === 0) {
+ this.intro_div.show();
+ }
+ else {
+ this.intro_div.hide();
+ }
},
update_location: function(low, high) {
this.location_span.text( commatize(low) + ' - ' + commatize(high) );
@@ -735,12 +747,6 @@
// Switching to local chrom.
if (chrom !== view.chrom) {
view.chrom = chrom;
- if (!view.chrom) {
- // No chrom selected
- view.intro_div.show();
- } else {
- view.intro_div.hide();
- }
view.chrom_select.val(view.chrom);
view.max_high = found.len-1; // -1 because we're using 0-based indexing.
view.reset();
@@ -810,6 +816,7 @@
sortable( track.container_div, '.draghandle' );
this.track_id_counter += 1;
this.num_tracks += 1;
+ this.update_intro_div();
},
add_label_track: function (label_track) {
label_track.view = this;
@@ -817,9 +824,13 @@
},
remove_track: function(track) {
this.has_changes = true;
- track.container_div.fadeOut('slow', function() { $(this).remove(); });
delete this.tracks[this.tracks.indexOf(track)];
this.num_tracks -= 1;
+ var view = this;
+ track.container_div.fadeOut('slow', function() {
+ $(this).remove();
+ view.update_intro_div();
+ });
},
reset: function() {
this.low = this.max_low;
--- a/templates/tracks/browser.mako Fri Jul 15 10:33:02 2011 -0400
+++ b/templates/tracks/browser.mako Mon Jul 18 15:09:49 2011 +0200
@@ -86,6 +86,75 @@
return new_bookmark;
};
+ /**
+ * Use track data to add a track to a view.
+ * TODO: rename function?
+ */
+ var add_async_success = function(track_data) {
+ var td = track_data,
+ new_track = new addable_track_types[track_data.track_type](
+ track_data.name, view, track_data.hda_ldda, track_data.dataset_id,
+ track_data.prefs, track_data.filters, track_data.tool );
+ view.add_track(new_track);
+ // Should replace with live event but can't get working
+ sortable(new_track.container_div, ".draghandle");
+ view.has_changes = true;
+ $("#no-tracks").hide();
+ };
+
+ /**
+ * Use a popup grid to add more tracks.
+ */
+ var add_tracks = function() {
+ $.ajax({
+ url: "${h.url_for( action='list_histories' )}",
+ data: { "f-dbkey": view.dbkey },
+ error: function() { alert( "Grid failed" ); },
+ success: function(table_html) {
+ show_modal(
+ "Select datasets for new tracks",
+ table_html, {
+ "Cancel": function() {
+ hide_modal();
+ },
+ "Insert": function() {
+ var requests = [];
+ $('input[name=id]:checked,input[name=ldda_ids]:checked').each(function() {
+ var data,
+ id = $(this).val();
+ if ($(this).attr("name") === "id") {
+ data = { hda_id: id };
+ } else {
+ data = { ldda_id: id};
+ }
+ requests[requests.length] = $.ajax({
+ url: "${h.url_for( action='add_track_async' )}",
+ data: data,
+ dataType: "json",
+ });
+ });
+ // To preserve order, wait until there are definitions for all tracks and then add
+ // them sequentially.
+ $.when.apply($, requests).then(function() {
+ // jQuery always returns an Array for arguments, so need to look at first element
+ // to determine whether multiple requests were made and consequently how to
+ // map arguments to track definitions.
+ var track_defs = (arguments[0] instanceof Array ?
+ $.map(arguments, function(arg) { return arg[0]; }) :
+ [ arguments[0] ]
+ );
+ for (var i= 0; i < track_defs.length; i++) {
+ add_async_success(track_defs[i]);
+ }
+ });
+ hide_modal();
+ }
+ }
+ );
+ }
+ });
+ };
+
$(function() {
// Hide bookmarks by default right now.
parent.force_right_panel("hide");
@@ -170,19 +239,7 @@
return "There are unsaved changes to your visualization which will be lost.";
}
};
-
- var add_async_success = function(track_data) {
- var td = track_data,
- new_track = new addable_track_types[track_data.track_type](
- track_data.name, view, track_data.hda_ldda, track_data.dataset_id,
- track_data.prefs, track_data.filters, track_data.tool );
- view.add_track(new_track);
- // Should replace with live event but can't get working
- sortable(new_track.container_div, ".draghandle");
- view.has_changes = true;
- $("#no-tracks").hide();
- };
-
+
%if add_dataset is not None:
$.ajax({
url: "${h.url_for( action='add_track_async' )}",
@@ -195,56 +252,7 @@
$("#viz-options-button").css( "position", "relative" );
make_popupmenu( $("#viz-options-button"), {
- "Add Tracks": function() {
- // Use a popup grid to add more tracks
- $.ajax({
- url: "${h.url_for( action='list_histories' )}",
- data: { "f-dbkey": view.dbkey },
- error: function() { alert( "Grid failed" ); },
- success: function(table_html) {
- show_modal(
- "Select datasets for new tracks",
- table_html, {
- "Cancel": function() {
- hide_modal();
- },
- "Insert": function() {
- var requests = [];
- $('input[name=id]:checked,input[name=ldda_ids]:checked').each(function() {
- var data,
- id = $(this).val();
- if ($(this).attr("name") === "id") {
- data = { hda_id: id };
- } else {
- data = { ldda_id: id};
- }
- requests[requests.length] = $.ajax({
- url: "${h.url_for( action='add_track_async' )}",
- data: data,
- dataType: "json",
- });
- });
- // To preserve order, wait until there are definitions for all tracks and then add
- // them sequentially.
- $.when.apply($, requests).then(function() {
- // jQuery always returns an Array for arguments, so need to look at first element
- // to determine whether multiple requests were made and consequently how to
- // map arguments to track definitions.
- var track_defs = (arguments[0] instanceof Array ?
- $.map(arguments, function(arg) { return arg[0]; }) :
- [ arguments[0] ]
- );
- for (var i= 0; i < track_defs.length; i++) {
- add_async_success(track_defs[i]);
- }
- });
- hide_modal();
- }
- }
- );
- }
- });
- },
+ "Add Tracks": add_tracks,
"Save": function() {
// Show saving dialog box
show_modal("Saving...", "<img src='${h.url_for('/static/images/yui/rel_interstitial_loading.gif')}'/>");
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: guru: Fixed a bug in PCA tool - standard deviation & prop variance values are now sorted by PC order.
by Bitbucket 15 Jul '11
by Bitbucket 15 Jul '11
15 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/5952ac09af12/
changeset: 5952ac09af12
user: guru
date: 2011-07-15 16:33:02
summary: Fixed a bug in PCA tool - standard deviation & prop variance values are now sorted by PC order.
affected #: 4 files (70 bytes)
--- a/test-data/pca_out1.tabular Thu Jul 14 22:54:43 2011 +0200
+++ b/test-data/pca_out1.tabular Fri Jul 15 10:33:02 2011 -0400
@@ -1,6 +1,6 @@
#Component 1 2 3 4
-#Std. deviation 0.9598 0.1436 0.3839 1.706
-#Proportion of variance explained 0.2303 0.005152 0.03684 0.7277
+#Std. deviation 1.706 0.9598 0.3839 0.1436
+#Proportion of variance explained 0.7277 0.2303 0.03684 0.005152
#Loadings 1 2 3 4
c1 0.5224 -0.3723 0.721 0.262
c2 -0.2634 -0.9256 -0.242 -0.1241
--- a/test-data/pca_out3.tabular Thu Jul 14 22:54:43 2011 +0200
+++ b/test-data/pca_out3.tabular Fri Jul 15 10:33:02 2011 -0400
@@ -1,6 +1,6 @@
#Component 1 2 3 4
-#Std. deviation 0.4905 0.1534 0.2793 2.049
-#Proportion of variance explained 0.05302 0.005183 0.01719 0.9246
+#Std. deviation 2.049 0.4905 0.2793 0.1534
+#Proportion of variance explained 0.9246 0.05302 0.01719 0.005183
#Loadings 1 2 3 4
c1 0.3616 -0.6565 0.581 0.3173
c2 -0.08227 -0.7297 -0.5964 -0.3241
--- a/tools/multivariate_stats/pca.py Thu Jul 14 22:54:43 2011 +0200
+++ b/tools/multivariate_stats/pca.py Fri Jul 15 10:33:02 2011 -0400
@@ -83,10 +83,12 @@
ncomps = len(summary['sdev'])
if type(summary['sdev']) == type({}):
- comps = summary['sdev'].keys()
+ comps_unsorted = summary['sdev'].keys()
+ comps=[]
sd = summary['sdev'].values()
for i in range(ncomps):
- sd[comps.index('Comp.%s' %(i+1))] = summary['sdev'].values()[i]
+ sd[i] = summary['sdev'].values()[comps_unsorted.index('Comp.%s' %(i+1))]
+ comps.append('Comp.%s' %(i+1))
elif type(summary['sdev']) == type([]):
comps=[]
for i in range(ncomps):
--- a/tools/multivariate_stats/pca.xml Thu Jul 14 22:54:43 2011 +0200
+++ b/tools/multivariate_stats/pca.xml Fri Jul 15 10:33:02 2011 -0400
@@ -1,4 +1,4 @@
-<tool id="pca1" name="Principal Component Analysis" version="1.0.1">
+<tool id="pca1" name="Principal Component Analysis" version="1.0.2"><description></description><command interpreter="python">
pca.py
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Fix bug in trackster filtering of GFF datasets.
by Bitbucket 14 Jul '11
by Bitbucket 14 Jul '11
14 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/f2638528e904/
changeset: f2638528e904
user: jgoecks
date: 2011-07-14 22:54:43
summary: Fix bug in trackster filtering of GFF datasets.
affected #: 1 file (0 bytes)
--- a/lib/galaxy/visualization/tracks/data_providers.py Thu Jul 14 15:58:06 2011 -0400
+++ b/lib/galaxy/visualization/tracks/data_providers.py Thu Jul 14 22:54:43 2011 +0200
@@ -412,7 +412,7 @@
'type': 'int',
'index': filter_col,
'tool_id': 'Filter1',
- 'tool_exp_name': 'c5' } ]
+ 'tool_exp_name': 'c6' } ]
filter_col += 1
if isinstance( self.original_dataset.datatype, Gtf ):
# Create filters based on dataset metadata.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Another patch from Assaf Gordon for the cleanup_datasets.py script.
by Bitbucket 14 Jul '11
by Bitbucket 14 Jul '11
14 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/a3fc507f2b42/
changeset: a3fc507f2b42
user: greg
date: 2011-07-14 21:58:06
summary: Another patch from Assaf Gordon for the cleanup_datasets.py script.
This patch adds messages for the "purge histories" step:
1. A message is printed when processing a new history (so that the user can tell to which history the following dataset/hda messages belong).
2. in "info_only" mode, a message is printed about each deleted history
3. in "info_only" mode, a message is printed for each HDA that is checked
4. The message for HDA is changed to include the associated dataset id.
affected #: 1 file (784 bytes)
--- a/scripts/cleanup_datasets/cleanup_datasets.py Thu Jul 14 14:25:29 2011 -0400
+++ b/scripts/cleanup_datasets/cleanup_datasets.py Thu Jul 14 15:58:06 2011 -0400
@@ -170,6 +170,7 @@
app.model.History.table.c.update_time < cutoff_time ) ) \
.options( eagerload( 'datasets' ) )
for history in histories:
+ print "### Processing history id %d (%s)" % (history.id, history.name)
for dataset_assoc in history.datasets:
_purge_dataset_instance( dataset_assoc, app, remove_from_disk, info_only = info_only ) #mark a DatasetInstance as deleted, clear associated files, and mark the Dataset as deleted if it is deletable
if not info_only:
@@ -182,6 +183,8 @@
history.purged = True
app.sa_session.add( history )
app.sa_session.flush()
+ else:
+ print "History id %d will be purged (without 'info_only' mode)" % history.id
history_count += 1
stop = time.time()
print 'Purged %d histories.' % history_count
@@ -364,15 +367,24 @@
# A dataset_instance is either a HDA or an LDDA. Purging a dataset instance marks the instance as deleted,
# and marks the associated dataset as deleted if it is not associated with another active DatsetInstance.
if not info_only:
- print "Marking as deleted: ", dataset_instance.__class__.__name__, " id ", dataset_instance.id
+ print "Marking as deleted: %s id %d (for dataset id %d)" % \
+ ( dataset_instance.__class__.__name__, dataset_instance.id, dataset_instance.dataset.id )
dataset_instance.mark_deleted( include_children = include_children )
dataset_instance.clear_associated_files()
app.sa_session.add( dataset_instance )
app.sa_session.flush()
app.sa_session.refresh( dataset_instance.dataset )
+ else:
+ print "%s id %d (for dataset id %d) will be marked as deleted (without 'info_only' mode)" % \
+ ( dataset_instance.__class__.__name__, dataset_instance.id, dataset_instance.dataset.id )
if is_deletable or _dataset_is_deletable( dataset_instance.dataset ):
# Calling methods may have already checked _dataset_is_deletable, if so, is_deletable should be True
_delete_dataset( dataset_instance.dataset, app, remove_from_disk, info_only=info_only, is_deletable=is_deletable )
+ else:
+ if info_only:
+ print "Not deleting dataset ", dataset_instance.dataset.id, " (will be possibly deleted without 'info_only' mode)"
+ else:
+ print "Not deleting dataset %d (shared between multiple histories/libraries, at least one not deleted)" % dataset_instance.dataset.id
#need to purge children here
if include_children:
for child in dataset_instance.children:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Change tool shed repository version to be revision, and some fixes for generating and saving repository metadata.
by Bitbucket 14 Jul '11
by Bitbucket 14 Jul '11
14 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/e43c31f9e64c/
changeset: e43c31f9e64c
user: greg
date: 2011-07-14 20:25:29
summary: Change tool shed repository version to be revision, and some fixes for generating and saving repository metadata.
affected #: 6 files (984 bytes)
--- a/lib/galaxy/webapps/community/controllers/common.py Thu Jul 14 12:12:55 2011 +0200
+++ b/lib/galaxy/webapps/community/controllers/common.py Thu Jul 14 14:25:29 2011 -0400
@@ -75,14 +75,14 @@
.filter( and_( trans.model.RepositoryMetadata.table.c.repository_id == trans.security.decode_id( id ),
trans.model.RepositoryMetadata.table.c.changeset_revision == changeset_revision ) ) \
.first()
-def set_repository_metadata( trans, id, ctx_str, **kwd ):
+def set_repository_metadata( trans, id, change_set_revision, **kwd ):
"""Set repository metadata"""
message = ''
status = 'done'
repository = get_repository( trans, id )
repo_dir = repository.repo_path
repo = hg.repository( ui.ui(), repo_dir )
- change_set = get_change_set( trans, repo, ctx_str )
+ change_set = get_change_set( trans, repo, change_set_revision )
invalid_files = []
flush_needed = False
if change_set is not None:
@@ -103,7 +103,6 @@
full_path = os.path.abspath( os.path.join( root, name ) )
tool = load_tool( trans, full_path )
if tool is not None:
- repository_metadata = get_repository_metadata( trans, id, repository.tip )
tool_requirements = []
for tr in tool.requirements:
requirement_dict = dict( name=tr.name,
@@ -126,6 +125,7 @@
tool_config=os.path.join( root, name ),
requirements=tool_requirements,
tests=tool_tests )
+ repository_metadata = get_repository_metadata( trans, id, change_set_revision )
if repository_metadata:
metadata = repository_metadata.metadata
if metadata and 'tools' in metadata:
@@ -161,32 +161,39 @@
# Find all exported workflows
elif name.endswith( '.ga' ):
try:
- repository_metadata = get_repository_metadata( trans, id, repository.tip )
full_path = os.path.abspath( os.path.join( root, name ) )
# Convert workflow data from json
fp = open( full_path, 'rb' )
workflow_text = fp.read()
fp.close()
- workflow_dict = from_json_string( workflow_text )
+ exported_workflow_dict = from_json_string( workflow_text )
+ # We'll store everything except the workflow steps in the database.
+ workflow_dict = { 'a_galaxy_workflow' : exported_workflow_dict[ 'a_galaxy_workflow' ],
+ 'name' :exported_workflow_dict[ 'name' ],
+ 'annotation' : exported_workflow_dict[ 'annotation' ],
+ 'format-version' : exported_workflow_dict[ 'format-version' ] }
+ repository_metadata = get_repository_metadata( trans, id, change_set_revision )
if repository_metadata:
metadata = repository_metadata.metadata
- old_metadata_workflows = metadata[ 'workflows' ]
- new_metadata_workflows = []
- for workflow_metadata_dict in old_metadata_workflows:
- # TODO: what if 2 exported galaxy workflows have the same name, annotation, format-version?
- if 'a_galaxy_workflow' in workflow_metadata_dict and util.string_as_bool( workflow_metadata_dict[ 'a_galaxy_workflow' ] ) and \
- 'name' in workflow_metadata_dict and workflow_metadata_dict[ 'name' ] == workflow_dict[ 'name' ] and \
- 'annotation' in workflow_metadata_dict and workflow_metadata_dict[ 'annotation' ] == workflow_dict[ 'annotation' ] and \
- 'format-version' in workflow_metadata_dict and workflow_metadata_dict[ 'format-version' ] == workflow_dict[ 'format-version' ]:
- new_metadata_workflows.append( workflow_dict )
- else:
- new_metadata_workflows.append( workflow_metadata_dict )
- if metadata is None:
- repository_metadata.metadata = {}
- repository_metadata.metadata[ 'workflows' ] = new_metadata_workflows
- trans.sa_session.add( repository_metadata )
- if not flush_needed:
- flush_needed = True
+ if metadata and 'workflows' in metadata:
+ metadata_workflows = metadata[ 'workflows' ]
+ found = False
+ for workflow_metadata_dict in metadata_workflows:
+ if 'a_galaxy_workflow' in workflow_metadata_dict and util.string_as_bool( workflow_metadata_dict[ 'a_galaxy_workflow' ] ) and \
+ 'name' in workflow_metadata_dict and workflow_metadata_dict[ 'name' ] == exported_workflow_dict[ 'name' ] and \
+ 'annotation' in workflow_metadata_dict and workflow_metadata_dict[ 'annotation' ] == exported_workflow_dict[ 'annotation' ] and \
+ 'format-version' in workflow_metadata_dict and workflow_metadata_dict[ 'format-version' ] == exported_workflow_dict[ 'format-version' ]:
+ found = True
+ break
+ if not found:
+ metadata_workflows.append( workflow_dict )
+ else:
+ if metadata is None:
+ repository_metadata.metadata = {}
+ repository_metadata.metadata[ 'workflows' ] = workflow_dict
+ trans.sa_session.add( repository_metadata )
+ if not flush_needed:
+ flush_needed = True
else:
if 'workflows' in metadata_dict:
metadata_dict[ 'workflows' ].append( workflow_dict )
@@ -202,10 +209,10 @@
if not flush_needed:
flush_needed = True
else:
- message = "Repository does not include changeset revision '%s'." % str( ctx_str )
+ message = "Repository does not include changeset revision '%s'." % str( change_set_revision )
status = 'error'
if invalid_files:
- message = "Metadata cannot be defined for change set revision '%s'. Correct the following problems and reset metadata.<br/>" % str( ctx_str )
+ message = "Metadata cannot be defined for change set revision '%s'. Correct the following problems and reset metadata.<br/>" % str( change_set_revision )
for itc_tup in invalid_files:
message += "<b>%s</b> - %s<br/>" % ( itc_tup[0], itc_tup[1] )
status = 'error'
@@ -217,11 +224,11 @@
def get_repository_by_name( trans, name ):
"""Get a repository from the database via name"""
return trans.sa_session.query( app.model.Repository ).filter_by( name=name ).one()
-def get_change_set( trans, repo, ctx_str, **kwd ):
+def get_change_set( trans, repo, change_set_revision, **kwd ):
"""Retrieve a specified change set from a repository"""
for changeset in repo.changelog:
ctx = repo.changectx( changeset )
- if str( ctx ) == ctx_str:
+ if str( ctx ) == change_set_revision:
return ctx
return None
def get_user( trans, id ):
--- a/lib/galaxy/webapps/community/controllers/repository.py Thu Jul 14 12:12:55 2011 +0200
+++ b/lib/galaxy/webapps/community/controllers/repository.py Thu Jul 14 14:25:29 2011 -0400
@@ -74,9 +74,9 @@
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
return repository.name
- class VersionColumn( grids.TextColumn ):
+ class RevisionColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
- return repository.version
+ return repository.revision
class DescriptionColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
return repository.description
@@ -126,8 +126,8 @@
DescriptionColumn( "Synopsis",
key="description",
attach_popup=False ),
- VersionColumn( "Version",
- attach_popup=False ),
+ RevisionColumn( "Revision",
+ attach_popup=False ),
CategoryColumn( "Category",
model_class=model.Category,
key="Category.name",
@@ -878,7 +878,6 @@
folder_contents.append( node )
return folder_contents
def __get_files( self, trans, repository, folder_path ):
- ok = True
def print_ticks( d ):
pass
cmd = "ls -p '%s'" % folder_path
@@ -887,17 +886,22 @@
events={ pexpect.TIMEOUT : print_ticks },
timeout=10 )
if 'No such file or directory' in output:
- status = 'error'
- message = "No folder named (%s) exists." % folder_path
- ok = False
- if ok:
- return output.split()
- return trans.response.send_redirect( web.url_for( controller='repository',
- action='browse_repositories',
- operation="view_or_manage_repository",
- id=trans.security.encode_id( repository.id ),
- status=status,
- message=message ) )
+ if 'root' in output:
+ # The repository is empty
+ return []
+ else:
+ # Some strange error occurred, the selected file was displayed, but
+ # does not exist in the sub-directory from which it was displayed.
+ # This should not happen...
+ status = 'error'
+ message = "No folder named (%s) exists." % folder_path
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='browse_repositories',
+ operation="view_or_manage_repository",
+ id=trans.security.encode_id( repository.id ),
+ status=status,
+ message=message ) )
+ return output.split()
@web.json
def get_file_contents( self, trans, file_path ):
# Avoid caching
--- a/lib/galaxy/webapps/community/model/__init__.py Thu Jul 14 12:12:55 2011 +0200
+++ b/lib/galaxy/webapps/community/model/__init__.py Thu Jul 14 14:25:29 2011 -0400
@@ -114,7 +114,7 @@
return config.get( "paths", option )
raise Exception( "Entry for repository %s missing in %s/hgweb.config file." % ( lhs, os.getcwd() ) )
@property
- def version( self ):
+ def revision( self ):
repo = hg.repository( ui.ui(), self.repo_path )
tip_ctx = repo.changectx( repo.changelog.tip() )
return "%s:%s" % ( str( tip_ctx.rev() ), str( repo.changectx( repo.changelog.tip() ) ) )
--- a/templates/webapps/community/repository/manage_repository.mako Thu Jul 14 12:12:55 2011 +0200
+++ b/templates/webapps/community/repository/manage_repository.mako Thu Jul 14 14:25:29 2011 -0400
@@ -122,9 +122,9 @@
<div class="form-row"><label>Version:</label>
%if can_view_change_log:
- <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${repository.version}</a>
+ <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${repository.revision}</a>
%else:
- ${repository.version}
+ ${repository.revision}
%endif
</div><div class="form-row">
--- a/templates/webapps/community/repository/rate_repository.mako Thu Jul 14 12:12:55 2011 +0200
+++ b/templates/webapps/community/repository/rate_repository.mako Thu Jul 14 14:25:29 2011 -0400
@@ -104,7 +104,7 @@
</div><div class="form-row"><label>Version:</label>
- ${repository.version}
+ ${repository.revision}
<div style="clear: both"></div></div><div class="form-row">
--- a/templates/webapps/community/repository/view_repository.mako Thu Jul 14 12:12:55 2011 +0200
+++ b/templates/webapps/community/repository/view_repository.mako Thu Jul 14 14:25:29 2011 -0400
@@ -120,9 +120,9 @@
<div class="form-row"><label>Version:</label>
%if can_view_change_log:
- <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${repository.version}</a>
+ <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${repository.revision}</a>
%else:
- ${repository.version}
+ ${repository.revision}
%endif
</div><div class="form-row">
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Trackster: document FeaturePainter object and methods as abstract.
by Bitbucket 14 Jul '11
by Bitbucket 14 Jul '11
14 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/fd53d9688eb3/
changeset: fd53d9688eb3
user: jgoecks
date: 2011-07-14 12:12:55
summary: Trackster: document FeaturePainter object and methods as abstract.
affected #: 1 file (377 bytes)
--- a/static/scripts/trackster.js Wed Jul 13 16:51:51 2011 -0400
+++ b/static/scripts/trackster.js Thu Jul 14 12:12:55 2011 +0200
@@ -3307,6 +3307,9 @@
ctx.restore();
}
+/**
+ * Abstract object for painting feature tracks. Subclasses must implement draw_element() for painting to work.
+ */
var FeaturePainter = function( data, view_start, view_end, prefs, mode ) {
Painter.call( this, data, view_start, view_end, prefs, mode );
}
@@ -3327,7 +3330,6 @@
},
draw: function( ctx, width, height, slots ) {
-
var data = this.data, view_start = this.view_start, view_end = this.view_end;
ctx.save();
@@ -3356,7 +3358,12 @@
}
ctx.restore();
- }
+ },
+
+ /**
+ * Abstract function for drawing an individual feature. NOTE: this method must be implemented by subclasses for drawing to work.
+ */
+ draw_element: function(ctx, mode, feature, slot, tile_low, tile_high, w_scale, y_scale, width ) {}
});
// Constants specific to feature tracks moved here (HACKING, these should
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Add support for exproted Galaxy workflows when generating metadata for a tool shed repository.
by Bitbucket 13 Jul '11
by Bitbucket 13 Jul '11
13 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/31dda910849a/
changeset: 31dda910849a
user: greg
date: 2011-07-13 22:51:51
summary: Add support for exproted Galaxy workflows when generating metadata for a tool shed repository.
affected #: 4 files (6.6 KB)
--- a/lib/galaxy/webapps/community/controllers/common.py Wed Jul 13 09:39:02 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/common.py Wed Jul 13 16:51:51 2011 -0400
@@ -83,7 +83,7 @@
repo_dir = repository.repo_path
repo = hg.repository( ui.ui(), repo_dir )
change_set = get_change_set( trans, repo, ctx_str )
- invalid_tool_configs = []
+ invalid_files = []
flush_needed = False
if change_set is not None:
metadata_dict = {}
@@ -110,12 +110,22 @@
type=tr.type,
version=tr.version )
tool_requirements.append( requirement_dict )
- tool_dict = dict( id = tool.id,
- name = tool.name,
- version = tool.version,
- description = tool.description,
- tool_config = os.path.join( root, name ),
- requirements = tool_requirements )
+ tool_tests = []
+ if tool.tests:
+ for ttb in tool.tests:
+ test_dict = dict( name=ttb.name,
+ required_files=ttb.required_files,
+ inputs=ttb.inputs,
+ outputs=ttb.outputs )
+ tool_tests.append( test_dict )
+ tool_dict = dict( id=tool.id,
+ name=tool.name,
+ version=tool.version,
+ description=tool.description,
+ version_string_cmd = tool.version_string_cmd,
+ tool_config=os.path.join( root, name ),
+ requirements=tool_requirements,
+ tests=tool_tests )
if repository_metadata:
metadata = repository_metadata.metadata
if metadata and 'tools' in metadata:
@@ -127,8 +137,10 @@
found = True
tool_metadata_dict[ 'name' ] = tool.name
tool_metadata_dict[ 'description' ] = tool.description
+ tool_metadata_dict[ 'version_string_cmd' ] = tool.version_string_cmd
tool_metadata_dict[ 'tool_config' ] = os.path.join( root, name )
tool_metadata_dict[ 'requirements' ] = tool_requirements
+ tool_metadata_dict[ 'tests' ] = tool_tests
flush_needed = True
if not found:
metadata_tools.append( tool_dict )
@@ -145,7 +157,43 @@
else:
metadata_dict[ 'tools' ] = [ tool_dict ]
except Exception, e:
- invalid_tool_configs.append( ( name, str( e ) ) )
+ invalid_files.append( ( name, str( e ) ) )
+ # Find all exported workflows
+ elif name.endswith( '.ga' ):
+ try:
+ repository_metadata = get_repository_metadata( trans, id, repository.tip )
+ full_path = os.path.abspath( os.path.join( root, name ) )
+ # Convert workflow data from json
+ fp = open( full_path, 'rb' )
+ workflow_text = fp.read()
+ fp.close()
+ workflow_dict = from_json_string( workflow_text )
+ if repository_metadata:
+ metadata = repository_metadata.metadata
+ old_metadata_workflows = metadata[ 'workflows' ]
+ new_metadata_workflows = []
+ for workflow_metadata_dict in old_metadata_workflows:
+ # TODO: what if 2 exported galaxy workflows have the same name, annotation, format-version?
+ if 'a_galaxy_workflow' in workflow_metadata_dict and util.string_as_bool( workflow_metadata_dict[ 'a_galaxy_workflow' ] ) and \
+ 'name' in workflow_metadata_dict and workflow_metadata_dict[ 'name' ] == workflow_dict[ 'name' ] and \
+ 'annotation' in workflow_metadata_dict and workflow_metadata_dict[ 'annotation' ] == workflow_dict[ 'annotation' ] and \
+ 'format-version' in workflow_metadata_dict and workflow_metadata_dict[ 'format-version' ] == workflow_dict[ 'format-version' ]:
+ new_metadata_workflows.append( workflow_dict )
+ else:
+ new_metadata_workflows.append( workflow_metadata_dict )
+ if metadata is None:
+ repository_metadata.metadata = {}
+ repository_metadata.metadata[ 'workflows' ] = new_metadata_workflows
+ trans.sa_session.add( repository_metadata )
+ if not flush_needed:
+ flush_needed = True
+ else:
+ if 'workflows' in metadata_dict:
+ metadata_dict[ 'workflows' ].append( workflow_dict )
+ else:
+ metadata_dict[ 'workflows' ] = [ workflow_dict ]
+ except Exception, e:
+ invalid_files.append( ( name, str( e ) ) )
if metadata_dict:
# The metadata_dict dictionary will contain items only
# if the repository did not already have metadata set.
@@ -156,9 +204,9 @@
else:
message = "Repository does not include changeset revision '%s'." % str( ctx_str )
status = 'error'
- if invalid_tool_configs:
+ if invalid_files:
message = "Metadata cannot be defined for change set revision '%s'. Correct the following problems and reset metadata.<br/>" % str( ctx_str )
- for itc_tup in invalid_tool_configs:
+ for itc_tup in invalid_files:
message += "<b>%s</b> - %s<br/>" % ( itc_tup[0], itc_tup[1] )
status = 'error'
elif flush_needed:
--- a/templates/webapps/community/repository/manage_repository.mako Wed Jul 13 09:39:02 2011 -0400
+++ b/templates/webapps/community/repository/manage_repository.mako Wed Jul 13 16:51:51 2011 -0400
@@ -187,7 +187,13 @@
%if metadata:
%if 'tools' in metadata:
<div class="form-row">
- <label>Tools:</label>
+ <table width="100%">
+ <tr bgcolor="#D8D8D8" width="100%">
+ <td><label>Tools:</label></td>
+ </tr>
+ </table>
+ </div>
+ <div class="form-row"><% tool_dicts = metadata[ 'tools' ] %><table class="grid"><tr>
@@ -226,6 +232,34 @@
</div><div style="clear: both"></div>
%endif
+ %if 'workflows' in metadata:
+ <div class="form-row">
+ <table width="100%">
+ <tr bgcolor="#D8D8D8" width="100%">
+ <td><label>Workflows:</label></td>
+ </tr>
+ </table>
+ </div>
+ <div style="clear: both"></div>
+ <div class="form-row">
+ <% workflow_dicts = metadata[ 'workflows' ] %>
+ <table class="grid">
+ <tr>
+ <td><b>name</b></td>
+ <td><b>format-version</b></td>
+ <td><b>annotation</b></td>
+ </tr>
+ %for workflow_dict in workflow_dicts:
+ <tr>
+ <td>${workflow_dict[ 'name' ]}</td>
+ <td>${workflow_dict[ 'format-version' ]}</td>
+ <td>${workflow_dict[ 'annotation' ]}</td>
+ </tr>
+ %endfor
+ </table>
+ </div>
+ <div style="clear: both"></div>
+ %endif
%endif
<form name="set_metadata" action="${h.url_for( controller='repository', action='set_metadata', id=trans.security.encode_id( repository.id ), ctx_str=repository.tip )}" method="post"><div class="form-row">
--- a/templates/webapps/community/repository/view_changelog.mako Wed Jul 13 09:39:02 2011 -0400
+++ b/templates/webapps/community/repository/view_changelog.mako Wed Jul 13 16:51:51 2011 -0400
@@ -94,7 +94,7 @@
%><% display_date = changeset[ 'display_date' ] %>
%if test_date != display_date:
- <tr colspan="2"><td bgcolor="#D8D8D8 ">${display_date}</td></tr>
+ <tr colspan="2"><td bgcolor="#D8D8D8">${display_date}</td></tr>
%endif
<tr><td>
--- a/templates/webapps/community/repository/view_repository.mako Wed Jul 13 09:39:02 2011 -0400
+++ b/templates/webapps/community/repository/view_repository.mako Wed Jul 13 16:51:51 2011 -0400
@@ -166,7 +166,13 @@
<div class="toolFormBody">
%if 'tools' in metadata:
<div class="form-row">
- <label>Tools:</label>
+ <table width="100%">
+ <tr bgcolor="#D8D8D8" width="100%">
+ <td><label>Tools:</label></td>
+ </tr>
+ </table>
+ </div>
+ <div class="form-row"><% tool_dicts = metadata[ 'tools' ] %><table class="grid"><tr>
@@ -205,6 +211,34 @@
</div><div style="clear: both"></div>
%endif
+ %if 'workflows' in metadata:
+ <div class="form-row">
+ <table width="100%">
+ <tr bgcolor="#D8D8D8" width="100%">
+ <td><label>Workflows:</label></td>
+ </tr>
+ </table>
+ </div>
+ <div style="clear: both"></div>
+ <div class="form-row">
+ <% workflow_dicts = metadata[ 'workflows' ] %>
+ <table class="grid">
+ <tr>
+ <td><b>name</b></td>
+ <td><b>format-version</b></td>
+ <td><b>annotation</b></td>
+ </tr>
+ %for workflow_dict in workflow_dicts:
+ <tr>
+ <td>${workflow_dict[ 'name' ]}</td>
+ <td>${workflow_dict[ 'format-version' ]}</td>
+ <td>${workflow_dict[ 'annotation' ]}</td>
+ </tr>
+ %endfor
+ </table>
+ </div>
+ <div style="clear: both"></div>
+ %endif
</div></div>
%endif
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Add patch from Assaf Gordon to the cleanup_datasets.py script. The changes are:
by Bitbucket 13 Jul '11
by Bitbucket 13 Jul '11
13 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/b2f7abd50f6a/
changeset: b2f7abd50f6a
user: greg
date: 2011-07-13 15:39:02
summary: Add patch from Assaf Gordon to the cleanup_datasets.py script. The changes are:
1. If a dataset is skipped (because it's shared/cloned and was already process), no message is printed at all.
2. If a dataset can not be deleted because it is shared, and one instance is not marked as "deleted", a proper message is printed.
3. If a dataset has metadata files, the message is changed depending on "info_only" and "remove_from_disk" flags.
4. The final summary message is slightly changed.
affected #: 1 file (514 bytes)
--- a/scripts/cleanup_datasets/cleanup_datasets.py Tue Jul 12 18:14:56 2011 -0400
+++ b/scripts/cleanup_datasets/cleanup_datasets.py Wed Jul 13 09:39:02 2011 -0400
@@ -310,17 +310,21 @@
dataset_ids.extend( [ row.id for row in history_dataset_ids_query.execute() ] )
# Process each of the Dataset objects
for dataset_id in dataset_ids:
+ dataset = app.sa_session.query( app.model.Dataset ).get( dataset_id )
+ if dataset.id in skip:
+ continue
+ skip.append( dataset.id )
print "######### Processing dataset id:", dataset_id
- dataset = app.sa_session.query( app.model.Dataset ).get( dataset_id )
- if dataset.id not in skip and _dataset_is_deletable( dataset ):
- deleted_dataset_count += 1
- for dataset_instance in dataset.history_associations + dataset.library_associations:
- # Mark each associated HDA as deleted
- _purge_dataset_instance( dataset_instance, app, remove_from_disk, include_children=True, info_only=info_only, is_deletable=True )
- deleted_instance_count += 1
- skip.append( dataset.id )
+ if not _dataset_is_deletable( dataset ):
+ print "Dataset is not deletable (shared between multiple histories/libraries, at least one is not deleted)"
+ continue
+ deleted_dataset_count += 1
+ for dataset_instance in dataset.history_associations + dataset.library_associations:
+ # Mark each associated HDA as deleted
+ _purge_dataset_instance( dataset_instance, app, remove_from_disk, include_children=True, info_only=info_only, is_deletable=True )
+ deleted_instance_count += 1
stop = time.time()
- print "Examined %d datasets, marked %d as deleted and purged %d dataset instances" % ( len( skip ), deleted_dataset_count, deleted_instance_count )
+ print "Examined %d datasets, marked %d datasets and %d dataset instances (HDA) as deleted" % ( len( skip ), deleted_dataset_count, deleted_instance_count )
print "Total elapsed time: ", stop - start
print "##########################################"
@@ -396,8 +400,13 @@
.filter( app.model.MetadataFile.table.c.lda_id==ldda.id ):
metadata_files.append( metadata_file )
for metadata_file in metadata_files:
- print "The following metadata files attached to associations of Dataset '%s' have been purged:" % dataset.id
- if not info_only:
+ op_description = "marked as deleted"
+ if remove_from_disk:
+ op_description = op_description + " and purged from disk"
+ if info_only:
+ print "The following metadata files attached to associations of Dataset '%s' will be %s (without 'info_only' mode):" % ( dataset.id, op_description )
+ else:
+ print "The following metadata files attached to associations of Dataset '%s' have been %s:" % ( dataset.id, op_description )
if remove_from_disk:
try:
print "Removing disk file ", metadata_file.file_name
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: kanwei: Improve BLAST parser tool error handling, and improve elementtree import as well.
by Bitbucket 12 Jul '11
by Bitbucket 12 Jul '11
12 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/26bffb1b7d57/
changeset: 26bffb1b7d57
user: kanwei
date: 2011-07-13 00:14:56
summary: Improve BLAST parser tool error handling, and improve elementtree import as well.
affected #: 3 files (260 bytes)
--- a/tools/metag_tools/megablast_xml_parser.py Tue Jul 12 17:04:16 2011 -0400
+++ b/tools/metag_tools/megablast_xml_parser.py Tue Jul 12 18:14:56 2011 -0400
@@ -2,12 +2,12 @@
import sys, os, re
-assert sys.version_info[:2] >= ( 2, 4 )
-
if sys.version_info[:2] >= ( 2, 5 ):
- import xml.etree.cElementTree as cElementTree
+ import xml.etree.cElementTree as ElementTree
else:
- import cElementTree
+ from galaxy import eggs
+ import pkg_resources; pkg_resources.require( "elementtree" )
+ from elementtree import ElementTree
def stop_err( msg ):
sys.stderr.write( "%s\n" % msg )
@@ -34,7 +34,7 @@
# get an iterable
try:
- context = cElementTree.iterparse( source, events=( "start", "end" ) )
+ context = ElementTree.iterparse( source, events=( "start", "end" ) )
except:
stop_err( "Invalid data format." )
# turn it into an iterator
@@ -46,7 +46,7 @@
stop_err( "Invalid data format." )
outfile = open( sys.argv[2], 'w' )
- try:
+ try:
for event, elem in context:
# for every <Iteration> tag
if event == "end" and elem.tag == "Iteration":
@@ -71,7 +71,7 @@
elem.clear()
except:
outfile.close()
- stop_err( "The input data contains tags that are not recognizable by the tool." )
+ stop_err( "The input data is malformed, or there is more than one dataset in the input file. Error: %s" % sys.exc_info()[1] )
outfile.close()
--- a/tools/metag_tools/megablast_xml_parser.xml Tue Jul 12 17:04:16 2011 -0400
+++ b/tools/metag_tools/megablast_xml_parser.xml Tue Jul 12 18:14:56 2011 -0400
@@ -2,26 +2,23 @@
<description></description><command interpreter="python">megablast_xml_parser.py $input1 $output1</command><inputs>
- <param name="input1" type="data" format="blastxml" label="Megablast XML output" />
+ <param name="input1" type="data" format="blastxml" label="Megablast XML output" /></inputs><outputs>
- <data name="output1" format="tabular"/>
+ <data name="output1" format="tabular"/></outputs>
-<requirements>
- <requirement type="python-module">cElementTree</requirement>
-</requirements><tests>
- <test>
- <param name="input1" value="megablast_xml_parser_test1.gz" ftype="blastxml" />
- <output name="output1" file="megablast_xml_parser_test1_out.tabular" ftype="tabular" />
- </test>
+ <test>
+ <param name="input1" value="megablast_xml_parser_test1.gz" ftype="blastxml" />
+ <output name="output1" file="megablast_xml_parser_test1_out.tabular" ftype="tabular" />
+ </test></tests><help>
**What it does**
This tool processes the XML output of any NCBI blast tool (if you run your own blast jobs, the XML output can be generated with **-m 7** option).
-
+
-----
**Output fields**
--- a/tools/ncbi_blast_plus/blastxml_to_tabular.py Tue Jul 12 17:04:16 2011 -0400
+++ b/tools/ncbi_blast_plus/blastxml_to_tabular.py Tue Jul 12 18:14:56 2011 -0400
@@ -5,7 +5,7 @@
BLAST filename, output format (std for standard 12 columns, or ext for the
extended 24 columns offered in the BLAST+ wrappers).
-The 12 colums output are 'qseqid sseqid pident length mismatch gapopen qstart
+The 12 columns output are 'qseqid sseqid pident length mismatch gapopen qstart
qend sstart send evalue bitscore' or 'std' at the BLAST+ command line, which
mean:
@@ -51,22 +51,23 @@
Be aware that the sequence in the extended tabular output or XML direct from
BLAST+ may or may not use XXXX masking on regions of low complexity. This
can throw the off the calculation of percentage identity and gap openings.
-[In fact, both BLAST 2.2.24+ and 2.2.25+ have a sutle bug in this regard,
+[In fact, both BLAST 2.2.24+ and 2.2.25+ have a subtle bug in this regard,
with these numbers changing depending on whether or not the low complexity
filter is used.]
-This script attempts to produce idential output to what BLAST+ would have done.
+This script attempts to produce identical output to what BLAST+ would have done.
However, check this with "diff -b ..." since BLAST+ sometimes includes an extra
space character (probably a bug).
"""
import sys
import re
-assert sys.version_info[:2] >= ( 2, 4 )
if sys.version_info[:2] >= ( 2, 5 ):
- import xml.etree.cElementTree as cElementTree
+ import xml.etree.cElementTree as ElementTree
else:
- import cElementTree
+ from galaxy import eggs
+ import pkg_resources; pkg_resources.require( "elementtree" )
+ from elementtree import ElementTree
def stop_err( msg ):
sys.stderr.write("%s\n" % msg)
@@ -90,7 +91,7 @@
# get an iterable
try:
- context = cElementTree.iterparse(in_file, events=("start", "end"))
+ context = ElementTree.iterparse(in_file, events=("start", "end"))
except:
stop_err("Invalid data format.")
# turn it into an iterator
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: kanwei: Rename version_string -> version_command, update wrappers
by Bitbucket 12 Jul '11
by Bitbucket 12 Jul '11
12 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/12cb939a8147/
changeset: 12cb939a8147
user: kanwei
date: 2011-07-12 23:04:16
summary: Rename version_string -> version_command, update wrappers
affected #: 7 files (31 bytes)
--- a/lib/galaxy/tools/__init__.py Thu Jul 07 11:19:33 2011 +0100
+++ b/lib/galaxy/tools/__init__.py Tue Jul 12 17:04:16 2011 -0400
@@ -397,8 +397,9 @@
self.description = util.xml_text(root, "description")
# Versioning for tools
self.version_string_cmd = None
- if root.find("version_string") is not None:
- self.version_string_cmd = root.find("version_string").text
+ version_cmd = root.find("version_command")
+ if version_cmd is not None:
+ self.version_string_cmd = version_cmd.text
# Parallelism for tasks, read from tool config.
parallelism = root.find("parallelism")
if parallelism is not None and parallelism.get("method"):
--- a/tools/ncbi_blast_plus/ncbi_blastn_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
+++ b/tools/ncbi_blast_plus/ncbi_blastn_wrapper.xml Tue Jul 12 17:04:16 2011 -0400
@@ -1,6 +1,6 @@
<tool id="ncbi_blastn_wrapper" name="NCBI BLAST+ blastn" version="0.0.11"><description>Search nucleotide database with nucleotide query sequence(s)</description>
- <version_string>blastn -version</version_string>
+ <version_command>blastn -version</version_command><command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
--- a/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
+++ b/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Tue Jul 12 17:04:16 2011 -0400
@@ -1,6 +1,6 @@
<tool id="ncbi_blastp_wrapper" name="NCBI BLAST+ blastp" version="0.0.11"><description>Search protein database with protein query sequence(s)</description>
- <version_string>blastp -version</version_string>
+ <version_command>blastp -version</version_command><command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
--- a/tools/ncbi_blast_plus/ncbi_blastx_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
+++ b/tools/ncbi_blast_plus/ncbi_blastx_wrapper.xml Tue Jul 12 17:04:16 2011 -0400
@@ -1,6 +1,6 @@
<tool id="ncbi_blastx_wrapper" name="NCBI BLAST+ blastx" version="0.0.11"><description>Search protein database with translated nucleotide query sequence(s)</description>
- <version_string>blastx -version</version_string>
+ <version_command>blastx -version</version_command><command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
--- a/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
+++ b/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Tue Jul 12 17:04:16 2011 -0400
@@ -1,6 +1,6 @@
<tool id="ncbi_tblastn_wrapper" name="NCBI BLAST+ tblastn" version="0.0.11"><description>Search translated nucleotide database with protein query sequence(s)</description>
- <version_string>tblastn -version</version_string>
+ <version_command>tblastn -version</version_command><command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
--- a/tools/ncbi_blast_plus/ncbi_tblastx_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
+++ b/tools/ncbi_blast_plus/ncbi_tblastx_wrapper.xml Tue Jul 12 17:04:16 2011 -0400
@@ -1,6 +1,6 @@
<tool id="ncbi_tblastx_wrapper" name="NCBI BLAST+ tblastx" version="0.0.11"><description>Search translated nucleotide database with translated nucleotide query sequence(s)</description>
- <version_string>tblastx -version</version_string>
+ <version_command>tblastx -version</version_command><command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
--- a/tools/ngs_rna/tophat_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
+++ b/tools/ngs_rna/tophat_wrapper.xml Tue Jul 12 17:04:16 2011 -0400
@@ -1,6 +1,6 @@
<tool id="tophat" name="Tophat for Illumina" version="1.5.0"><description>Find splice junctions using RNA-seq data</description>
- <version_string>tophat --version</version_string>
+ <version_command>tophat --version</version_command><requirements><requirement type="package">tophat</requirement></requirements>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: peterjc: Support new tool version tag in NCBI BLAST+ wrappers
by Bitbucket 12 Jul '11
by Bitbucket 12 Jul '11
12 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/632d4c48d97c/
changeset: 632d4c48d97c
user: peterjc
date: 2011-07-07 12:19:33
summary: Support new tool version tag in NCBI BLAST+ wrappers
affected #: 5 files (267 bytes)
--- a/tools/ncbi_blast_plus/ncbi_blastn_wrapper.xml Tue Jul 12 15:02:37 2011 -0400
+++ b/tools/ncbi_blast_plus/ncbi_blastn_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
@@ -1,5 +1,6 @@
-<tool id="ncbi_blastn_wrapper" name="NCBI BLAST+ blastn" version="0.0.10">
+<tool id="ncbi_blastn_wrapper" name="NCBI BLAST+ blastn" version="0.0.11"><description>Search nucleotide database with nucleotide query sequence(s)</description>
+ <version_string>blastn -version</version_string><command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
--- a/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Tue Jul 12 15:02:37 2011 -0400
+++ b/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
@@ -1,5 +1,6 @@
-<tool id="ncbi_blastp_wrapper" name="NCBI BLAST+ blastp" version="0.0.10">
+<tool id="ncbi_blastp_wrapper" name="NCBI BLAST+ blastp" version="0.0.11"><description>Search protein database with protein query sequence(s)</description>
+ <version_string>blastp -version</version_string><command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
--- a/tools/ncbi_blast_plus/ncbi_blastx_wrapper.xml Tue Jul 12 15:02:37 2011 -0400
+++ b/tools/ncbi_blast_plus/ncbi_blastx_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
@@ -1,5 +1,6 @@
-<tool id="ncbi_blastx_wrapper" name="NCBI BLAST+ blastx" version="0.0.10">
+<tool id="ncbi_blastx_wrapper" name="NCBI BLAST+ blastx" version="0.0.11"><description>Search protein database with translated nucleotide query sequence(s)</description>
+ <version_string>blastx -version</version_string><command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
--- a/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Tue Jul 12 15:02:37 2011 -0400
+++ b/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
@@ -1,5 +1,6 @@
-<tool id="ncbi_tblastn_wrapper" name="NCBI BLAST+ tblastn" version="0.0.10">
+<tool id="ncbi_tblastn_wrapper" name="NCBI BLAST+ tblastn" version="0.0.11"><description>Search translated nucleotide database with protein query sequence(s)</description>
+ <version_string>tblastn -version</version_string><command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
--- a/tools/ncbi_blast_plus/ncbi_tblastx_wrapper.xml Tue Jul 12 15:02:37 2011 -0400
+++ b/tools/ncbi_blast_plus/ncbi_tblastx_wrapper.xml Thu Jul 07 11:19:33 2011 +0100
@@ -1,5 +1,6 @@
-<tool id="ncbi_tblastx_wrapper" name="NCBI BLAST+ tblastx" version="0.0.10">
+<tool id="ncbi_tblastx_wrapper" name="NCBI BLAST+ tblastx" version="0.0.11"><description>Search translated nucleotide database with translated nucleotide query sequence(s)</description>
+ <version_string>tblastx -version</version_string><command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/661aca672402/
changeset: 661aca672402
user: greg
date: 2011-07-12 21:02:37
summary: Fix for displaying tools.
affected #: 1 file (14 bytes)
--- a/templates/webapps/community/repository/tool_form.mako Tue Jul 12 13:51:28 2011 -0400
+++ b/templates/webapps/community/repository/tool_form.mako Tue Jul 12 15:02:37 2011 -0400
@@ -84,7 +84,7 @@
field = SelectField( param.name )
field.add_option( param.name, param.name )
field_html = field.get_html()
- elif isinstance( param, SelectToolParameter ) and param.data_ref:
+ elif isinstance( param, SelectToolParameter ) and hasattr( param, 'data_ref' ):
field = SelectField( param.name, display=param.display )
field.add_option( param.data_ref, param.data_ref )
field_html = field.get_html( prefix )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Make a backup copy of the tool shed's hgweb.config file just before changes are made to it. Add the ability for a repository owner to change categories associated with their repository.
by Bitbucket 12 Jul '11
by Bitbucket 12 Jul '11
12 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/af9b19b57969/
changeset: af9b19b57969
user: greg
date: 2011-07-12 19:51:28
summary: Make a backup copy of the tool shed's hgweb.config file just before changes are made to it. Add the ability for a repository owner to change categories associated with their repository.
affected #: 4 files (3.8 KB)
--- a/lib/galaxy/webapps/community/controllers/repository.py Tue Jul 12 10:07:15 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Tue Jul 12 13:51:28 2011 -0400
@@ -356,11 +356,19 @@
if not( VALID_REPOSITORYNAME_RE.match( name ) ):
return "Repository names must contain only lower-case letters, numbers and underscore '_'."
return ''
+ def __make_hgweb_config_copy( self, trans, hgweb_config ):
+ # Make a backup of the hgweb.config file
+ today = date.today()
+ backup_date = today.strftime( "%Y_%m_%d" )
+ hgweb_config_copy = '%s/hgweb.config_%s_backup' % ( trans.app.config.root, backup_date )
+ shutil.copy( os.path.abspath( hgweb_config ), os.path.abspath( hgweb_config_copy ) )
def __add_hgweb_config_entry( self, trans, repository, repository_path ):
# Add an entry in the hgweb.config file for a new repository.
# An entry looks something like:
# repos/test/mira_assembler = database/community_files/000/repo_123.
hgweb_config = "%s/hgweb.config" % trans.app.config.root
+ # Make a backup of the hgweb.config file since we're going to be changing it.
+ self.__make_hgweb_config_copy( trans, hgweb_config )
entry = "repos/%s/%s = %s" % ( repository.user.username, repository.name, repository_path.lstrip( './' ) )
if os.path.exists( hgweb_config ):
output = open( hgweb_config, 'a' )
@@ -374,6 +382,8 @@
# the owner changes the name of the repository. An entry looks something like:
# repos/test/mira_assembler = database/community_files/000/repo_123.
hgweb_config = "%s/hgweb.config" % trans.app.config.root
+ # Make a backup of the hgweb.config file since we're going to be changing it.
+ self.__make_hgweb_config_copy( trans, hgweb_config )
repo_dir = repository.repo_path
old_lhs = "repos/%s/%s" % ( repository.user.username, old_repository_name )
old_entry = "%s = %s" % ( old_lhs, repo_dir )
@@ -537,6 +547,7 @@
display_reviews = util.string_as_bool( params.get( 'display_reviews', False ) )
alerts = params.get( 'alerts', '' )
alerts_checked = CheckboxField.is_checked( alerts )
+ category_ids = util.listify( params.get( 'category_id', '' ) )
if repository.email_alerts:
email_alerts = from_json_string( repository.email_alerts )
else:
@@ -572,7 +583,21 @@
if flush_needed:
trans.sa_session.add( repository )
trans.sa_session.flush()
- message = "The repository information has been updated."
+ message = "The repository information has been updated."
+ elif params.get( 'manage_categories_button', False ):
+ flush_needed = False
+ # Delete all currently existing categories.
+ for rca in repository.categories:
+ trans.sa_session.delete( rca )
+ trans.sa_session.flush()
+ if category_ids:
+ # Create category associations
+ for category_id in category_ids:
+ category = trans.app.model.Category.get( trans.security.decode_id( category_id ) )
+ rca = trans.app.model.RepositoryCategoryAssociation( repository, category )
+ trans.sa_session.add( rca )
+ trans.sa_session.flush()
+ message = "The repository information has been updated."
elif params.get( 'user_access_button', False ):
if allow_push not in [ 'none' ]:
remove_auth = params.get( 'remove_auth', '' )
@@ -586,6 +611,7 @@
usernames.append( user.username )
usernames = ','.join( usernames )
repository.set_allow_push( usernames, remove_auth=remove_auth )
+ message = "The repository information has been updated."
elif params.get( 'receive_email_alerts_button', False ):
flush_needed = False
if alerts_checked:
@@ -601,6 +627,7 @@
if flush_needed:
trans.sa_session.add( repository )
trans.sa_session.flush()
+ message = "The repository information has been updated."
if error:
status = 'error'
if repository.allow_push:
@@ -615,6 +642,8 @@
metadata = repository_metadata.metadata
else:
metadata = None
+ categories = get_categories( trans )
+ selected_categories = [ rca.category_id for rca in repository.categories ]
return trans.fill_template( '/webapps/community/repository/manage_repository.mako',
repo_name=repo_name,
description=description,
@@ -623,6 +652,8 @@
allow_push_select_field=allow_push_select_field,
repo=repo,
repository=repository,
+ selected_categories=selected_categories,
+ categories=categories,
metadata=metadata,
avg_rating=avg_rating,
display_reviews=display_reviews,
--- a/templates/webapps/community/repository/create_repository.mako Tue Jul 12 10:07:15 2011 -0400
+++ b/templates/webapps/community/repository/create_repository.mako Tue Jul 12 13:51:28 2011 -0400
@@ -38,7 +38,7 @@
<div style="clear: both"></div></div><div class="form-row">
- <label>Category</label>
+ <label>Categories</label><div class="form-row"><select name="category_id" multiple>
%for category in categories:
@@ -50,6 +50,9 @@
%endfor
</select></div>
+ <div class="toolParamHelp" style="clear: both;">
+ Multi-select list - hold the appropriate key while clicking to select multiple categories.
+ </div><div style="clear: both"></div></div><div class="form-row">
--- a/templates/webapps/community/repository/manage_repository.mako Tue Jul 12 10:07:15 2011 -0400
+++ b/templates/webapps/community/repository/manage_repository.mako Tue Jul 12 13:51:28 2011 -0400
@@ -151,6 +151,34 @@
</form></div></div>
+<p/>
+<div class="toolForm">
+ <div class="toolFormTitle">Manage categories</div>
+ <div class="toolFormBody">
+ <form name="categories" id="categories" action="${h.url_for( controller='repository', action='manage_repository', id=trans.security.encode_id( repository.id ) )}" method="post" >
+ <div class="form-row">
+ <label>Categories</label>
+ <select name="category_id" multiple>
+ %for category in categories:
+ %if category.id in selected_categories:
+ <option value="${trans.security.encode_id( category.id )}" selected>${category.name}</option>
+ %else:
+ <option value="${trans.security.encode_id( category.id )}">${category.name}</option>
+ %endif
+ %endfor
+ </select>
+ <div class="toolParamHelp" style="clear: both;">
+ Multi-select list - hold the appropriate key while clicking to select multiple categories.
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <input type="submit" name="manage_categories_button" value="Save"/>
+ </div>
+ </form>
+ </div>
+</div>
+<p/>
%if can_set_metadata:
<p/><div class="toolForm">
@@ -215,7 +243,7 @@
%if trans.app.config.smtp_server:
<p/><div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">Notification on update</div><div class="toolFormBody"><form name="receive_email_alerts" id="receive_email_alerts" action="${h.url_for( controller='repository', action='manage_repository', id=trans.security.encode_id( repository.id ) )}" method="post" ><div class="form-row">
--- a/templates/webapps/community/repository/view_repository.mako Tue Jul 12 10:07:15 2011 -0400
+++ b/templates/webapps/community/repository/view_repository.mako Tue Jul 12 13:51:28 2011 -0400
@@ -145,6 +145,20 @@
%endif
</div></div>
+%if repository.categories:
+ <p/>
+ <div class="toolForm">
+ <div class="toolFormTitle">Categories</div>
+ <div class="toolFormBody">
+ %for rca in repository.categories:
+ <div class="form-row">
+ ${rca.category.name}
+ </div>
+ %endfor
+ <div style="clear: both"></div>
+ </div>
+ </div>
+%endif
%if metadata:
<p/><div class="toolForm">
@@ -197,7 +211,7 @@
%if trans.user and trans.app.config.smtp_server:
<p/><div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">Notification on update</div><div class="toolFormBody"><form name="receive_email_alerts" id="receive_email_alerts" action="${h.url_for( controller='repository', action='view_repository', id=trans.security.encode_id( repository.id ) )}" method="post" ><div class="form-row">
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Fix for renaming a tool shed repository, and aother fix for displaying a tool that includes a SelectToolParameter with a data_ref.
by Bitbucket 12 Jul '11
by Bitbucket 12 Jul '11
12 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/7c7d01c511d0/
changeset: 7c7d01c511d0
user: greg
date: 2011-07-12 16:07:15
summary: Fix for renaming a tool shed repository, and aother fix for displaying a tool that includes a SelectToolParameter with a data_ref.
affected #: 5 files (2.0 KB)
--- a/lib/galaxy/webapps/community/controllers/repository.py Mon Jul 11 14:48:12 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Tue Jul 12 10:07:15 2011 -0400
@@ -369,6 +369,23 @@
output.write( '[paths]\n' )
output.write( "%s\n" % entry )
output.close()
+ def __change_hgweb_config_entry( self, trans, repository, old_repository_name, new_repository_name ):
+ # Change an entry in the hgweb.config file for a repository. This only happens when
+ # the owner changes the name of the repository. An entry looks something like:
+ # repos/test/mira_assembler = database/community_files/000/repo_123.
+ hgweb_config = "%s/hgweb.config" % trans.app.config.root
+ repo_dir = repository.repo_path
+ old_lhs = "repos/%s/%s" % ( repository.user.username, old_repository_name )
+ old_entry = "%s = %s" % ( old_lhs, repo_dir )
+ new_entry = "repos/%s/%s = %s\n" % ( repository.user.username, new_repository_name, repo_dir )
+ tmp_fd, tmp_fname = tempfile.mkstemp()
+ new_hgweb_config = open( tmp_fname, 'wb' )
+ for i, line in enumerate( open( hgweb_config ) ):
+ if line.startswith( old_lhs ):
+ new_hgweb_config.write( new_entry )
+ else:
+ new_hgweb_config.write( line )
+ shutil.move( tmp_fname, os.path.abspath( hgweb_config ) )
def __create_hgrc_file( self, repository ):
# At this point, an entry for the repository is required to be in the hgweb.config
# file so we can call repository.repo_path.
@@ -511,7 +528,8 @@
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
repository = get_repository( trans, id )
- repo = hg.repository( ui.ui(), repository.repo_path )
+ repo_dir = repository.repo_path
+ repo = hg.repository( ui.ui(), repo_dir )
repo_name = util.restore_text( params.get( 'repo_name', repository.name ) )
description = util.restore_text( params.get( 'description', repository.description ) )
long_description = util.restore_text( params.get( 'long_description', repository.long_description ) )
@@ -528,6 +546,7 @@
user = trans.user
if params.get( 'edit_repository_button', False ):
flush_needed = False
+ # TODO: add a can_manage in the security agent.
if user != repository.user:
message = "You are not the owner of this repository, so you cannot manage it."
status = error
@@ -541,6 +560,7 @@
if message:
error = True
else:
+ self.__change_hgweb_config_entry( trans, repository, repository.name, repo_name )
repository.name = repo_name
flush_needed = True
if description != repository.description:
@@ -552,6 +572,7 @@
if flush_needed:
trans.sa_session.add( repository )
trans.sa_session.flush()
+ message = "The repository information has been updated."
elif params.get( 'user_access_button', False ):
if allow_push not in [ 'none' ]:
remove_auth = params.get( 'remove_auth', '' )
--- a/lib/galaxy/webapps/community/model/__init__.py Mon Jul 11 14:48:12 2011 -0400
+++ b/lib/galaxy/webapps/community/model/__init__.py Tue Jul 12 10:07:15 2011 -0400
@@ -4,7 +4,7 @@
Naming: try to use class names that have a distinct plural form so that
the relationship cardinalities are obvious (e.g. prefer Dataset to Data)
"""
-import os.path, os, errno, sys, codecs, operator, tempfile, logging, tarfile, mimetypes, ConfigParser
+import os.path, os, errno, sys, codecs, operator, logging, tarfile, mimetypes, ConfigParser
from galaxy import util
from galaxy.util.bunch import Bunch
from galaxy.util.hash_util import *
--- a/templates/webapps/community/repository/manage_repository.mako Mon Jul 11 14:48:12 2011 -0400
+++ b/templates/webapps/community/repository/manage_repository.mako Tue Jul 12 10:07:15 2011 -0400
@@ -9,6 +9,7 @@
can_push = trans.app.security_agent.can_push( trans.user, repository )
can_upload = can_push
can_browse_contents = not is_new
+ can_set_metadata = not is_new
can_rate = not is_new and trans.user and repository.user != trans.user
can_view_change_log = not is_new
if can_push:
@@ -79,10 +80,10 @@
%endif
%if can_browse_contents:
<a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='gz' )}">Download as a .tar.gz file</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='bz2' )}">Download as a .tar.bz2 file</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='zip' )}">Download as a zip file</a>
%endif
- <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='gz' )}">Download as a .tar.gz file</a>
- <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='bz2' )}">Download as a .tar.bz2 file</a>
- <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='zip' )}">Download as a zip file</a></div>
%endif
</ul>
@@ -150,65 +151,67 @@
</form></div></div>
-<p/>
-<div class="toolForm">
- <div class="toolFormTitle">Repository metadata</div>
- <div class="toolFormBody">
- %if metadata:
- %if 'tools' in metadata:
+%if can_set_metadata:
+ <p/>
+ <div class="toolForm">
+ <div class="toolFormTitle">Repository metadata</div>
+ <div class="toolFormBody">
+ %if metadata:
+ %if 'tools' in metadata:
+ <div class="form-row">
+ <label>Tools:</label>
+ <% tool_dicts = metadata[ 'tools' ] %>
+ <table class="grid">
+ <tr>
+ <td><b>name</b></td>
+ <td><b>description</b></td>
+ <td><b>version</b></td>
+ <td><b>requirements</b></td>
+ </tr>
+ %for tool_dict in tool_dicts:
+ <tr>
+ <td><a href="${h.url_for( controller='repository', action='display_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=tool_dict[ 'tool_config' ] )}">${tool_dict[ 'name' ]}</a></td>
+ <td>${tool_dict[ 'description' ]}</td>
+ <td>${tool_dict[ 'version' ]}</td>
+ <td>
+ <%
+ if 'requirements' in tool_dict:
+ requirements = tool_dict[ 'requirements' ]
+ else:
+ requirements = None
+ %>
+ %if requirements:
+ <%
+ requirements_str = ''
+ for requirement_dict in tool_dict[ 'requirements' ]:
+ requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] )
+ requirements_str = requirements_str.rstrip( ', ' )
+ %>
+ ${requirements_str}
+ %else:
+ none
+ %endif
+ </td>
+ </tr>
+ %endfor
+ </table>
+ </div>
+ <div style="clear: both"></div>
+ %endif
+ %endif
+ <form name="set_metadata" action="${h.url_for( controller='repository', action='set_metadata', id=trans.security.encode_id( repository.id ), ctx_str=repository.tip )}" method="post"><div class="form-row">
- <label>Tools:</label>
- <% tool_dicts = metadata[ 'tools' ] %>
- <table class="grid">
- <tr>
- <td><b>name</b></td>
- <td><b>description</b></td>
- <td><b>version</b></td>
- <td><b>requirements</b></td>
- </tr>
- %for tool_dict in tool_dicts:
- <tr>
- <td><a href="${h.url_for( controller='repository', action='display_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=tool_dict[ 'tool_config' ] )}">${tool_dict[ 'name' ]}</a></td>
- <td>${tool_dict[ 'description' ]}</td>
- <td>${tool_dict[ 'version' ]}</td>
- <td>
- <%
- if 'requirements' in tool_dict:
- requirements = tool_dict[ 'requirements' ]
- else:
- requirements = None
- %>
- %if requirements:
- <%
- requirements_str = ''
- for requirement_dict in tool_dict[ 'requirements' ]:
- requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] )
- requirements_str = requirements_str.rstrip( ', ' )
- %>
- ${requirements_str}
- %else:
- none
- %endif
- </td>
- </tr>
- %endfor
- </table>
+ <div style="float: left; width: 250px; margin-right: 10px;">
+ <input type="submit" name="set_metadata_button" value="Reset metadata"/>
+ </div>
+ <div class="toolParamHelp" style="clear: both;">
+ Inspect the repository and reset the above attributes for the repository tip.
+ </div></div>
- <div style="clear: both"></div>
- %endif
- %endif
- <form name="set_metadata" action="${h.url_for( controller='repository', action='set_metadata', id=trans.security.encode_id( repository.id ), ctx_str=repository.tip )}" method="post">
- <div class="form-row">
- <div style="float: left; width: 250px; margin-right: 10px;">
- <input type="submit" name="set_metadata_button" value="Reset metadata"/>
- </div>
- <div class="toolParamHelp" style="clear: both;">
- Inspect the repository and reset the above attributes for the repository tip.
- </div>
- </div>
- </form>
+ </form>
+ </div></div>
-</div>
+%endif
%if trans.app.config.smtp_server:
<p/><div class="toolForm">
--- a/templates/webapps/community/repository/tool_form.mako Mon Jul 11 14:48:12 2011 -0400
+++ b/templates/webapps/community/repository/tool_form.mako Tue Jul 12 10:07:15 2011 -0400
@@ -4,7 +4,7 @@
<%
from galaxy.util.expressions import ExpressionContext
from galaxy import util
- from galaxy.tools.parameters.basic import DataToolParameter, ColumnListParameter
+ from galaxy.tools.parameters.basic import DataToolParameter, ColumnListParameter, SelectToolParameter
from galaxy.web.form_builder import SelectField
is_admin = trans.user_is_admin()
@@ -84,6 +84,10 @@
field = SelectField( param.name )
field.add_option( param.name, param.name )
field_html = field.get_html()
+ elif isinstance( param, SelectToolParameter ) and param.data_ref:
+ field = SelectField( param.name, display=param.display )
+ field.add_option( param.data_ref, param.data_ref )
+ field_html = field.get_html( prefix )
else:
field = param.get_html_field( trans, None, other_values )
field_html = field.get_html( prefix )
--- a/templates/webapps/community/repository/view_repository.mako Mon Jul 11 14:48:12 2011 -0400
+++ b/templates/webapps/community/repository/view_repository.mako Tue Jul 12 10:07:15 2011 -0400
@@ -79,10 +79,10 @@
%endif
%if can_browse_contents:
<a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='gz' )}">Download as a .tar.gz file</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='bz2' )}">Download as a .tar.bz2 file</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='zip' )}">Download as a zip file</a>
%endif
- <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='gz' )}">Download as a .tar.gz file</a>
- <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='bz2' )}">Download as a .tar.bz2 file</a>
- <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), file_type='zip' )}">Download as a zip file</a></div>
%endif
</ul>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Fix for setting tool shed repository etadata multiple times when nothing in the repository has changed.
by Bitbucket 11 Jul '11
by Bitbucket 11 Jul '11
11 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/38899d79629b/
changeset: 38899d79629b
user: greg
date: 2011-07-11 20:48:12
summary: Fix for setting tool shed repository etadata multiple times when nothing in the repository has changed.
affected #: 1 file (178 bytes)
--- a/lib/galaxy/webapps/community/controllers/common.py Mon Jul 11 14:10:56 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/common.py Mon Jul 11 14:48:12 2011 -0400
@@ -146,10 +146,13 @@
metadata_dict[ 'tools' ] = [ tool_dict ]
except Exception, e:
invalid_tool_configs.append( ( name, str( e ) ) )
- repository_metadata = trans.model.RepositoryMetadata( repository.id, repository.tip, metadata_dict )
- trans.sa_session.add( repository_metadata )
- if not flush_needed:
- flush_needed = True
+ if metadata_dict:
+ # The metadata_dict dictionary will contain items only
+ # if the repository did not already have metadata set.
+ repository_metadata = trans.model.RepositoryMetadata( repository.id, repository.tip, metadata_dict )
+ trans.sa_session.add( repository_metadata )
+ if not flush_needed:
+ flush_needed = True
else:
message = "Repository does not include changeset revision '%s'." % str( ctx_str )
status = 'error'
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Bug fix for setting tool shed repository metadata on repositories containing more than 1 tool.
by Bitbucket 11 Jul '11
by Bitbucket 11 Jul '11
11 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/6e9fca39e3f4/
changeset: 6e9fca39e3f4
user: greg
date: 2011-07-11 20:10:56
summary: Bug fix for setting tool shed repository metadata on repositories containing more than 1 tool.
affected #: 1 file (106 bytes)
--- a/lib/galaxy/webapps/community/controllers/common.py Mon Jul 11 13:45:57 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/common.py Mon Jul 11 14:10:56 2011 -0400
@@ -86,6 +86,7 @@
invalid_tool_configs = []
flush_needed = False
if change_set is not None:
+ metadata_dict = {}
for root, dirs, files in os.walk( repo_dir ):
if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
if '.hg' in dirs:
@@ -139,13 +140,16 @@
if not flush_needed:
flush_needed = True
else:
- metadata_dict = dict( tools = [ tool_dict ] )
- repository_metadata = trans.model.RepositoryMetadata( repository.id, repository.tip, metadata_dict )
- trans.sa_session.add( repository_metadata )
- if not flush_needed:
- flush_needed = True
+ if 'tools' in metadata_dict:
+ metadata_dict[ 'tools' ].append( tool_dict )
+ else:
+ metadata_dict[ 'tools' ] = [ tool_dict ]
except Exception, e:
invalid_tool_configs.append( ( name, str( e ) ) )
+ repository_metadata = trans.model.RepositoryMetadata( repository.id, repository.tip, metadata_dict )
+ trans.sa_session.add( repository_metadata )
+ if not flush_needed:
+ flush_needed = True
else:
message = "Repository does not include changeset revision '%s'." % str( ctx_str )
status = 'error'
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Allow an admin user to manage repositories they do not own.
by Bitbucket 11 Jul '11
by Bitbucket 11 Jul '11
11 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/0007cf69d1dc/
changeset: 0007cf69d1dc
user: greg
date: 2011-07-11 19:45:57
summary: Allow an admin user to manage repositories they do not own.
affected #: 1 file (61 bytes)
--- a/lib/galaxy/webapps/community/controllers/repository.py Mon Jul 11 13:34:23 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Mon Jul 11 13:45:57 2011 -0400
@@ -214,7 +214,8 @@
if operation == "view_or_manage_repository":
repository_id = kwd.get( 'id', None )
repository = get_repository( trans, repository_id )
- if repository.user == trans.user:
+ is_admin = trans.user_is_admin()
+ if is_admin or repository.user == trans.user:
return trans.response.send_redirect( web.url_for( controller='repository',
action='manage_repository',
**kwd ) )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Do not set tool shed repository metadata if tool does not load. Add tool config <requirements> settings to tool shed repository metadata.
by Bitbucket 11 Jul '11
by Bitbucket 11 Jul '11
11 Jul '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/34c190323b36/
changeset: 34c190323b36
user: greg
date: 2011-07-11 19:34:23
summary: Do not set tool shed repository metadata if tool does not load. Add tool config <requirements> settings to tool shed repository metadata.
affected #: 5 files (4.3 KB)
--- a/lib/galaxy/webapps/community/controllers/common.py Fri Jul 08 16:11:28 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/common.py Mon Jul 11 13:34:23 2011 -0400
@@ -75,9 +75,100 @@
.filter( and_( trans.model.RepositoryMetadata.table.c.repository_id == trans.security.decode_id( id ),
trans.model.RepositoryMetadata.table.c.changeset_revision == changeset_revision ) ) \
.first()
+def set_repository_metadata( trans, id, ctx_str, **kwd ):
+ """Set repository metadata"""
+ message = ''
+ status = 'done'
+ repository = get_repository( trans, id )
+ repo_dir = repository.repo_path
+ repo = hg.repository( ui.ui(), repo_dir )
+ change_set = get_change_set( trans, repo, ctx_str )
+ invalid_tool_configs = []
+ flush_needed = False
+ if change_set is not None:
+ for root, dirs, files in os.walk( repo_dir ):
+ if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
+ if '.hg' in dirs:
+ # Don't visit .hg directories - should be impossible since we don't
+ # allow uploaded archives that contain .hg dirs, but just in case...
+ dirs.remove( '.hg' )
+ if 'hgrc' in files:
+ # Don't include hgrc files in commit.
+ files.remove( 'hgrc' )
+ for name in files:
+ # Find all tool configs.
+ if name.endswith( '.xml' ):
+ try:
+ full_path = os.path.abspath( os.path.join( root, name ) )
+ tool = load_tool( trans, full_path )
+ if tool is not None:
+ repository_metadata = get_repository_metadata( trans, id, repository.tip )
+ tool_requirements = []
+ for tr in tool.requirements:
+ requirement_dict = dict( name=tr.name,
+ type=tr.type,
+ version=tr.version )
+ tool_requirements.append( requirement_dict )
+ tool_dict = dict( id = tool.id,
+ name = tool.name,
+ version = tool.version,
+ description = tool.description,
+ tool_config = os.path.join( root, name ),
+ requirements = tool_requirements )
+ if repository_metadata:
+ metadata = repository_metadata.metadata
+ if metadata and 'tools' in metadata:
+ metadata_tools = metadata[ 'tools' ]
+ found = False
+ for tool_metadata_dict in metadata_tools:
+ if 'id' in tool_metadata_dict and tool_metadata_dict[ 'id' ] == tool.id and \
+ 'version' in tool_metadata_dict and tool_metadata_dict[ 'version' ] == tool.version:
+ found = True
+ tool_metadata_dict[ 'name' ] = tool.name
+ tool_metadata_dict[ 'description' ] = tool.description
+ tool_metadata_dict[ 'tool_config' ] = os.path.join( root, name )
+ tool_metadata_dict[ 'requirements' ] = tool_requirements
+ flush_needed = True
+ if not found:
+ metadata_tools.append( tool_dict )
+ else:
+ if metadata is None:
+ repository_metadata.metadata = {}
+ repository_metadata.metadata[ 'tools' ] = [ tool_dict ]
+ trans.sa_session.add( repository_metadata )
+ if not flush_needed:
+ flush_needed = True
+ else:
+ metadata_dict = dict( tools = [ tool_dict ] )
+ repository_metadata = trans.model.RepositoryMetadata( repository.id, repository.tip, metadata_dict )
+ trans.sa_session.add( repository_metadata )
+ if not flush_needed:
+ flush_needed = True
+ except Exception, e:
+ invalid_tool_configs.append( ( name, str( e ) ) )
+ else:
+ message = "Repository does not include changeset revision '%s'." % str( ctx_str )
+ status = 'error'
+ if invalid_tool_configs:
+ message = "Metadata cannot be defined for change set revision '%s'. Correct the following problems and reset metadata.<br/>" % str( ctx_str )
+ for itc_tup in invalid_tool_configs:
+ message += "<b>%s</b> - %s<br/>" % ( itc_tup[0], itc_tup[1] )
+ status = 'error'
+ elif flush_needed:
+ # We only flush if there are no tool config errors, so change sets will only have metadata
+ # if everything in them is valid.
+ trans.sa_session.flush()
+ return message, status
def get_repository_by_name( trans, name ):
"""Get a repository from the database via name"""
return trans.sa_session.query( app.model.Repository ).filter_by( name=name ).one()
+def get_change_set( trans, repo, ctx_str, **kwd ):
+ """Retrieve a specified change set from a repository"""
+ for changeset in repo.changelog:
+ ctx = repo.changectx( changeset )
+ if str( ctx ) == ctx_str:
+ return ctx
+ return None
def get_user( trans, id ):
"""Get a user from the database"""
return trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( id ) )
@@ -184,77 +275,3 @@
ToolClass = Tool
return ToolClass( config_file, root, trans.app )
return None
-def set_repository_metadata( trans, id, ctx_str, **kwd ):
- """Set repository metadata"""
- message = ''
- status = 'done'
- repository = get_repository( trans, id )
- repo_dir = repository.repo_path
- repo = hg.repository( ui.ui(), repo_dir )
- found = False
- invalid_tool_configs = []
- for changeset in repo.changelog:
- ctx = repo.changectx( changeset )
- if str( ctx ) == ctx_str:
- found = True
- break
- if found:
- for root, dirs, files in os.walk( repo_dir ):
- if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
- if '.hg' in dirs:
- # Don't visit .hg directories - should be impossible since we don't
- # allow uploaded archives that contain .hg dirs, but just in case...
- dirs.remove( '.hg' )
- if 'hgrc' in files:
- # Don't include hgrc files in commit.
- files.remove( 'hgrc' )
- for name in files:
- # Find all tool configs.
- if name.endswith( '.xml' ):
- try:
- full_path = os.path.abspath( os.path.join( root, name ) )
- tool = load_tool( trans, full_path )
- if tool is not None:
- repository_metadata = get_repository_metadata( trans, id, repository.tip )
- # TODO: add more stuff, like requirements
- tool_dict = dict( id = tool.id,
- name = tool.name,
- version = tool.version,
- description = tool.description,
- tool_config = full_path )
- if repository_metadata:
- metadata = repository_metadata.metadata
- if metadata and 'tools' in metadata:
- metadata_tools = metadata[ 'tools' ]
- found = False
- for tool_metadata_dict in metadata_tools:
- if 'id' in tool_metadata_dict and tool_metadata_dict[ 'id' ] == tool.id and \
- 'version' in tool_metadata_dict and tool_metadata_dict[ 'version' ] == tool.version:
- found = True
- tool_metadata_dict[ 'name' ] = tool.name
- tool_metadata_dict[ 'description' ] = tool.description
- tool_metadata_dict[ 'tool_config' ] = os.path.join( root, name )
- # TODO: add more stuff, like tool requirements, code files, etc
- if not found:
- metadata_tools.append( tool_dict )
- else:
- if metadata is None:
- repository_metadata.metadata = {}
- repository_metadata.metadata[ 'tools' ] = [ tool_dict ]
- trans.sa_session.add( repository_metadata )
- else:
- metadata_dict = dict( tools = [ tool_dict ] )
- repository_metadata = trans.model.RepositoryMetadata( repository.id, repository.tip, metadata_dict )
- trans.sa_session.add( repository_metadata )
- trans.sa_session.flush()
- except Exception, e:
- invalid_tool_configs.append( ( name, str( e ) ) )
- else:
- message = "Repository does not include changeset revision '%s'." % str( ctx_str )
- status = 'error'
- if invalid_tool_configs:
- message = "The following tool configs are invalid and were not added to the repository metadata:<br/>"
- for itc_tup in invalid_tool_configs:
- message += "<b>%s</b> - %s<br/>" % ( itc_tup[0], itc_tup[1] )
- status = 'error'
- return message, status
--- a/lib/galaxy/webapps/community/controllers/repository.py Fri Jul 08 16:11:28 2011 -0400
+++ b/lib/galaxy/webapps/community/controllers/repository.py Mon Jul 11 13:34:23 2011 -0400
@@ -643,13 +643,8 @@
status = params.get( 'status', 'done' )
repository = get_repository( trans, id )
repo = hg.repository( ui.ui(), repository.repo_path )
- found = False
- for changeset in repo.changelog:
- ctx = repo.changectx( changeset )
- if str( ctx ) == ctx_str:
- found = True
- break
- if not found:
+ ctx = get_change_set( trans, repo, ctx_str )
+ if ctx is None:
message = "Repository does not include changeset revision '%s'." % str( ctx_str )
status = 'error'
return trans.response.send_redirect( web.url_for( controller='repository',
@@ -753,6 +748,8 @@
@web.require_login( "set repository metadata" )
def set_metadata( self, trans, id, ctx_str, **kwd ):
message, status = set_repository_metadata( trans, id, ctx_str, **kwd )
+ if not message:
+ message = "Metadata for change set revision '%s' has been reset." % str( ctx_str )
return trans.response.send_redirect( web.url_for( controller='repository',
action='manage_repository',
id=id,
--- a/templates/webapps/community/repository/manage_repository.mako Fri Jul 08 16:11:28 2011 -0400
+++ b/templates/webapps/community/repository/manage_repository.mako Mon Jul 11 13:34:23 2011 -0400
@@ -160,11 +160,36 @@
<label>Tools:</label><% tool_dicts = metadata[ 'tools' ] %><table class="grid">
+ <tr>
+ <td><b>name</b></td>
+ <td><b>description</b></td>
+ <td><b>version</b></td>
+ <td><b>requirements</b></td>
+ </tr>
%for tool_dict in tool_dicts:
<tr><td><a href="${h.url_for( controller='repository', action='display_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=tool_dict[ 'tool_config' ] )}">${tool_dict[ 'name' ]}</a></td><td>${tool_dict[ 'description' ]}</td>
- <td>version: ${tool_dict[ 'version' ]}</td>
+ <td>${tool_dict[ 'version' ]}</td>
+ <td>
+ <%
+ if 'requirements' in tool_dict:
+ requirements = tool_dict[ 'requirements' ]
+ else:
+ requirements = None
+ %>
+ %if requirements:
+ <%
+ requirements_str = ''
+ for requirement_dict in tool_dict[ 'requirements' ]:
+ requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] )
+ requirements_str = requirements_str.rstrip( ', ' )
+ %>
+ ${requirements_str}
+ %else:
+ none
+ %endif
+ </td></tr>
%endfor
</table>
--- a/templates/webapps/community/repository/tool_form.mako Fri Jul 08 16:11:28 2011 -0400
+++ b/templates/webapps/community/repository/tool_form.mako Mon Jul 11 13:34:23 2011 -0400
@@ -15,6 +15,10 @@
can_rate = trans.user and repository.user != trans.user
can_manage = is_admin or repository.user == trans.user
can_view_change_log = not is_new
+ if can_push:
+ browse_label = 'Browse or delete repository files'
+ else:
+ browse_label = 'Browse repository files'
%><html>
@@ -116,6 +120,9 @@
%if can_view_change_log:
<a class="action-button" href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">View change log</a>
%endif
+ %if can_browse_contents:
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ %endif
%if can_rate:
<a class="action-button" href="${h.url_for( controller='repository', action='rate_repository', id=trans.app.security.encode_id( repository.id ) )}">Rate repository</a>
%endif
--- a/templates/webapps/community/repository/view_repository.mako Fri Jul 08 16:11:28 2011 -0400
+++ b/templates/webapps/community/repository/view_repository.mako Mon Jul 11 13:34:23 2011 -0400
@@ -155,11 +155,36 @@
<label>Tools:</label><% tool_dicts = metadata[ 'tools' ] %><table class="grid">
+ <tr>
+ <td><b>name</b></td>
+ <td><b>description</b></td>
+ <td><b>version</b></td>
+ <td><b>requirements</b></td>
+ </tr>
%for tool_dict in tool_dicts:
<tr><td><a href="${h.url_for( controller='repository', action='display_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=tool_dict[ 'tool_config' ] )}">${tool_dict[ 'name' ]}</a></td><td>${tool_dict[ 'description' ]}</td><td>version: ${tool_dict[ 'version' ]}</td>
+ <td>
+ <%
+ if 'requirements' in tool_dict:
+ requirements = tool_dict[ 'requirements' ]
+ else:
+ requirements = None
+ %>
+ %if requirements:
+ <%
+ requirements_str = ''
+ for requirement_dict in tool_dict[ 'requirements' ]:
+ requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] )
+ requirements_str = requirements_str.rstrip( ', ' )
+ %>
+ ${requirements_str}
+ %else:
+ none
+ %endif
+ </td></tr>
%endfor
</table>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0