func fetchAPI(serverAddr, query string) (string, os.Error) { conn, err := net.Dial("tcp", "", serverAddr) if err != nil { return "", err } defer conn.Close() cc := http.NewClientConn(conn, nil) defer cc.Close() url, err := http.ParseURL("http://" + serverAddr + "/?q=" + http.URLEscape(query)) if err != nil { return "", err } req := &http.Request{ Method: "GET", URL: url, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, //Close: true, XXX possible HTTP bug. Does not work when this is uncommented. Host: serverAddr, UserAgent: "GoNeedle-ClientConnect", } //d, err := http.DumpRequest(req, true) //fmt.Printf("REQ:\n%s\n", string(d)) err = cc.Write(req) if err != nil { return "", err } resp, err := cc.Read() if resp == nil { return "", err } if resp.Body == nil { return "", nil } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } return string(body), nil }
// Parse() returns the Post{} object of the post for urlPath func (pm *PostMan) Parse(urlPath string) (*Post, os.Error) { // If urlPath has a trailing '/', remove it if len(urlPath) > 0 && urlPath[len(urlPath)-1] == '/' { urlPath = urlPath[:len(urlPath)-1] } // Obtain the post filename postfileAbs, postfileRel := pm.fs.GetDiskPath(urlPath) if postfileAbs == "" { return nil, ErrNoPost } // Read GIT info ct, ut, err := GITGetCreateUpdateTime(pm.gitCmd, pm.fs.Dir(), postfileRel) if err != nil { log.Printf("Problem: Reading GIT times from '%s' (%s)\n", postfileRel, err) return nil, err } // Read post contents rawbuf, err := ioutil.ReadFile(postfileAbs) if err != nil { return nil, err } bufr := bufio.NewReader(bytes.NewBuffer(rawbuf)) // Read header mimer := textproto.NewReader(bufr) h, err := mimer.ReadMIMEHeader() if err != nil { log.Printf("Problem: Reading MIME header of '%s': (%s)\n", postfileRel, err) return nil, err } // Parse tags tags := []string{} for _, l := range h["Tags"] { ll := strings.Split(l, ",", -1) for _, t := range ll { tt := strings.TrimSpace(t) if tt == "" { continue } tags = append(tags, tt) } } // Parse options var hidden bool for _, l := range h["Options"] { ll := strings.Split(l, ",", -1) for _, t := range ll { switch strings.ToLower(strings.TrimSpace(t)) { case "hidden": hidden = true } } } // Read title and body var title string for { title0, _, err := bufr.ReadLine() if err != nil { log.Printf("Problem: Reading title of '%s': (%s)\n", postfileRel, err) return nil, err } title1 := make([]byte, len(title0)) copy(title1, title0) title = strings.TrimSpace(string(title1)) if title != "" { break } } // Read body of post and exerpt exerpt := "" body := []byte{} for { line, _, err := bufr.ReadLine() if err != nil { if err == os.EOF { break } return nil, err } l := strings.TrimSpace(string(line)) if l == "<!--more-->" { exerpt = string(body) } body = append(body, line...) body = append(body, '\n') } // Prepare post object post := &Post{ ID: h.Get("Id"), Title: title, URL: urlPath, URLEscaped: http.URLEscape(urlPath), Body: string(body), Exerpt: exerpt, Tags: tags, Created: ct.Format(PostTimeLayout), CreatedTime: ct, UpdatedTime: ut, Hidden: hidden, } if ut != nil { post.Updated = ut.Format(PostTimeLayout) } return post, nil }