package com.github.lindenb.jvarkit.tools.cgi;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import com.github.lindenb.jvarkit.util.jcommander.Program;
import com.github.lindenb.jvarkit.util.log.Logger;
import htsjdk.samtools.util.CloserUtil;
@Program(name="",description="CGI/Web based version of samtools tview")
public class SamtoolsTviewCGI extends AbstractCGICallApp
{
private static final Logger LOG=Logger.build(SamtoolsTviewCGI.class).make();
private SamtoolsTviewCGI()
{
}
/*
private File convertFile(File f) throws IOException
{
if(f==null) return f;
if(f.isAbsolute()) return f;
String base=getPreferences().get("base.bam.directory",null);
if(base==null) return f;
return new File(base,f.getPath());
}*/
private void goButton(
XMLStreamWriter w,
String bamStr,
String label,
int shift,
String chrom,
int position1
) throws XMLStreamException,IOException
{
if(position1+shift<1)
{
position1=1;
shift=0;
}
if(chrom==null || bamStr==null || position1+shift<1) return;
w.writeStartElement("form");
w.writeAttribute("method", "POST");
w.writeAttribute("class", "formbutton");
w.writeEmptyElement("input");
w.writeAttribute("name", "bam");
w.writeAttribute("type", "hidden");
w.writeAttribute("value", bamStr);
w.writeEmptyElement("input");
w.writeAttribute("name", "pos");
w.writeAttribute("type", "hidden");
w.writeAttribute("value",(chrom+":"+(position1+shift)));
w.writeStartElement("button");
w.writeAttribute("type", "submit");
w.writeAttribute("title", chrom+":"+(position1+shift));
w.writeEntityRef(label);
w.writeEndElement();//button
w.writeEndElement();//form
}
private void printForm(
XMLStreamWriter w,
String bamStr,
String posStr
) throws XMLStreamException
{
w.writeEmptyElement("hr");
w.writeStartElement("form");
w.writeAttribute("method", "POST");
w.writeStartElement("label");
w.writeAttribute("for", "bam");
w.writeCharacters("Bam File(s)");
w.writeEndElement();
w.writeEmptyElement("br");
w.writeStartElement("textarea");
w.writeAttribute("width", "100%");
w.writeAttribute("name", "bam");
w.writeAttribute("id", "bam");
w.writeAttribute("placeholder", "/path/to/file.bam on server");
w.writeAttribute("required", "true");
w.writeCharacters(bamStr==null?"":bamStr.trim());
w.writeEndElement();
w.writeEmptyElement("br");
w.writeStartElement("label");
w.writeAttribute("for", "pos");
w.writeCharacters("Position");
w.writeEndElement();
w.writeEmptyElement("input");
w.writeAttribute("type", "text");
w.writeAttribute("name", "pos");
w.writeAttribute("id", "pos");
w.writeAttribute("value", posStr==null?"":posStr.trim());
w.writeAttribute("placeholder", "chrom:pos");
w.writeEmptyElement("br");
w.writeEmptyElement("input");
w.writeAttribute("type", "submit");
w.writeEmptyElement("br");
w.writeEndElement();//form
}
@Override
protected void doCGI()
{
setMimeHeaderPrinted(true);
System.out.print("Content-type: text/html;charset=utf-8\n");
System.out.println();
System.out.flush();
XMLStreamWriter w=null;
try
{
/* parse CHROM and position */
String chrom=null;
int position1=-1;
String posStr=this.getString("pos");
if(posStr!=null)
{
posStr=posStr.trim();
int colon=posStr.indexOf(':');
if(colon>0 && colon+1 < posStr.length())
{
chrom=posStr.substring(0,colon);
try {
position1=Integer.parseInt(posStr.substring(colon+1));
} catch (Exception e)
{
chrom=null;
position1=-1;
}
}
}
XMLOutputFactory xof=XMLOutputFactory.newFactory();
w=xof.createXMLStreamWriter(System.out,"UTF-8");
w.writeStartElement("html");
w.writeStartElement("head");
w.writeStartElement("style");
w.writeAttribute("type", "text/css");
w.writeCharacters(
"label { text-align:right; margin:5px;}\n"+
"button {font-size:200%;min-width:100px;border: 1px solid; background-image:-moz-linear-gradient( top, gray, lightgray );margin:5px;}\n"+
"button:hover {background-image:-moz-linear-gradient( top, lightgray, gray );}\n"+
".code {border:1px solid black;font-family:monospace;font-size:14pt;color:white;background-color:black;max-width:100%;max-height:400px;overflow:auto;padding:20px;}\n"+
".bigtitle {text-align:center;padding:10px;text-shadow: 3px 3px 4px gray; font-size:200%;}\n"+
"textarea{box-sizing: border-box;width: 100%;}\n"+
".formbutton{display:inline;}\n"
);
w.writeEndElement();//style
if(posStr!=null)
{
w.writeStartElement("title");
w.writeCharacters(posStr);
w.writeEndElement();//title
}
w.writeEndElement();//head
w.writeStartElement("body");
w.flush();
if(posStr!=null)
{
w.writeStartElement("h1");
w.writeAttribute("class","bigtitle");
w.writeCharacters(posStr);
w.writeEndElement();//title
}
if(posStr!=null && posStr.length()>0 && (chrom==null || position1<=0))
{
w.writeCharacters("BAD POS: "+posStr);
w.writeEmptyElement("br");
}
try
{
getPreferences();
}
catch(Exception err)
{
writeHTMLException(w, err);
w.flush();
}
/* get samtools loc */
File samtools=null;
try
{
samtools=new File(getPreferences().get("samtools.path", "samtools"));
if(!samtools.exists())
{
w.writeCharacters("Cannot find samtools: "+samtools);
w.writeEmptyElement("br");
}
}
catch(Exception err)
{
writeHTMLException(w, err);
}
String bamString=this.getString("bam");
String bamList[]=new String[0];
if(bamString!=null && samtools!=null)
{
w.writeStartElement("div");
w.writeAttribute("style", "text-align:center;font-size:120%;clear: both;");
w.writeStartElement("div");
goButton(w,bamString,"#x21DA",-30,chrom,position1);
goButton(w,bamString,"#x21D0",-20,chrom,position1);
goButton(w,bamString,"#x2190",-10,chrom,position1);
goButton(w,bamString,"#x2192",1,chrom,position1);
goButton(w,bamString,"#x21D2",10,chrom,position1);
goButton(w,bamString,"#x21D2",20,chrom,position1);
goButton(w,bamString,"#x21DB",30,chrom,position1);
w.writeEndElement();//div
w.writeEndElement();//div
w.flush();
bamList=bamString.split("[\n]+");
}
for(String bamFileStr:bamList)
{
bamFileStr=bamFileStr.trim();
if(samtools==null || bamFileStr.isEmpty()) continue;
File bamFile=null;
if(bamFileStr!=null && bamFileStr.endsWith(".bam"))
{
bamFile=new File(bamFileStr.trim());
if(!(bamFile.exists() && bamFile.isFile() && bamFile.canRead()))
{
w.writeCharacters("BAD BAM File: "+bamFileStr);
w.writeEmptyElement("br");
bamFile=null;
}
else
{
File bai=new File(bamFileStr+".bai");
if(!bai.exists())
{
bai=new File(bamFileStr.substring(0,bamFileStr.length()-3)+"bai");
}
if(!bai.exists())
{
w.writeCharacters("BAM File: "+bamFileStr+" is not indexed");
w.writeEmptyElement("br");
bamFile=null;
}
}
}
if(bamFile==null) continue;
w.writeEmptyElement("hr");
w.writeStartElement("h3");
w.writeStartElement("a");
w.writeAttribute("href", "#");
w.writeCharacters("file://"+bamFileStr);
w.writeEndElement();//a
w.writeEndElement();//h3
if(bamFile!=null)
{
Process proc=null;
InputStream os=null;
ConsummeInputStreamThread err=null;
try
{
List<String> args=new ArrayList<String>();
args.add(samtools.getPath());
args.add("tview");
args.add("-d");args.add("T");
if(chrom!=null && position1>0)
{
args.add("-p");args.add(chrom+":"+position1);
}
args.add(bamFile.getPath());
String ref=getPreferences().get("default.reference.path",null);
if(ref!=null)
{
args.add(ref);
}
w.writeComment(args.toString());
w.flush();
proc=Runtime.getRuntime().exec(
args.toArray(new String[args.size()]),
new String[]{},
null
);
err=new ConsummeInputStreamThread(proc.getErrorStream());
err.start();
int c;
os=proc.getInputStream();
w.writeStartElement("div");
w.writeAttribute("style", "text-align:center;");
w.writeStartElement("pre");
w.writeAttribute("class", "code");
while((c=os.read())!=-1)
{
if(c=='\n')
{
w.writeEmptyElement("br");
}
else
{
w.writeCharacters(String.valueOf((char)c));
}
if(System.out.checkError()) break;
}
w.writeEndElement();//pre
w.writeEndElement();//div
err.join();
}
catch(Throwable t)
{
writeHTMLException(w, t);
w.writeCharacters(String.valueOf(t.getMessage()));
}
finally
{
if(err!=null) try { err.interrupt();} catch(Exception err2){}
CloserUtil.close(os);
}
}
}
printForm(w,bamString,posStr);
writeHtmlFooter(w);
w.writeEndElement();//body
w.writeEndElement();//html
}
catch(Exception err)
{
LOG.error(err);
}
finally
{
if(w!=null)
{
try {w.flush();} catch(XMLStreamException err){}
CloserUtil.close(w);
}
}
}
public static void main(String[] args)
{
new SamtoolsTviewCGI().instanceMainWithExit(args);
}
}