Json issue in getting date in golang dropbox library - go

I'm writing a little program using the dropbox api to learn go. I'm using the client library here: https://github.com/stacktic/dropbox.
I'm able to upload and download a file so I know my api keys and what not are working correctly. Using the Metadata method I can get the metadata for a file. However, when I try to use the UnmarshalJSON method to get a human readable date from the ClientMtime item in the entry struct, I get "unexpected end of JSON input". Any ideas on what's the issue?
The code I'm using is as follows:
func main() {
db := dropbox.NewDropbox()
db.SetAppInfo("Blah", "blah")
db.SetAccessToken("Token")
list,err := db.Metadata("/app_folder/test.jpg", true, false, "", "", 1)
if err != nil {
log.Fatal(err)
}
var date []byte
err = list.ClientMtime.UnmarshalJSON(date)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%v", date)
}
Thanks!

You want:
date, err := list.ClientMtime.MarshalJSON()
UnmarshalJson goes the other way; []byte -> DBTime
That's why it's an end of input error, the []byte is empty.
Optionally, ClientMTime is a time. Time which has String() and Format() methods.
You can access all the time formatting features by converting it.
See: https://github.com/stacktic/dropbox/blob/master/dropbox.go#L158

Related

How to get response after http request

I'm studying Go and am a real newbie in this field.
I am facing a problem when I try to copy some value.
What I am doing is:
I want to get some response in [response] using httpRequest.
httpClient := &http.Client{}
response, err := httpClient.Do(req)
if err != nil {
panic(err)
}
After that, I want to save the stored value in response at 'origin.txt'
origin_ ,_:= ioutil.ReadAll(response.Body)
f_, err := os.Create("origin.txt")
f_.Write(origin_);
And I want to get a specific value by using goquery package.
doc, err := goquery.NewDocumentFromReader(response.Body)
if err != nil {
log.Fatal(err)
}
doc.Find(".className").Each(func(i int, s *goquery.Selection) {
w.WriteString("============" + strconv.Itoa(i) + "============")
s.Find("tr").Each(func(i int, s_ *goquery.Selection) {
fmt.Println(s_.Text())
w.WriteString(s_.Text())
})
}
)
But in this case, I can get a value exactly what I want from 2) but cannot get anything from 3).
At first, I think the problem is, the response object at 3) is affected by 2) action. Because it is a reference object.
So I tried to copy it to another object and then do it again.
origin := *response
but, I got the same result as first.
What should I do?
How can I assign a reference value to another one by its value?
Should I request it twice for each attempt?
I actually don't see where you use shared resources between 2 and 3.
However that being said origin := *response won't buy you much. The data (response.Body) is a io.ReadCloser. The ioutil.ReadAll() will consume and store all the data that the stream has. You only get to do this once.
However you have the data stored in origin. If you need another io.Reader for that data (say for case 3), then you can make that byte slice look like an io.Reader again: bytes.NewReader(origin).

How do I write a gota dataframe to a csv?

I have found many many code examples of writing to a CSV by passing in a [][]string. (like the following):
package main
import (
"os"
"log"
"encoding/csv"
)
var data = [][]string{
{"Row 1", "30"},
{"Row 2", "60"},
{"Row 3", "90"}}
func main() {
file, err := os.Create("tutorials_technology.csv")
if err != nil {
log.Fatal(err)
}
defer file.Close()
w := csv.NewWriter(file)
for _, value := range data {
if err := w.Write(value); err != nil {
log.Fatalln("Error writing record to csv: ", err)
}
}
w.Flush()
}
However, I haven't found any code examples that show how to use the gota dataframe.WriteCSV() function to write to a CSV. In the gota dataframe documentation, there isn't an example for writing to a csv, but there is an example for reading from a csv.
The dataframe function WriteCSV() requires an input of the io.Writer{} interface. I wasn't sure how to satsify that.
The following didn't work
writer := csv.NewWriter(f)
df.WriteCSV(writer) // TODO This writer needs to be a []byte writer
I've been working on this for quite a while. Does anyone have any clues?
I have looked into turning my gota dataframe into a [][]string type, but that's a little inconvenient because I put my data into a gota dataframe with the package's LoadStructs() function and I had read in some CSV in a semi-custom way before putting them into structs.
So I could write a function to turn my structs into a [][]string format, but I feel like that is pretty tedious and I'm sure there has got to be a better way. In fact, I'm sure there is because the dataframe type has the WriteCSV() method but I just haven't figured out how to use it.
Here are my structs
type CsvLine struct {
Index int
Date string
Symbol string
Open float64
High float64
Low float64
Close float64
// Volume float64
// Market_Cap float64
}
type File struct {
Rows []CsvLine
}
Disclaimer: I am a little bit of a golang newbie. I've only been using Go for a couple months, and this is the first time I've tried to write to a file. I haven't interacted much with the io.Writer interface, but I hear that it's very useful.
And yes, I frequently look at the Golang.org blog and I've read "Effective Go" and I keep referencing it.
So it turns out I misunderstood the io.Writer interface and I didn't understand what the os.Create() function returns.
It turns out the code is even simpler and easier than I thought it would be.
Here is the working code example:
df := dataframe.LoadStructs(file.Rows)
f, err := os.Create(outFileName)
if err != nil {
log.Fatal(err)
}
df.WriteCSV(f)

Golang un-gzip from bytes.Reader

I have a file struct that holds a body which is just a *bytes.Reader I have two methods on the struct Zip() error and UnZip() error. When I call Zip it should zip the file storing the zipped data in body and I should be able to call UnZip on the same file and store the unzipped data in the body.
The minimal example I have is below in the playground. https://play.golang.org/p/WmZtqtvnyN
I'm able to zip the file just fine and looks like it's doing what it's supposed to do; however, when I try and unzip the file I get unexpected EOF
I've been going at this for hours now. Any help is greatly appreciated.
I believe you should close gzip writer before geting bytes from the underlying buffer.
func (f *File) Zip() error {
buff := bytes.NewBuffer(nil)
writer := gzip.NewWriter(buff)
defer writer.Close()
_, err := f.Body.WriteTo(writer)
if err != nil {
return err
}
writer.Close() // I have added this line
f.Body = bytes.NewReader(buff.Bytes())
f.Name = fmt.Sprintf("%s.gz", f.Name)
return nil
}
As per the documentation for gzip.NewReader, If r does not also implement io.ByteReader, the decompressor may read more data than necessary from r.
For bytes.Reader, A Reader implements the io.Reader, io.ReaderAt, io.WriterTo, io.Seeker, io.ByteScanner, and io.RuneScanner interfaces by reading from a byte slice.
The problem maybe lies in the fact that bytes.Reader does not implement io.ByteReader.

Passing a map as a value to insert into Cassandra

I'm trying to insert a map value into my Cassandra database. I'm using Go to write my client. Currently its throwing the error "can not marshal string into map(varchar, varchar)". I understand what the error is, but I can't resolve it. Here is the code that I've written.
if err := session.Query("INSERT INTO emergency_records
(mapColumn)
VALUES (?)",
"{'key' : 'value'}").Exec();
err != nil {
log.Fatal(err)
}
What I don't get is that I've written one query as a whole unbroken string and it works fine without throwing this error. Yet breaking it down with the question mark it throws the error. I know this is something simple that I'm just overlooking and couldn't find in the documentation, but any help would be great thanks.
I haven't used Go casandra client before but I guess passing map as a map instead of string should work:
mapValue := map[string]string{"key": "value"}
if err := session.Query("INSERT INTO emergency_records (mapColumn) VALUES (?)", mapValue).Exec(); err != nil {
log.Fatal(err)
}

Working in the console via exec.Command

Please help. I have to pass the console commando with a certain number of parameters. There are many.
That is, ideally, should be as follows:
test.go --distr
For example:
test.go --distr mc curl cron
i create function
func chroot_create() {
cmd := exec.Command("urpmi",
"--urpmi-root",
*fldir,
"--no-verify-rpm",
"--nolock",
"--auto",
"--ignoresize",
"--no-suggests",
"basesystem-minimal",
"rpm-build",
"sudo",
"urpmi",
"curl")
if err := cmd.Run(); err != nil {
log.Println(err)
}
}
And catch parameter distr through flag.Parse ()
How do I get rid of
"rpm-build",
"sudo",
"urpmi",
"curl")
That would not be tied to count packets. Please forgive me for stupidity, I'm just starting to learn golang. Especially when there was a problem.
Full code http://pastebin.com/yeuKy8Cc
You are looking for the ... operator.
func lsElements(elems ...string) {
cmd := exec.Command("ls", append([]string{"-l", "-h", "/root"}, elems...)...)
if err := cmd.Run(); err != nil {
log.Println(err)
}
}
You receive as function parameter ...string which is in really a []string, except that when you call the function, you pass the strings separately.
In order to use it, (and it works with any slices), you can "transform" your slice into list of element with ... suffix.
In the case of exec, you could use elem... directly if you had only this. However, has you have fixed parameters as well, you need to build your slice with append and extend it back with ...
Example: http://play.golang.org/p/180roQGL4a

Resources