| 
					
				 | 
			
			
				@@ -12,6 +12,7 @@ import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"reflect" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"strings" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"github.com/gocarina/gocsv" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"github.com/gorilla/schema" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -20,6 +21,7 @@ type Renderer interface { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type JSONRenderer struct{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+type CSVRenderer struct{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type htmlTemplateData struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Data    interface{} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -51,6 +53,11 @@ func init() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		panic(err) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	csvRenderer, err := NewCSVRenderer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		panic(err) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Render = make(map[string]func(http.ResponseWriter, *http.Request, interface{}, ...url.Values)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Render["html"] = func(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -61,6 +68,10 @@ func init() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		jsonRenderer.Render(w, r, data, options...) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	Render["csv"] = func(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		csvRenderer.Render(w, r, data, options...) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func query(values ...string) template.URL { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -108,6 +119,35 @@ func (rend *JSONRenderer) Render(w http.ResponseWriter, r *http.Request, data in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func NewCSVRenderer() (*CSVRenderer, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return &CSVRenderer{}, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (rend *CSVRenderer) Render(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	w.Header().Set("Content-Type", "text/csv; charset=utf-8") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if isErrorType(data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		j, err := json.Marshal(JsonResponse{nil, []byte(data.(error).Error())}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.WriteHeader(http.StatusInternalServerError) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.Write(j) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		result, err := gocsv.MarshalString(data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		response, err := json.Marshal(JsonResponse{[]byte(result), nil}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.Write(response) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type HTMLRenderer struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	TemplatePath string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |