2

I'm writing a script which tries to send a Gist through Github's API. All the requests need to be in the following JSON format:

{
    "description": "the description for this gist",
    "public": true,
    "files": {
        "file1.txt": {
           "content": "String file contents"
        }
    }
}

I'm confused by how the formatting of the "content" field should be done. I am trying to send in the "content" field a text file of code such as

if(n <= 3)
  n++;
else
  n--;

If I append all the lines with newlines (i.e. "n++"; -> "n++;\n") and escape other characters like backslashes and quotes, then I can send the file as a string where the JSON looks like this:

{
    "description": "the description for this gist",
    "public": true,
    "files": {
        "file1.txt": {
           "content": "if(n<=3)\nn++;\nelse\nn--;"
        }
    }
}

, but all the indentation is lost and the Gist ends up looking like this:

if(n <= 3)
n++;
else
n--;

If I send the file as a base64 encoded string, then I get a JSON parsing error. I'm writing the JSON to a text file and using curl to send the request as below

curl --user user -X POST -H 'Content-Type application/json' -d @test.txt https://api.github.com/gists

So what options do I have to send the contents of the text file with indentation preserved? I am currently writing the script in bash, but if there is a language with parsing features designed for this case, I'd be open to using that instead.

Is there any way to send the file, preserved in its indented state, as the string literal of this JSON obeject? Am I misunderstanding the API?

1
  • Trying to achieve the same. I think this should be done using base64 encoding of the file but my tests fail. { "description": "the description for this gist", "public": true, "files": { "file1.txt": { "content": "U3RyaW5nIGZpbGUgY29udGVudHMK", "encoding": "base64" } } } Commented Jun 19, 2015 at 4:23

2 Answers 2

2

Look at your string:

"content": "if(n<=3)\nn++;\nelse\nn--;"

If there was indenting, you'd see it in the string:

"content": "if(n<=3)\n  n++;\nelse\n  n--;"

Your bash script strips the indenting due to a bug in the code you wrote. This is usually due to failing to quote, or from using an incorrect while read loop. Your script is not included so I can't say where.

You can avoid all this and several more bugs by using jq instead of trying to escape your own data:

$ cat file
if(n <= 3)
  n++;
else
  n--;

$ jq -R -s . file
"if(n <= 3)\n  n++;\nelse\n  n--;\n"
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks so much! I actually had not considered while read loop to concatenate all the lines together and save leading whitespace. I implemented that in bash and everything works perfectly :) jq was interesting to read about, but it was easier to bang out the while read loop than to install jq.
1

You can use sed to transform a file to a content string.

cat <<END
{
  "description":"filename",
  "public":false,
  "files": {
    "filename": {
    "content":"$(sed -e 's/\\/\\\\/g' -e 's/"/\\"/g'  -e 's/$/\\n/' <filename)"
    }
  }
}
END

See my gistpost script. Very basic and rough but it works

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.