func TestGet(t *testing.T) { settings, err := Open("_examples/input/settings.yaml") if err != nil { t.Errorf("Test failed.") } test1 := "Hello World!" val1 := to.String(settings.Get("test_string")) if val1 != test1 { t.Errorf("Got %t expecting %t.", val1, test1) } val2 := int(to.Int64(settings.Get("non_defined_int"))) if val2 != 0 { t.Errorf("Test failed.") } test3 := "Third" val3 := settings.Get("test_map", "element_3", "test_sequence").([]interface{}) if val3[2] != test3 { t.Errorf("Got %t expecting %t.", val3[2], test3) } test5 := "Hello World!" val5 := to.String(settings.Get("test_string")) if test5 != val5 { t.Errorf("Got %t expecting %t.", test5, val5) } test6 := 1234 val6 := int(to.Int64(settings.Get("test_int"))) if test6 != val6 { t.Errorf("Got %t expecting %t.", test6, val6) } test7 := float64(1.2) val7 := to.Float64(settings.Get("test_float")) if test7 != val7 { t.Errorf("Got %t expecting %t.", test7, val7) } test8 := true val8 := to.Bool(settings.Get("test_bool")) if test8 != val8 { t.Errorf("Got %t expecting %t.", test8, val8) } }
// Loads settings func loadSettings(file string) (*yaml.Yaml, error) { var entries map[interface{}]interface{} var ok bool // Trying to read settings from file. y, err := yaml.Open(file) if err != nil { return nil, err } // Loading and verifying host entries if entries, ok = y.Get("hosts").(map[interface{}]interface{}); ok == false { return nil, errors.New("Missing \"hosts\" entry.") } h := map[string]*host.Host{} // Populating host entries. for key := range entries { name := to.String(key) path := to.String(entries[name]) info, err := os.Stat(path) if err != nil { return nil, fmt.Errorf("Failed to validate host %s: %q.", name, err) } if info.IsDir() == false { return nil, fmt.Errorf("Host %s does not point to a directory.", name) } h[name], err = host.New(name, path) if err != nil { return nil, fmt.Errorf("Failed to initialize host %s: %q.", name, err) } } for name := range hosts { hosts[name].Close() } hosts = h if _, ok := hosts["default"]; ok == false { log.Printf("Warning: default host was not provided.\n") } return y, nil }
/* Appends items into the table. An item could be either a map or a struct. */ func (self *Table) Append(items ...interface{}) ([]db.Id, error) { ids := make([]db.Id, len(items)) for i, item := range items { fields, values, err := self.FieldValues(item, toInternal) // Error ocurred, stop appending. if err != nil { return ids, err } res, err := self.source.doExec( fmt.Sprintf("INSERT INTO `%s`", self.Name()), sqlFields(fields), "VALUES", sqlValues(values), ) // Error ocurred, stop appending. if err != nil { return ids, err } // Last inserted ID could be zero too. id, _ := res.LastInsertId() ids[i] = db.Id(to.String(id)) } return ids, nil }
func (a *ABF) getJSONList(id uint64) (list map[string]interface{}, err error) { req, err := http.NewRequest("GET", abfURL+"/api/v1/build_lists/"+to.String(id)+".json", nil) if err != nil { return } req.SetBasicAuth(abfUser, abfAPIKey) resp, err := abfClient.Do(req) if err != nil { return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return } var result map[string]interface{} err = json.Unmarshal(body, &result) if err != nil { return } dig.Get(&result, &list, "build_list") return }
func (a *ABF) makeBuildList(list map[string]interface{}) (*models.List, error) { pkg := a.makePkgList(list) changelog := "" var logs []interface{} dig.Get(&list, &logs, "logs") for _, v := range logs { asserted := v.(map[string]interface{}) if dig.String(&asserted, "file_name") == "changelog.log" { changelog = dig.String(&asserted, "url") break } } handleID := to.String(dig.Uint64(&list, "id")) handleProject := dig.String(&list, "project", "fullname") platform := dig.String(&list, "save_to_repository", "platform", "name") bl := models.List{ Name: dig.String(&list, "project", "name"), Platform: platform, Channel: dig.String(&list, "save_to_repository", "name"), Variants: dig.String(&list, "arch", "name"), Artifacts: pkg, Links: []models.ListLink{ { Name: models.LinkMain, URL: fmt.Sprintf("%s/build_lists/%v", abfURL, handleID), }, { Name: models.LinkChangelog, URL: changelog, }, { Name: models.LinkSCM, URL: fmt.Sprintf("%s/%v/commits/%v", abfURL, handleProject, platform), }, }, Changes: changelog, BuildDate: time.Unix(dig.Int64(&list, "updated_at"), 0), StageCurrent: models.ListStageNotStarted, StageResult: models.ListRunning, Activity: []models.ListActivity{ { UserID: models.FindUser(models.UserSystem).ID, Activity: "Imported this build list from ABF.", }, }, IntegrationName: "abf", IntegrationOne: "[" + handleID + "]", IntegrationTwo: dig.String(&list, "commit_hash"), } return &bl, nil }
// Converts a Go value into internal database representation. func toInternal(val interface{}) interface{} { switch t := val.(type) { case db.Marshaler: return t case []byte: return string(t) case *time.Time: if t == nil || t.IsZero() { return sqlgen.Value{sqlgen.Raw{sqlNull}} } return t.Format(DateFormat) case time.Time: if t.IsZero() { return sqlgen.Value{sqlgen.Raw{sqlNull}} } return t.Format(DateFormat) case time.Duration: return fmt.Sprintf(TimeFormat, int(t/time.Hour), int(t/time.Minute%60), int(t/time.Second%60), t%time.Second/time.Millisecond) case sql.NullBool: if t.Valid { if t.Bool { return toInternal(t.Bool) } return false } return sqlgen.Value{sqlgen.Raw{sqlNull}} case sql.NullFloat64: if t.Valid { if t.Float64 != 0.0 { return toInternal(t.Float64) } return float64(0) } return sqlgen.Value{sqlgen.Raw{sqlNull}} case sql.NullInt64: if t.Valid { if t.Int64 != 0 { return toInternal(t.Int64) } return 0 } return sqlgen.Value{sqlgen.Raw{sqlNull}} case sql.NullString: if t.Valid { return toInternal(t.String) } return sqlgen.Value{sqlgen.Raw{sqlNull}} case bool: if t == true { return `1` } return `0` } return to.String(val) }
func ActivityJSONHandler(ctx context.Context, rw http.ResponseWriter, r *http.Request) { dataRenderer := data.FromContext(ctx) page := int(to.Int64(r.FormValue("page"))) if page <= 0 { page = 1 } limit := int(to.Int64(r.FormValue("limit"))) if limit <= 0 { limit = 50 } var cnt int if err := models.DB.Model(&models.ListActivity{}).Count(&cnt).Error; err != nil { panic(err) } totalpages := cnt / 50 if cnt%50 != 0 { totalpages++ } if page > totalpages { page = totalpages } var activities []models.ListActivity if err := models.DB.Limit(limit).Offset((page - 1) * limit).Order("created_at desc").Find(&activities).Error; err != nil && err != gorm.ErrRecordNotFound { panic(err) } // render a better karma view var rendered []*activityJSON for _, v := range activities { // load the username... rendered = append(rendered, &activityJSON{ ListId: v.ListID, User: models.FindUserByID(v.UserID).Username, Comment: string(bluemonday.UGCPolicy().SanitizeBytes(blackfriday.MarkdownCommon([]byte(v.Activity)))), Time: v.CreatedAt, URL: render.ConvertURL("/b/" + to.String(v.ListID)), }) } dataRenderer.Data = map[string]interface{}{ "totalpages": totalpages, "page": page, "activities": rendered, } dataRenderer.Type = data.DataJSON }
// BuildGetHandler displays build information for a specific build func BuildGetHandler(ctx context.Context, rw http.ResponseWriter, r *http.Request) { dataRenderer := data.FromContext(ctx) toRender := map[string]interface{}{} id := to.Uint64(pat.Param(ctx, "id")) var pkg models.List if err := models.DB.Where("id = ?", id).First(&pkg).Error; err != nil { if err == gorm.ErrRecordNotFound { panic(ErrNotFound) } else { panic(err) } } toRender["Title"] = "Build " + to.String(id) + ": " + pkg.Name toRender["Nav"] = 2 toRender["ID"] = to.String(id) dataRenderer.Data = toRender dataRenderer.Template = "builds/build" }
// Loads templates with .tpl extension from the templates directory. At this // moment only index.tpl is expected. func (host *Host) loadTemplates() error { tpldir := to.String(host.Settings.Get("document", "templates")) if tpldir == "" { tpldir = "templates" } tplroot := host.DocumentRoot + PS + tpldir fp, err := os.Open(tplroot) if err != nil { return fmt.Errorf("Error trying to open %s: %s", tplroot, err.Error()) } host.TemplateRoot = tplroot defer fp.Close() files, err := fp.Readdir(-1) if err != nil { return fmt.Errorf("Error reading directory %s: %s", tplroot, err.Error()) } for _, fp := range files { if strings.HasSuffix(fp.Name(), ".tpl") == true { file := host.TemplateRoot + PS + fp.Name() err := host.loadTemplate(file) if err != nil { log.Printf("%s: Template error in file %s: %s\n", host.Name, file, err.Error()) } } } if _, ok := host.Templates["index.tpl"]; ok == false { return fmt.Errorf("Template %s could not be found.", "index.tpl") } return nil }
// loadTemplates loads templates with .tpl extension from the templates // directory. At this moment only index.tpl is expected. func (host *Host) loadTemplates() error { var err error var fp *os.File tpldir := to.String(host.Settings.Get("content", "templates")) if tpldir == "" { tpldir = "templates" } tplroot := host.DocumentRoot + pathSeparator + tpldir if fp, err = os.Open(tplroot); err != nil { return fmt.Errorf("Error trying to open %s: %q", tplroot, err) } defer fp.Close() host.TemplateRoot = tplroot var files []os.FileInfo if files, err = fp.Readdir(-1); err != nil { return fmt.Errorf("Error reading directory %s: %q", tplroot, err) } for _, fp := range files { if strings.HasSuffix(fp.Name(), ".tpl") == true { file := host.TemplateRoot + pathSeparator + fp.Name() err := host.loadTemplate(file) if err != nil { log.Printf("%s: Template error in file %s: %q\n", host.Name, file, err) } } } if _, ok := host.Templates["index.tpl"]; ok == false { return fmt.Errorf("Template %s could not be found.", "index.tpl") } return nil }
/* Appends items into the table. An item could be either a map or a struct. */ func (self *Table) Append(items ...interface{}) ([]db.Id, error) { ids := make([]db.Id, len(items)) for i, item := range items { fields, values, err := self.FieldValues(item, toInternal) // Error ocurred, stop appending. if err != nil { return ids, err } tail := "" if _, ok := self.ColumnTypes[self.PrimaryKey]; ok == true { tail = fmt.Sprintf("RETURNING %s", self.PrimaryKey) } row, err := self.source.doQueryRow( fmt.Sprintf(`INSERT INTO "%s"`, self.Name()), sqlFields(fields), "VALUES", sqlValues(values), tail, ) // Error ocurred, stop appending. if err != nil { return ids, err } var id int err = row.Scan(&id) // Error ocurred, stop appending. if err != nil { return ids, err } // Last inserted ID could be zero too. ids[i] = db.Id(to.String(id)) } return ids, nil }
// Converts a Go value into internal database representation. func toInternal(val interface{}) interface{} { switch t := val.(type) { case []byte: return string(t) case time.Time: return t.Format(DateFormat) case time.Duration: return fmt.Sprintf(TimeFormat, int(t/time.Hour), int(t/time.Minute%60), int(t/time.Second%60), t%time.Second/time.Millisecond) case bool: if t == true { return `1` } else { return `0` } } return to.String(val) }
/* Converts a Go value into internal database representation. */ func toInternal(val interface{}) string { switch t := val.(type) { case []byte: return string(t) case time.Time: return t.Format(DateFormat) case time.Duration: return fmt.Sprintf(TimeFormat, int(t.Hours()), int(t.Minutes())%60, int(t.Seconds())%60, uint64(t.Nanoseconds())%1e9) case bool: if t == true { return "1" } else { return "0" } } return to.String(val) }
// Accept tells ABF to publish the build lists specified in the List. func (a *ABF) Accept(m *models.List) error { for _, v := range strings.Split(m.IntegrationOne, ";") { noBrackets := v[1 : len(v)-1] id := to.Uint64(noBrackets) req, err := http.NewRequest("PUT", abfURL+"/api/v1/build_lists/"+to.String(id)+"/publish.json", nil) if err != nil { return err } req.SetBasicAuth(abfUser, abfAPIKey) req.Header.Add("Content-Length", "0") resp, err := abfClient.Do(req) if err != nil { return err } defer resp.Body.Close() } return nil }
func (a *ABF) sendToTesting(id uint64) error { req, err := http.NewRequest("PUT", abfURL+"/api/v1/build_lists/"+to.String(id)+"/publish_into_testing.json", nil) if err != nil { return err } req.SetBasicAuth(abfUser, abfAPIKey) req.Header.Add("Content-Length", "0") resp, err := abfClient.Do(req) if err != nil { fmt.Fprintf(os.Stderr, "failed to send %d to testing: %s\n", id, err.Error()) return err } defer resp.Body.Close() // we are not doing this again... //bte, _ := ioutil.ReadAll(resp.Body) //fmt.Printf("sending %d to testing yielded %s\n", id, bte) return nil }
func (host *Host) getContentPath() (string, error) { var directories []string contentdir := to.String(host.Settings.Get("content", "markdown")) if contentdir == "" { directories = []string{ "content", "markdown", } } else { directories = []string{contentdir} } for _, directory := range directories { path := host.DocumentRoot + pathSeparator + directory if _, err := os.Stat(path); err == nil { return path, nil } } return "", errors.New(`Content directory was not found.`) }
// Attempts to fetch results one by one. func TestResultFetch(t *testing.T) { var err error var res db.Result var sess db.Database var artist db.Collection if sess, err = db.Open(Adapter, settings); err != nil { t.Fatal(err) } defer sess.Close() if artist, err = sess.Collection("artist"); err != nil { t.Fatal(err) } // Dumping into a map. rowMap := map[string]interface{}{} res = artist.Find() for { err = res.Next(&rowMap) if err == db.ErrNoMoreRows { break } if err == nil { if to.Int64(rowMap["id"]) == 0 { t.Fatalf("Expecting a not null ID.") } if to.String(rowMap["name"]) == "" { t.Fatalf("Expecting a name.") } } else { t.Fatal(err) } } res.Close() // Dumping into an struct with no tags. rowStruct := struct { ID uint64 Name string }{} res = artist.Find() for { err = res.Next(&rowStruct) if err == db.ErrNoMoreRows { break } if err == nil { if rowStruct.ID == 0 { t.Fatalf("Expecting a not null ID.") } if rowStruct.Name == "" { t.Fatalf("Expecting a name.") } } else { t.Fatal(err) } } res.Close() // Dumping into a tagged struct. rowStruct2 := struct { Value1 uint64 `field:"id"` Value2 string `field:"name"` }{} res = artist.Find() for { err = res.Next(&rowStruct2) if err == db.ErrNoMoreRows { break } if err == nil { if rowStruct2.Value1 == 0 { t.Fatalf("Expecting a not null ID.") } if rowStruct2.Value2 == "" { t.Fatalf("Expecting a name.") } } else { t.Fatal(err) } } res.Close() // Dumping into an slice of maps. allRowsMap := []map[string]interface{}{} res = artist.Find() if err = res.All(&allRowsMap); err != nil { t.Fatal(err) } if len(allRowsMap) != 4 { t.Fatalf("Expecting 4 items.") } for _, singleRowMap := range allRowsMap { if to.Int64(singleRowMap["id"]) == 0 { t.Fatalf("Expecting a not null ID.") } } // Dumping into an slice of structs. allRowsStruct := []struct { ID uint64 Name string }{} res = artist.Find() if err = res.All(&allRowsStruct); err != nil { t.Fatal(err) } if len(allRowsStruct) != 4 { t.Fatalf("Expecting 4 items.") } for _, singleRowStruct := range allRowsStruct { if singleRowStruct.ID == 0 { t.Fatalf("Expecting a not null ID.") } } // Dumping into an slice of tagged structs. allRowsStruct2 := []struct { Value1 uint64 `field:"id"` Value2 string `field:"name"` }{} res = artist.Find() if err = res.All(&allRowsStruct2); err != nil { t.Fatal(err) } if len(allRowsStruct2) != 4 { t.Fatalf("Expecting 4 items.") } for _, singleRowStruct2 := range allRowsStruct2 { if singleRowStruct2.Value1 == 0 { t.Fatalf("Expecting a not null ID.") } } }
func (self *T) FieldValues(item interface{}, convertFn func(interface{}) string) ([]string, []string, error) { fields := []string{} values := []string{} itemv := reflect.ValueOf(item) itemt := itemv.Type() switch itemt.Kind() { case reflect.Struct: nfields := itemv.NumField() values = make([]string, 0, nfields) fields = make([]string, 0, nfields) for i := 0; i < nfields; i++ { field := itemt.Field(i) if field.PkgPath == "" { value := itemv.Field(i).Interface() // Struct tags tag := field.Tag // omitempty:bool if tag.Get("omitempty") == "true" { zero := reflect.Zero(reflect.TypeOf(value)).Interface() if value == zero { continue } } // field:string fieldName := tag.Get("field") if fieldName == "-" { // Skip the field if its tag's value is - continue } if fieldName == "" { fieldName = self.ColumnLike(field.Name) } // inline:bool if tag.Get("inline") == "true" { infields, invalues, inerr := self.FieldValues(value, convertFn) if inerr != nil { return nil, nil, inerr } fields = append(fields, infields...) values = append(values, invalues...) } else { fields = append(fields, fieldName) values = append(values, convertFn(value)) } } } case reflect.Map: nfields := itemv.Len() values = make([]string, nfields) fields = make([]string, nfields) mkeys := itemv.MapKeys() for i, keyv := range mkeys { valv := itemv.MapIndex(keyv) fields[i] = self.ColumnLike(to.String(keyv.Interface())) values[i] = convertFn(valv.Interface()) } default: return nil, nil, db.ErrExpectingMapOrStruct } return fields, values, nil }
func TestApi(t *testing.T) { var err error client := New(&oauth.Credentials{ to.String(conf.Get("twitter", "app", "key")), to.String(conf.Get("twitter", "app", "secret")), }) client.SetAuth(&oauth.Credentials{ to.String(conf.Get("twitter", "user", "token")), to.String(conf.Get("twitter", "user", "secret")), }) _, err = client.VerifyCredentials(nil) if err != nil { t.Errorf("Test failed: %s\n", err.Error()) } _, err = client.HomeTimeline(nil) if err != nil { t.Errorf("Test failed: %s\n", err.Error()) } _, err = client.MentionsTimeline(nil) if err != nil { t.Errorf("Test failed: %s\n", err.Error()) } _, err = client.UserTimeline(nil) if err != nil { t.Errorf("Test failed: %s\n", err.Error()) } _, err = client.RetweetsOfMe(nil) if err != nil { t.Errorf("Test failed: %s\n", err.Error()) } _, err = client.Retweets(int64(21947795900469248), nil) if err != nil { t.Errorf("Test failed: %s\n", err.Error()) } var status *map[string]interface{} status, err = client.Update(fmt.Sprintf("Test message @ %s", time.Now()), nil) if err != nil { t.Errorf("Test failed: %s\n", err.Error()) } tweetId := dig.Int64(status, "id_str") _, err = client.Destroy(tweetId, nil) if err != nil { t.Errorf("Test failed: %s\n", err.Error()) } tweetId = dig.Int64(status, "id_str") files := []string{ "_resources/test.jpg", } _, err = client.UpdateWithMedia("Hello", nil, files) if err != nil { t.Errorf("Test failed: %s\n", err.Error()) } _, err = client.Retweet(int64(21947795900469248), nil) if err != nil { t.Errorf("Test failed: %s\n", err.Error()) } }
// This test uses and result and tries to fetch items one by one. func TestResultFetch(t *testing.T) { var err error var res db.Result // Opening database. sess, err := db.Open(Adapter, settings) if err != nil { t.Fatal(err) } // We should close the database when it's no longer in use. defer sess.Close() artist, err := sess.Collection("artist") if err != nil { t.Fatal(err) } // Testing map res = artist.Find() row_m := map[string]interface{}{} for { err = res.Next(&row_m) if err == db.ErrNoMoreRows { // No more row_ms left. break } if err == nil { if row_m["_id"] == nil { t.Fatalf("Expecting an ID.") } if _, ok := row_m["_id"].(bson.ObjectId); ok != true { t.Fatalf("Expecting a bson.ObjectId.") } if row_m["_id"].(bson.ObjectId).Valid() != true { t.Fatalf("Expecting a valid bson.ObjectId.") } if to.String(row_m["name"]) == "" { t.Fatalf("Expecting a name.") } } else { t.Fatal(err) } } res.Close() // Testing struct row_s := struct { Id bson.ObjectId `bson:"_id"` Name string `bson:"name"` }{} res = artist.Find() for { err = res.Next(&row_s) if err == db.ErrNoMoreRows { // No more row_s' left. break } if err == nil { if row_s.Id.Valid() == false { t.Fatalf("Expecting a not null ID.") } if row_s.Name == "" { t.Fatalf("Expecting a name.") } } else { t.Fatal(err) } } res.Close() // Testing tagged struct row_t := struct { Value1 bson.ObjectId `bson:"_id"` Value2 string `bson:"name"` }{} res = artist.Find() for { err = res.Next(&row_t) if err == db.ErrNoMoreRows { // No more row_t's left. break } if err == nil { if row_t.Value1.Valid() == false { t.Fatalf("Expecting a not null ID.") } if row_t.Value2 == "" { t.Fatalf("Expecting a name.") } } else { t.Fatal(err) } } res.Close() // Testing Result.All() with a slice of maps. res = artist.Find() all_rows_m := []map[string]interface{}{} err = res.All(&all_rows_m) if err != nil { t.Fatal(err) } for _, single_row_m := range all_rows_m { if single_row_m["_id"] == nil { t.Fatalf("Expecting a not null ID.") } } // Testing Result.All() with a slice of structs. res = artist.Find() all_rows_s := []struct { Id bson.ObjectId `bson:"_id"` Name string }{} err = res.All(&all_rows_s) if err != nil { t.Fatal(err) } for _, single_row_s := range all_rows_s { if single_row_s.Id.Valid() == false { t.Fatalf("Expecting a not null ID.") } } // Testing Result.All() with a slice of tagged structs. res = artist.Find() all_rows_t := []struct { Value1 bson.ObjectId `bson:"_id"` Value2 string `bson:"name"` }{} err = res.All(&all_rows_t) if err != nil { t.Fatal(err) } for _, single_row_t := range all_rows_t { if single_row_t.Value1.Valid() == false { t.Fatalf("Expecting a not null ID.") } } }
// Execute runs a luminos server using a settings file. func (c *runCommand) Execute() (err error) { var stat os.FileInfo // If no settings file was specified, use the default. if *flagSettings == "" { *flagSettings = envSettingsFile } // Attempt to stat the settings file. stat, err = os.Stat(*flagSettings) // It must not return an error. if err != nil { return fmt.Errorf("Error while opening %s: %q", *flagSettings, err) } // We must have a value in stat. if stat == nil { return fmt.Errorf("Could not load settings file: %s.", *flagSettings) } // And the file must not be a directory. if stat.IsDir() { return fmt.Errorf("Could not open %s: it's a directory!", *flagSettings) } // Now that we're positively sure that we have a valid file, let's try to // read settings from it. if settings, err = loadSettings(*flagSettings); err != nil { return fmt.Errorf("Error while reading settings file %s: %q", *flagSettings, err) } // Starting settings watcher. if err = settingsWatcher(); err == nil { watch.Watch(*flagSettings) } // Reading setttings. serverType := to.String(settings.Get("server", "type")) domain := envServerDomain address := to.String(settings.Get("server", "socket")) if address == "" { domain = envServerProtocol address = fmt.Sprintf("%s:%d", to.String(settings.Get("server", "bind")), to.Int64(settings.Get("server", "port"))) } // Creating a network listener. var listener net.Listener if listener, err = net.Listen(domain, address); err != nil { return fmt.Errorf("Could not create network listener: %q", err) } // Listener must be closed when the function exits. defer listener.Close() // Attempt to start a server. switch serverType { case "fastcgi": if err == nil { log.Printf("Starting FastCGI server. Listening at %s.\n", address) fcgi.Serve(listener, &server{}) } else { return fmt.Errorf("Failed to start FastCGI server: %q", err) } case "standalone": if err == nil { log.Printf("Starting HTTP server. Listening at %s.\n", address) http.Serve(listener, &server{}) } else { return fmt.Errorf("Failed to start HTTP server: %q", err) } default: return fmt.Errorf("Unknown server type: %s", serverType) } return nil }
// This test uses and result and tries to fetch items one by one. func TestResultFetch(t *testing.T) { var err error var res db.Result // Opening database. sess, err := db.Open(wrapperName, settings) if err != nil { t.Fatalf(err.Error()) } // We should close the database when it's no longer in use. defer sess.Close() artist, err := sess.Collection("artist") if err != nil { t.Fatalf(err.Error()) } // Testing map res = artist.Find() row_m := map[string]interface{}{} for { err = res.Next(&row_m) if err == db.ErrNoMoreRows { // No more row_ms left. break } if err == nil { if to.Int64(row_m["id"]) == 0 { t.Fatalf("Expecting a not null ID.") } if to.String(row_m["name"]) == "" { t.Fatalf("Expecting a name.") } } else { t.Fatalf(err.Error()) } } res.Close() // Testing struct row_s := struct { Id uint64 Name string }{} res = artist.Find() for { err = res.Next(&row_s) if err == db.ErrNoMoreRows { // No more row_s' left. break } if err == nil { if row_s.Id == 0 { t.Fatalf("Expecting a not null ID.") } if row_s.Name == "" { t.Fatalf("Expecting a name.") } } else { t.Fatalf(err.Error()) } } res.Close() // Testing tagged struct row_t := struct { Value1 uint64 `field:"id"` Value2 string `field:"name"` }{} res = artist.Find() for { err = res.Next(&row_t) if err == db.ErrNoMoreRows { // No more row_t's left. break } if err == nil { if row_t.Value1 == 0 { t.Fatalf("Expecting a not null ID.") } if row_t.Value2 == "" { t.Fatalf("Expecting a name.") } } else { t.Fatalf(err.Error()) } } res.Close() // Testing Result.All() with a slice of maps. res = artist.Find() all_rows_m := []map[string]interface{}{} err = res.All(&all_rows_m) if err != nil { t.Fatalf(err.Error()) } for _, single_row_m := range all_rows_m { if to.Int64(single_row_m["id"]) == 0 { t.Fatalf("Expecting a not null ID.") } } // Testing Result.All() with a slice of structs. res = artist.Find() all_rows_s := []struct { Id uint64 Name string }{} err = res.All(&all_rows_s) if err != nil { t.Fatalf(err.Error()) } for _, single_row_s := range all_rows_s { if single_row_s.Id == 0 { t.Fatalf("Expecting a not null ID.") } } // Testing Result.All() with a slice of tagged structs. res = artist.Find() all_rows_t := []struct { Value1 uint64 `field:"id"` Value2 string `field:"name"` }{} err = res.All(&all_rows_t) if err != nil { t.Fatalf(err.Error()) } for _, single_row_t := range all_rows_t { if single_row_t.Value1 == 0 { t.Fatalf("Expecting a not null ID.") } } }
func main() { klog.Info("starting kahinah v4") // -- mux ----------------------------------------------------------------- mux := goji.NewMux() // -- middleware ---------------------------------------------------------- // logging middleware (base middleware) mux.UseC(func(inner goji.Handler) goji.Handler { return goji.HandlerFunc(func(ctx context.Context, rw http.ResponseWriter, r *http.Request) { klog.Debugf("req (%v): path (%v), user-agent (%v), referrer (%v)", r.RemoteAddr, r.RequestURI, r.UserAgent(), r.Referer()) wp := mutil.WrapWriter(rw) // proxy the rw for info later inner.ServeHTTPC(ctx, wp, r) klog.Debugf("resp (%v): status (%v), bytes written (%v)", r.RemoteAddr, wp.Status(), wp.BytesWritten()) }) }) // rendering middleware (required by panic) renderer := urender.New(urender.Options{ Directory: "views", Layout: "layout", Extensions: []string{".tmpl", ".tpl"}, Funcs: []template.FuncMap{ template.FuncMap{ "rfc3339": func(t time.Time) string { return t.Format(time.RFC3339) }, "since": func(t time.Time) string { hrs := time.Since(t).Hours() return fmt.Sprintf("%dd %02dhrs", int(hrs)/24, int(hrs)%24) }, "emailat": func(s string) string { return strings.Replace(s, "@", " [@T] ", -1) }, "mapaccess": func(s interface{}, m map[string]string) string { return m[to.String(s)] }, "url": render.ConvertURL, "urldata": render.ConvertURLWithData, }, }, IndentJSON: true, IndentXML: true, IsDevelopment: conf.GetDefault("runMode", "dev").(string) == "dev", }) mux.UseC(func(inner goji.Handler) goji.Handler { return goji.HandlerFunc(func(ctx context.Context, rw http.ResponseWriter, r *http.Request) { newCtx := render.NewContext(ctx, renderer) inner.ServeHTTPC(newCtx, rw, r) }) }) // panic middleware mux.UseC(controllers.PanicMiddleware) // not found middleware mux.UseC(func(inner goji.Handler) goji.Handler { return goji.HandlerFunc(func(ctx context.Context, rw http.ResponseWriter, r *http.Request) { routeFound := middleware.Pattern(ctx) if routeFound != nil { inner.ServeHTTPC(ctx, rw, r) return } panic(controllers.ErrNotFound) }) }) // authentication (cas) middleware if enable, ok := conf.GetDefault("authentication.cas.enable", false).(bool); ok && enable { url, _ := url.Parse(conf.Get("authentication.cas.url").(string)) casClient := cas.NewClient(&cas.Options{ URL: url, }) mux.Use(casClient.Handle) } // sessions middleware sessionConfig := &sessionmw.Config{ Secret: []byte(securecookie.GenerateRandomKey(64)), BlockSecret: []byte(securecookie.GenerateRandomKey(32)), Store: kv.NewMemStore(), Name: "kahinah", } mux.UseC(sessionConfig.Handler) // csrf middleware mux.UseC(csrf.Protect(securecookie.GenerateRandomKey(64), csrf.Secure(false))) // data rendering middleware mux.UseC(func(inner goji.Handler) goji.Handler { return goji.HandlerFunc(func(ctx context.Context, rw http.ResponseWriter, r *http.Request) { newCtx := data.RenderMiddleware(ctx, rw, r) inner.ServeHTTPC(newCtx, rw, r) data.RenderAfterware(newCtx, rw, r) }) }) // -------------------------------------------------------------------- // HANDLERS // -------------------------------------------------------------------- getHandlers := map[string]goji.HandlerFunc{ // static paths "/static/*": controllers.StaticHandler, // main page "/": controllers.MainHandler, // builds - json "/i/list/json/": controllers.ListsAPIHandler, // builds "/i/list/": controllers.ListsHandler, // build - specific "/b/:id/": controllers.BuildGetHandler, // build - specific - json "/b/:id/json/": controllers.BuildGetJSONHandler, // activity - json "/i/activity/json/": controllers.ActivityJSONHandler, // activity - html "/i/activity/": controllers.ActivityHandler, // admin "/admin/": controllers.AdminGetHandler, // authentication - login "/u/login/": controllers.UserLoginHandler, // authentication - logout "/u/logout/": controllers.UserLogoutHandler, } postHandlers := map[string]goji.HandlerFunc{ // webhooks "/hook/*": controllers.IntegrationHandler, // build - specific "/b/:id/": controllers.BuildPostHandler, // admin "/admin/": controllers.AdminPostHandler, } for k, v := range getHandlers { if len(k) > 1 && strings.HasSuffix(k, "/") { getHandlerRedirectName := render.ConvertURLRelative(k[:len(k)-1]) klog.Debugf("get handler setup: redirecting %v", getHandlerRedirectName) mux.HandleFunc(pat.Get(getHandlerRedirectName), controllers.RedirectHandler) } getHandlerUseName := render.ConvertURLRelative(k) klog.Debugf("get handler setup: using %v", getHandlerUseName) mux.HandleC(pat.Get(getHandlerUseName), v) } for k, v := range postHandlers { if len(k) > 1 && strings.HasSuffix(k, "/") { postHandlerRedirectName := render.ConvertURLRelative(k[:len(k)-1]) klog.Debugf("post handler setup: redirecting %v", postHandlerRedirectName) mux.HandleFunc(pat.Post(postHandlerRedirectName), controllers.RedirectHandler) } postHandlerUseName := render.ConvertURLRelative(k) klog.Debugf("post handler setup: using %v", postHandlerUseName) mux.HandleC(pat.Post(postHandlerUseName), v) } // -- cronjobs ---------------------------------------------------------- cronRunner := cron.New() // integration polling if pollRate, ok := conf.Get("integration.poll").(string); ok && pollRate != "" { pollFunc := func() { pollAllErr := integration.PollAll() for name, err := range pollAllErr { klog.Warningf("integration polling failed for %v: %v", name, err) } } cronRunner.AddFunc(pollRate, pollFunc) // and do an initial poll pollFunc() } // process new stages/check processes every 10 seconds cronRunner.AddFunc("@every 10s", func() { models.CheckAllListStages() }) // run the job scheduler every minute cronRunner.AddFunc("@every 1m", func() { job.ProcessQueue() }) // start cron cronRunner.Start() // -- server setup -------------------------------------------------------- // bind and listen listenAddr := conf.GetDefault("listenAddr", "0.0.0.0").(string) listenPort := conf.GetDefault("listenPort", 3000).(int64) klog.Infof("listening to %v:%v", listenAddr, listenPort) if err := http.ListenAndServe(fmt.Sprintf("%v:%v", listenAddr, listenPort), mux); err != nil { klog.Fatalf("unable to serve: %v", err) } cronRunner.Stop() klog.Info("processing leftover jobs...") close(job.Queue) for len(job.Queue) > 0 { job.ProcessQueue() } }
// FieldValues accepts a map or a struct and splits them into an array of // columns and values. func (t *T) FieldValues(item interface{}, convertFn func(interface{}) interface{}) ([]string, []interface{}, error) { fields := []string{} values := []interface{}{} itemV := reflect.ValueOf(item) itemT := itemV.Type() if itemT.Kind() == reflect.Ptr { // Single derefence. Just in case user passed a pointer to struct instead of a struct. item = itemV.Elem().Interface() itemV = reflect.ValueOf(item) itemT = itemV.Type() } switch itemT.Kind() { case reflect.Struct: nfields := itemV.NumField() values = make([]interface{}, 0, nfields) fields = make([]string, 0, nfields) for i := 0; i < nfields; i++ { field := itemT.Field(i) if field.PkgPath != `` { // Field is unexported. continue } if field.Anonymous { // It's an anonymous field. Let's skip it unless it has an explicit // `db` tag. if field.Tag.Get(`db`) == `` { continue } } // Field options. fieldName, fieldOptions := util.ParseTag(field.Tag.Get(`db`)) // Deprecated `field` tag. if deprecatedField := field.Tag.Get(`field`); deprecatedField != `` { fieldName = deprecatedField } // Deprecated `omitempty` tag. if deprecatedOmitEmpty := field.Tag.Get(`omitempty`); deprecatedOmitEmpty != `` { fieldOptions[`omitempty`] = true } // Deprecated `inline` tag. if deprecatedInline := field.Tag.Get(`inline`); deprecatedInline != `` { fieldOptions[`inline`] = true } // Skipping field if fieldName == `-` { continue } // Trying to match field name. // Explicit JSON or BSON options. if fieldName == `` && fieldOptions[`bson`] { // Using name from the BSON tag. fieldName, _ = util.ParseTag(field.Tag.Get(`bson`)) } if fieldName == `` && fieldOptions[`bson`] { // Using name from the JSON tag. fieldName, _ = util.ParseTag(field.Tag.Get(`bson`)) } // Still don't have a match? try to match againt JSON. if fieldName == `` { fieldName, _ = util.ParseTag(field.Tag.Get(`json`)) } // Still don't have a match? try to match againt BSON. if fieldName == `` { fieldName, _ = util.ParseTag(field.Tag.Get(`bson`)) } // Nothing works, trying to match by name. if fieldName == `` { fieldName = t.columnLike(field.Name) } // Processing tag options. value := itemV.Field(i).Interface() if fieldOptions[`omitempty`] == true { zero := reflect.Zero(reflect.TypeOf(value)).Interface() if value == zero { continue } } if fieldOptions[`inline`] == true { infields, invalues, inerr := t.FieldValues(value, convertFn) if inerr != nil { return nil, nil, inerr } fields = append(fields, infields...) values = append(values, invalues...) } else { fields = append(fields, fieldName) v, err := marshal(convertFn(value)) if err != nil { return nil, nil, err } values = append(values, v) } } case reflect.Map: nfields := itemV.Len() values = make([]interface{}, nfields) fields = make([]string, nfields) mkeys := itemV.MapKeys() for i, keyV := range mkeys { valv := itemV.MapIndex(keyV) fields[i] = t.columnLike(to.String(keyV.Interface())) v, err := marshal(convertFn(valv.Interface())) if err != nil { return nil, nil, err } values[i] = v } default: return nil, nil, db.ErrExpectingMapOrStruct } return fields, values, nil }
// Tests datatype conversions. func TestDataTypes(t *testing.T) { var res db.Result var items []db.Item sess, err := db.Open(wrapperName, settings) if err != nil { t.Fatalf(err.Error()) } defer sess.Close() dataTypes := sess.ExistentCollection("data_types") dataTypes.Truncate() ids, err := dataTypes.Append(testValues) if err != nil { t.Fatalf(err.Error()) } found, err := dataTypes.Count(db.Cond{"id": db.Id(ids[0])}) if err != nil { t.Fatalf(err.Error()) } if found == 0 { t.Errorf("Expecting an item.") } // Getting and reinserting (a db.Item). item, _ := dataTypes.Find() _, err = dataTypes.Append(item) if err == nil { t.Fatalf("Expecting duplicated-key error.") } delete(item, "id") _, err = dataTypes.Append(item) if err != nil { t.Fatalf(err.Error()) } // Testing date ranges items, err = dataTypes.FindAll(db.Cond{ "_date": time.Now(), }) if err != nil { t.Fatalf(err.Error()) } if len(items) > 0 { t.Fatalf("Expecting no results.") } items, err = dataTypes.FindAll(db.Cond{ "_date <=": time.Now(), }) if err != nil { t.Fatalf(err.Error()) } if len(items) != 2 { t.Fatalf("Expecting some results.") } // Testing struct sresults := []testValuesStruct{} res, err = dataTypes.Query() if err != nil { t.Fatalf(err.Error()) } err = res.All(&sresults) if err != nil { t.Fatalf(err.Error()) } // Testing struct equality for _, item := range sresults { if reflect.DeepEqual(item, testValues) == false { t.Errorf("Struct is different.") } } // Testing maps results, _ := dataTypes.FindAll() for _, item := range results { for key, _ := range item { switch key { // Signed integers. case "_int", "_int8", "_int16", "_int32", "_int64": if to.Int64(item[key]) != testValues.Int64 { t.Fatalf("Wrong datatype %v.", key) } // Unsigned integers. case "_uint", "_uint8", "_uint16", "_uint32", "_uint64": if to.Uint64(item[key]) != testValues.Uint64 { t.Fatalf("Wrong datatype %v.", key) } // Floating point. case "_float32": case "_float64": if to.Float64(item[key]) != testValues.Float64 { t.Fatalf("Wrong datatype %v.", key) } // Boolean case "_bool": if to.Bool(item[key]) != testValues.Bool { t.Fatalf("Wrong datatype %v.", key) } // String case "_string": if to.String(item[key]) != testValues.String { t.Fatalf("Wrong datatype %v.", key) } // Date case "_date": if to.Time(item[key]).Equal(testValues.Date) == false { t.Fatalf("Wrong datatype %v.", key) } } } } }
func (a *ABF) handleResponse(resp *http.Response, testing bool) error { defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return err } var result map[string]interface{} err = json.Unmarshal(body, &result) if err != nil { return err } var lists []interface{} err = dig.Get(&result, &lists, "build_lists") if err != nil { return err } for _, v := range lists { asserted := v.(map[string]interface{}) id := dig.Uint64(&asserted, "id") strID := "[" + to.String(id) + "]" var num int err = models.DB.Model(&models.List{}).Where("integration_name = ? AND integration_one LIKE ?", "abf", "%"+strID+"%").Count(&num).Error if err != nil && err != gorm.ErrRecordNotFound { klog.Criticalf("abf: couldn't check db for existing (list %v): %v", id, err) continue } if num != 0 { klog.Infof("abf: ignoring list, already processed (list %v)", id) continue } json, err := a.getJSONList(id) if err != nil { klog.Criticalf("abf: couldn't retrieve the build list JSON (list %v): %v", id, err) continue } // check if arch is on whitelist if abfArchWhitelistSet != nil && !abfArchWhitelistSet.Contains(dig.String(&json, "arch", "name")) { klog.Infof("abf: ignoring list, arch not on whitelist (list %v)", id) continue } // check if platform is on whitelist if !abfPlatformsSet.Contains(dig.String(&json, "save_to_repository", "platform", "name")) { klog.Infof("abf: ignoring list, platform not on whitelist (list %v)", id) continue } // *check for duplicates before continuing // *we only check for duplicates in the same platform; different platforms have different conditions // check for duplicates var duplicate models.List err = models.DB.Where("platform = ? AND integration_two = ? AND stage_current <> ?", dig.String(&json, "save_to_repository", "platform", "name"), dig.String(&json, "commit_hash"), models.ListStageFinished).First(&duplicate).Error if err != nil && err != gorm.ErrRecordNotFound { klog.Criticalf("abf: couldn't check db for duplicates (list %v): %v", id, err) continue } if err == nil { // we had no problem finding a duplicate, so handle and continue duplicate.IntegrationOne += ";" + strID duplicate.Variants += ";" + dig.String(&json, "arch", "name") if testing { // we got this from the build completed (not in testing) list // send id to testing go a.sendToTesting(id) } err = models.DB.Save(&duplicate).Error if err != nil { klog.Criticalf("abf: couldn't save duplicate modification to %v (list %v): %v", duplicate.ID, id, err) } pkgs := a.makePkgList(json) for _, listpkg := range pkgs { listpkg.ListID = duplicate.ID err = models.DB.Create(&listpkg).Error if err != nil { klog.Criticalf("abf: couldn't save new list package to %v (list %v): %v", duplicate.ID, id, err) } } // add a link to it newLink := models.ListLink{ ListID: duplicate.ID, Name: fmt.Sprintf("Build List for %v", dig.String(&json, "arch", "name")), URL: fmt.Sprintf("%s/build_lists/%v", abfURL, id), } if err := models.DB.Create(&newLink).Error; err != nil { klog.Criticalf("abf: couldn't save new list link to %v (list %v): %v", duplicate.ID, id, err) } // ok, we're done here continue } list, err := a.makeBuildList(json) if err != nil { klog.Criticalf("abf: couldn't make new list (list %v): %v\n", id, err) continue } if testing { // Now send it to testing go a.sendToTesting(id) } if err := models.DB.Create(list).Error; err != nil { klog.Criticalf("abf: couldn't create new list in db (list %v): %v", id, err) continue } } return nil }
// A simple ServeHTTP. func (host *Host) ServeHTTP(w http.ResponseWriter, req *http.Request) { var localFile string // TODO: Fix this non-critical race condition. // We need to save some variables in a per request basis, in particular the // hostname. It may not always match the host name we gave to it (i.e: the // "default" hostname). A per-request context would be useful. host.Request = req // Default status. status := http.StatusNotFound size := -1 // Requested path reqpath := strings.Trim(req.URL.Path, "/") // Stripping path index := len(host.Path) if reqpath[0:index] == host.Path { reqpath = reqpath[index:] } reqpath = strings.Trim(reqpath, "/") // Trying to match a file on webroot/ webrootdir := to.String(host.Settings.Get("document", "webroot")) if webrootdir == "" { webrootdir = "webroot" } webroot := host.DocumentRoot + PS + webrootdir localFile = webroot + PS + reqpath stat, err := os.Stat(localFile) if err == nil { // File exists if stat.IsDir() == false { // Exists and it's not a directory, let's serve it. status = http.StatusOK http.ServeFile(w, req, localFile) size = int(stat.Size()) } } if status == http.StatusNotFound { docrootdir := to.String(host.Settings.Get("document", "markdown")) if docrootdir == "" { docrootdir = "markdown" } docroot := host.DocumentRoot + PS + docrootdir testFile := docroot + PS + reqpath stat, err = os.Stat(testFile) localFile, stat = guessFile(testFile, true) if stat != nil { if reqpath != "" { if stat.IsDir() == false { if strings.HasSuffix(req.URL.Path, "/") == true { http.Redirect(w, req, "/"+host.Path+"/"+reqpath, 301) w.Write([]byte(http.StatusText(301))) return } } else { if strings.HasSuffix(req.URL.Path, "/") == false { http.Redirect(w, req, req.URL.Path+"/", 301) w.Write([]byte(http.StatusText(301))) return } } } p := &page.Page{} p.FilePath = localFile p.BasePath = req.URL.Path relPath := localFile[len(docroot):] if stat.IsDir() == false { p.FileDir = path.Dir(localFile) p.BasePath = path.Dir(relPath) } else { p.FileDir = localFile p.BasePath = relPath } content, err := host.readFile(localFile) if err == nil { p.Content = template.HTML(content) } p.FileDir = strings.TrimRight(p.FileDir, PS) + PS p.BasePath = strings.TrimRight(p.BasePath, PS) + PS // werc-like header and footer. hfile, hstat := guessFile(p.FileDir+"_header", true) if hstat != nil { hcontent, herr := host.readFile(hfile) if herr == nil { p.ContentHeader = template.HTML(hcontent) } } if p.BasePath == "/" { p.IsHome = true } // werc-like header and footer. ffile, fstat := guessFile(p.FileDir+"_footer", true) if fstat != nil { fcontent, ferr := host.readFile(ffile) if ferr == nil { p.ContentFooter = template.HTML(fcontent) } } if p.Content != "" { title, _ := regexp.Compile(`<h[\d]>(.+)</h`) found := title.FindStringSubmatch(string(p.Content)) if len(found) > 0 { p.Title = found[1] } } p.CreateBreadCrumb() p.CreateMenu() p.CreateSideMenu() err = host.Templates["index.tpl"].Execute(w, p) if err == nil { status = http.StatusOK } else { http.Error(w, err.Error(), http.StatusInternalServerError) status = http.StatusInternalServerError } } } if status == http.StatusNotFound { http.Error(w, "Not found", http.StatusNotFound) } fmt.Println(strings.Join([]string{ chunk(req.RemoteAddr), chunk(""), chunk(""), chunk("[" + time.Now().Format("02/Jan/2006:15:04:05 -0700") + "]"), chunk("\"" + fmt.Sprintf("%s %s %s", req.Method, req.RequestURI, req.Proto) + "\""), chunk(fmt.Sprintf("%d", status)), chunk(fmt.Sprintf("%d", size)), }, " "), ) }
func (self *runCommand) Execute() error { // Default settings file. if *flagSettings == "" { *flagSettings = DEFAULT_SETTINGS_FILE } stat, err := os.Stat(*flagSettings) if err != nil { return fmt.Errorf("Error while opening %s: %s", *flagSettings, err.Error()) } if stat != nil { if stat.IsDir() == true { return fmt.Errorf("Could not open %s: it's a directory!", *flagSettings) } else { settings, err = loadSettings(*flagSettings) if err != nil { return fmt.Errorf("Error while reading settings file %s: %s", *flagSettings, err.Error()) } err = settingsWatcher() if err == nil { watch.Watch(*flagSettings) } serverType := to.String(settings.Get("server", "type")) domain := DEFAULT_SERVER_DOMAIN address := to.String(settings.Get("server", "socket")) if address == "" { domain = DEFAULT_SERVER_PROTOCOL address = fmt.Sprintf("%s:%d", to.String(settings.Get("server", "bind")), to.Int64(settings.Get("server", "port"))) } listener, err := net.Listen(domain, address) if err != nil { return err } defer listener.Close() switch serverType { case "fastcgi": if err == nil { log.Printf("Starting FastCGI server. Listening at %s.", address) fcgi.Serve(listener, &server{}) } else { return fmt.Errorf("Failed to start FastCGI server: %s", err.Error()) } case "standalone": if err == nil { log.Printf("Starting HTTP server. Listening at %s.", address) http.Serve(listener, &server{}) } else { return fmt.Errorf("Failed to start HTTP server: %s", err.Error()) } default: return fmt.Errorf("Unknown server type: %s", serverType) } } } else { return fmt.Errorf("Could not load settings file: %s.", *flagSettings) } return nil }
/* Renders a LaTeX string, returns a PNG image path. */ func (self *Renderer) Render(latex string) (string, error) { var err error name := checksum.String(latex, crypto.SHA1) // Relative output directory. relPath := name[0:4] + PS + name[4:8] + PS + name[8:12] + PS + name[12:16] + PS + name[16:] + ".png" // Setting output directory. pngPath := OutputDirectory + PS + relPath err = os.MkdirAll(path.Dir(pngPath), 0755) if err != nil { return "", err } // Does the output file already exists? if self.UseCache == true { _, err = os.Stat(pngPath) if err == nil { return relPath, nil } } // Setting working directory. workdir := WorkingDirectory + PS + name err = os.MkdirAll(workdir, 0755) if err != nil { return "", err } // Will clean the directory at the end. defer os.RemoveAll(workdir) // Writing LaTeX to a file. texFile, err := os.Create(workdir + PS + "output.tex") if err != nil { return "", err } defer texFile.Close() _, err = io.WriteString(texFile, latex) if err != nil { return "", err } // Temp files. dviPath := workdir + PS + "output.dvi" epsPath := workdir + PS + "output.eps" // LaTeX toolchain batch := []*exec.Cmd{ exec.Command( "latex", "-no-shell-escape", "-interaction=batchmode", fmt.Sprintf("-output-directory=%s", workdir), texFile.Name(), ), exec.Command( "dvips", "-G", "-R2", "-E", dviPath, "-o", epsPath, ), exec.Command( "convert", "+adjoin", "-density", to.String(self.Density), "-antialias", epsPath, pngPath, ), } // Executing toolchain. os.Setenv("openout_any", "p") for _, cmd := range batch { err = cmd.Run() if err != nil { // Trying to catch error logPath := workdir + PS + "output.log" logFile, err := os.Open(logPath) if err == nil { buf := bytes.NewBuffer(nil) buf.ReadFrom(logFile) logFile.Close() if buf.Len() > 0 { return "", errors.New(string(buf.Bytes())) } } return "", err } } // Had success? stat, err := os.Stat(pngPath) if err != nil || stat == nil { return "", errors.New("Failed to create PNG file.") } return relPath, err }
func (self *Table) Query(terms ...interface{}) (db.Result, error) { var err error queryChunks := sqlutil.NewQueryChunks() // Analyzing given terms. for _, term := range terms { switch v := term.(type) { case db.Limit: if queryChunks.Limit == "" { queryChunks.Limit = fmt.Sprintf("LIMIT %d", v) } else { return nil, db.ErrQueryLimitParam } case db.Sort: if queryChunks.Sort == "" { sortChunks := make([]string, len(v)) i := 0 for column, sort := range v { sort = strings.ToUpper(to.String(sort)) if sort == "-1" { sort = "DESC" } if sort == "1" { sort = "ASC" } sortChunks[i] = fmt.Sprintf("%s %s", column, sort) i++ } queryChunks.Sort = fmt.Sprintf("ORDER BY %s", strings.Join(sortChunks, ", ")) } else { return nil, db.ErrQuerySortParam } case db.Offset: if queryChunks.Offset == "" { queryChunks.Offset = fmt.Sprintf("OFFSET %d", v) } else { return nil, db.ErrQueryOffsetParam } case db.Fields: queryChunks.Fields = append(queryChunks.Fields, v...) case db.Relate: for name, terms := range v { col, err := self.RelationCollection(name, terms) if err != nil { return nil, err } queryChunks.Relations = append(queryChunks.Relations, db.Relation{All: false, Name: name, Collection: col, On: terms}) } case db.RelateAll: for name, terms := range v { col, err := self.RelationCollection(name, terms) if err != nil { return nil, err } queryChunks.Relations = append(queryChunks.Relations, db.Relation{All: true, Name: name, Collection: col, On: terms}) } } } // No specific fields given. if len(queryChunks.Fields) == 0 { queryChunks.Fields = []string{"*"} } // Compiling conditions queryChunks.Conditions, queryChunks.Arguments = self.compileConditions(terms) if queryChunks.Conditions == "" { queryChunks.Conditions = "1 = 1" } // Actually executing query. rows, err := self.source.doQuery( // Mandatory fmt.Sprintf(`SELECT %s FROM "%s"`, strings.Join(queryChunks.Fields, ", "), self.Name()), fmt.Sprintf("WHERE %s", queryChunks.Conditions), queryChunks.Arguments, // Optional queryChunks.Sort, queryChunks.Limit, queryChunks.Offset, ) if err != nil { return nil, err } result := &Result{ sqlutil.Result{ Rows: rows, Table: &self.T, Relations: queryChunks.Relations, }, } return result, nil }