From 28edb1de72fafb6e2185496eebcd2f8731191ecb Mon Sep 17 00:00:00 2001 From: Frederic Lemoine Date: Thu, 16 Feb 2017 16:28:35 +0100 Subject: [PATCH] Added command to download tree images from iTOL --- cmd/dlimage.go | 23 +++++++++++++++ cmd/itoldl.go | 58 ++++++++++++++++++++++++++++++++++++++ cmd/{itol.go => itolup.go} | 2 +- cmd/rename.go | 48 ------------------------------- cmd/root.go | 44 +++++++++++++++++++++++++++++ download/download.go | 5 ++++ download/format.go | 39 +++++++++++++++++++++++++ download/itol.go | 50 ++++++++++++++++++++++++++++++++ upload/itol.go | 2 +- 9 files changed, 221 insertions(+), 50 deletions(-) create mode 100644 cmd/dlimage.go create mode 100644 cmd/itoldl.go rename cmd/{itol.go => itolup.go} (99%) create mode 100644 download/download.go create mode 100644 download/format.go create mode 100644 download/itol.go diff --git a/cmd/dlimage.go b/cmd/dlimage.go new file mode 100644 index 0000000..df57d91 --- /dev/null +++ b/cmd/dlimage.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +var dltreeid string +var dlformat string +var dloutput string + +// dlimageCmd represents the download command +var dlimageCmd = &cobra.Command{ + Use: "dlimage", + Short: "Download a tree image from from a server", + Long: `Download a tree image from a server`, +} + +func init() { + RootCmd.AddCommand(dlimageCmd) + dlimageCmd.PersistentFlags().StringVarP(&dltreeid, "tree-id", "i", "", "Tree id to download") + dlimageCmd.PersistentFlags().StringVarP(&dlformat, "format", "f", "pdf", "Image format (png, pdf, eps, svg)") + dlimageCmd.PersistentFlags().StringVarP(&dloutput, "output", "o", "", "Image output file") +} diff --git a/cmd/itoldl.go b/cmd/itoldl.go new file mode 100644 index 0000000..5c13587 --- /dev/null +++ b/cmd/itoldl.go @@ -0,0 +1,58 @@ +package cmd + +import ( + "errors" + "io/ioutil" + + "github.com/fredericlemoine/gotree/download" + "github.com/fredericlemoine/gotree/io" + "github.com/spf13/cobra" +) + +var dlconfig string + +// dlitolCmd represents the dlitol command +var dlitolCmd = &cobra.Command{ + Use: "itol", + Short: "Download a tree image from iTOL", + Long: `Download a tree image from iTOL + +Option -c allows to give a configuration file having tab separated key value pairs, +as defined here: +http://itol.embl.de/help.cgi#bExOpt +`, + Run: func(cmd *cobra.Command, args []string) { + if dloutput == "" { + io.ExitWithMessage(errors.New("Output file must be specified")) + } + if dltreeid == "" { + io.ExitWithMessage(errors.New("Tree id must be specified")) + } + format := download.Format(dlformat) + if format == download.IMGFORMAT_UNKNOWN { + io.ExitWithMessage(errors.New("Unkown format: " + dlformat)) + } + var config map[string]string + if dlconfig != "" { + var err error + config, err = readMapFile(dlconfig, false) + if err != nil { + io.ExitWithMessage(err) + } + } else { + config = make(map[string]string) + } + + dl := download.NewItolImageDownloader(config) + b, err := dl.Download(dltreeid, format) + if err != nil { + io.ExitWithMessage(err) + } + ioutil.WriteFile(dloutput, b, 0644) + }, +} + +func init() { + dlimageCmd.AddCommand(dlitolCmd) + dlitolCmd.PersistentFlags().StringVarP(&dlconfig, "config", "c", "", "Itol image config file") +} diff --git a/cmd/itol.go b/cmd/itolup.go similarity index 99% rename from cmd/itol.go rename to cmd/itolup.go index 1039d69..22fc7ad 100644 --- a/cmd/itol.go +++ b/cmd/itolup.go @@ -42,7 +42,7 @@ Will store only urls in the output file `, Run: func(cmd *cobra.Command, args []string) { // args: All annotation files to add to the upload - upld := upload.NewItolUploader(itoluploadid, itolprojectname, args) + upld := upload.NewItolUploader(itoluploadid, itolprojectname, args...) i := 0 for reftree := range readTrees(intreefile) { url, response, err := upld.Upload(fmt.Sprintf("%s_%03d", itoltreename, i), reftree.Tree) diff --git a/cmd/rename.go b/cmd/rename.go index 58467e9..6836815 100644 --- a/cmd/rename.go +++ b/cmd/rename.go @@ -1,59 +1,11 @@ package cmd import ( - "bufio" - "compress/gzip" "errors" - "fmt" "github.com/fredericlemoine/gotree/io" - "github.com/fredericlemoine/gotree/io/utils" "github.com/spf13/cobra" - "os" - "strings" ) -func readMapFile(file string, revert bool) (map[string]string, error) { - outmap := make(map[string]string, 0) - var mapfile *os.File - var err error - var reader *bufio.Reader - - if mapfile, err = os.Open(file); err != nil { - return outmap, err - } - - if strings.HasSuffix(file, ".gz") { - if gr, err2 := gzip.NewReader(mapfile); err2 != nil { - return outmap, err2 - } else { - reader = bufio.NewReader(gr) - } - } else { - reader = bufio.NewReader(mapfile) - } - line, e := utils.Readln(reader) - nl := 1 - for e == nil { - cols := strings.Split(line, "\t") - if len(cols) != 2 { - return outmap, errors.New("Map file does not have 2 fields at line: " + fmt.Sprintf("%d", nl)) - } - if revert { - outmap[cols[1]] = cols[0] - } else { - outmap[cols[0]] = cols[1] - } - line, e = utils.Readln(reader) - nl++ - } - - if err = mapfile.Close(); err != nil { - return outmap, err - } - - return outmap, nil -} - // renameCmd represents the rename command var renameCmd = &cobra.Command{ Use: "rename", diff --git a/cmd/root.go b/cmd/root.go index e8e9e38..be56942 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -2,6 +2,8 @@ package cmd import ( "bufio" + "compress/gzip" + "errors" "fmt" "os" "runtime" @@ -134,3 +136,45 @@ func parseTipsFile(file string) []string { f.Close() return tips } + +func readMapFile(file string, revert bool) (map[string]string, error) { + outmap := make(map[string]string, 0) + var mapfile *os.File + var err error + var reader *bufio.Reader + + if mapfile, err = os.Open(file); err != nil { + return outmap, err + } + + if strings.HasSuffix(file, ".gz") { + if gr, err2 := gzip.NewReader(mapfile); err2 != nil { + return outmap, err2 + } else { + reader = bufio.NewReader(gr) + } + } else { + reader = bufio.NewReader(mapfile) + } + line, e := utils.Readln(reader) + nl := 1 + for e == nil { + cols := strings.Split(line, "\t") + if len(cols) != 2 { + return outmap, errors.New("Map file does not have 2 fields at line: " + fmt.Sprintf("%d", nl)) + } + if revert { + outmap[cols[1]] = cols[0] + } else { + outmap[cols[0]] = cols[1] + } + line, e = utils.Readln(reader) + nl++ + } + + if err = mapfile.Close(); err != nil { + return outmap, err + } + + return outmap, nil +} diff --git a/download/download.go b/download/download.go new file mode 100644 index 0000000..7e68250 --- /dev/null +++ b/download/download.go @@ -0,0 +1,5 @@ +package download + +type ImageDownloader interface { + Download(id string) ([]byte, error) // Down a tree image from a server +} diff --git a/download/format.go b/download/format.go new file mode 100644 index 0000000..fd475f1 --- /dev/null +++ b/download/format.go @@ -0,0 +1,39 @@ +package download + +const ( + IMGFORMAT_SVG = 0 + IMGFORMAT_PNG = 1 + IMGFORMAT_EPS = 2 + IMGFORMAT_PDF = 3 + IMGFORMAT_UNKNOWN = 4 +) + +func Format(format string) int { + switch format { + case "svg": + return IMGFORMAT_SVG + case "png": + return IMGFORMAT_PNG + case "eps": + return IMGFORMAT_EPS + case "pdf": + return IMGFORMAT_PDF + default: + return IMGFORMAT_UNKNOWN + } +} + +func StrFormat(format int) string { + switch format { + case IMGFORMAT_SVG: + return "svg" + case IMGFORMAT_PNG: + return "png" + case IMGFORMAT_EPS: + return "eps" + case IMGFORMAT_PDF: + return "pdf" + default: + return "unknown" + } +} diff --git a/download/itol.go b/download/itol.go new file mode 100644 index 0000000..5f6f72c --- /dev/null +++ b/download/itol.go @@ -0,0 +1,50 @@ +package download + +import ( + "errors" + "io/ioutil" + "net/http" + "net/url" +) + +type ItolImageDownloader struct { + config map[string]string +} + +func NewItolImageDownloader(config map[string]string) *ItolImageDownloader { + return &ItolImageDownloader{config} +} + +// Down a tree image from ITOL +func (d *ItolImageDownloader) Download(id string, format int) ([]byte, error) { + posturl := "http://itol.embl.de/batch_downloader.cgi" + var err error + var postresponse *http.Response + var responsebody []byte + + form := url.Values{} + form.Add("tree", id) + + strformat := StrFormat(format) + if strformat == "unknown" { + return nil, errors.New("Output image format unknown") + } + form.Add("format", strformat) + + for k, v := range d.config { + if k != "" && v != "" { + form.Add(k, v) + } + } + postresponse, err = http.PostForm(posturl, form) + + defer postresponse.Body.Close() + if responsebody, err = ioutil.ReadAll(postresponse.Body); err != nil { + return nil, err + } + + if postresponse.Header.Get("Content-Type") == "text/html" { + return nil, errors.New(string(responsebody)) + } + return responsebody, nil +} diff --git a/upload/itol.go b/upload/itol.go index 1aeee9b..145a6fc 100644 --- a/upload/itol.go +++ b/upload/itol.go @@ -24,7 +24,7 @@ type ItolUploader struct { // Initialize a new itoluploader // if uploadid=="", then tree will be public and deleted // after 30 days -func NewItolUploader(uploadid, projectname string, annotationfiles []string) *ItolUploader { +func NewItolUploader(uploadid, projectname string, annotationfiles ...string) *ItolUploader { return &ItolUploader{uploadid, projectname, annotationfiles} }