Skip to content

Instantly share code, notes, and snippets.

@lshifr
Created December 12, 2012 11:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lshifr/4267071 to your computer and use it in GitHub Desktop.
Save lshifr/4267071 to your computer and use it in GitHub Desktop.
A Mathematica client for Github gists

##GithubGistClient

GithubGistClient is a Mathematica client for Githib gists, which uses the Github gist API to manipulate gists from within Mathematica

(* Mathematica Package *)
BeginPackage["GithubGistClient`"]
(* Exported symbols added here with SymbolName::usage *)
(* TODO:
1. Make this OO
2. Get rid of curl
3. Refine the API
*)
$curl;
$userpswd;
getGist;
GistObject;
getBriefVersionInfo;
getVersionCommitDate;
getVersionURL;
getGistComments;
getGistCommentsURL;
getGistCreationTime;
getGistID;
getGistHtmlURL;
getGistURL;
getGistUpdateTime;
getGistFilesInfo;
getGistFileKeyName;
getGistFileNames;
getGistFileInfo;
getGistFileContent;
getGistFileName;
getGistFileRawURL;
getGistFileType;
makeFileEditInfo;
FileEditInfo;
makeFileDeleteInfo;
makeGistEditInfo;
editGist;
makeFileCreateInfo;
FileCreateInfo;
makeGistCreateInfo;
createGist;
deleteGist;
listUserGists;
Begin["`Private`"] (* Begin Private Context *)
Needs["ResourceLocator`"];
$curl := Throw[$Failed, "curl_path_not_set"];
$userpswd := Throw[$Failed, "user_and_pswd_not_set"];
$temporaryDirectory = ApplicationDataUserDirectory["GithubGistClient"];
ClearAll[fullName];
fullName[name_] := FileNameJoin[{$temporaryDirectory , name}];
stringify[s_String] := StringJoin["\"", s, "\""];
auth[] := " --user " <> $userpswd;
ClearAll[LetL];
SetAttributes[LetL, HoldAll];
SyntaxInformation[LetL] = {"ArgumentsPattern" -> {_, _},
"LocalVariables" -> {"Solve", {1, Infinity}}};
LetL /: Verbatim[SetDelayed][lhs_, rhs : HoldPattern[LetL[{__}, _]]] :=
Block[{With}, Attributes[With] = {HoldAll};
lhs := Evaluate[rhs]];
LetL[{}, expr_] := expr;
LetL[{head_}, expr_] := With[{head}, expr];
LetL[{head_, tail__}, expr_] :=
Block[{With}, Attributes[With] = {HoldAll};
With[{head}, Evaluate[LetL[{tail}, expr]]]];
Clear[makeTemporaryJSONFile];
makeTemporaryJSONFile[name_String, content_] :=
Export[name, content, "JSON"]
Clear[getGistScript];
getGistScript[gistID_String, tempfile_String, isAuth_: False] :=
stringify@StringJoin[
stringify@$curl,
" -k -v ",
If[isAuth, auth[], Sequence @@ {}],
" -X GET https://api.github.com/gists/",
gistID,
" -o ",
stringify@tempfile];
ClearAll[getGist];
getGist[gistID_String, isAuth_: False] :=
Module[{tempFile = fullName["result.txt"]},
If[FileExistsQ[tempFile], DeleteFile[tempFile]];
If[Run[getGistScript[gistID, tempFile, False]] != 0 || !FileExistsQ[tempFile],
Return[$Failed]
];
GistObject@Import[tempFile, "JSON"]]
ClearAll[GistObject];
GistObject[gist_][prop_] := OptionValue[gist, prop];
ClearAll[getBriefVersionInfo];
getBriefVersionInfo[gist_GistObject] :=
FilterRules[#, "committed_at" | "url" | "version" -> _] & /@
gist["history"]
ClearAll[getVersionCommitDate, getVersionURL]
getVersionCommitDate[versionData_List] :=
"committed_at" /. versionData;
getVersionURL[versionData_List] :=
"url" /. versionData;
ClearAll[getGistComments, getGistCommentsURL, getGistCreationTime,
getGistID, getGistHtmlURL, getGistURL, getGistUpdateTime];
getGistID[gist_GistObject] := gist["id"];
getGistHtmlURL[gist_GistObject] := gist["html_url"];
getGistURL[gist_GistObject] := gist["url"];
getGistUpdateTime[gist_GistObject] := DateList@gist["updated_at"];
getGistComments[gist_GistObject] := gist["comments"];
getGistCommentsURL[gist_GistObject] := gist["comments_url"];
getGistCreationTime[gist_GistObject] := gist["created_at"];
getGistDescription[gist_GistObject] := gist["description"];
ClearAll[getGistFilesInfo];
getGistFilesInfo[gist_GistObject] := gist["files"];
ClearAll[getGistFileKeyName];
getGistFileKeyName[name_ -> _] := name;
ClearAll[getGistFileNames];
getGistFileNames[gist_GistObject] :=
Map[getGistFileKeyName, getGistFilesInfo[gist]];
Clear[getGistFileInfo];
getGistFileInfo[name_, gist_GistObject] :=
getGistFileInfo[name, getGistFilesInfo[gist]];
getGistFileInfo[name_, filesInfo_] :=
name /. filesInfo;
ClearAll[getGistFileContent, getGistFileName, getGistFileRawURL,
getGistFileType];
getGistFileContent[name_, gist_GistObject] :=
"content" /. getGistFileInfo[name, gist];
getGistFileName[name_, gist_GistObject] :=
"filename" /. getGistFileInfo[name, gist];
getGistFileRawURL[name_, gist_GistObject] :=
"raw_url" /. getGistFileInfo[name, gist];
getGistFileType[name_, gist_GistObject] :=
"type" /. getGistFileInfo[name, gist];
ClearAll[makeFileEditInfo]
makeFileEditInfo[name_, Automatic, Automatic] := Sequence[]
makeFileEditInfo[name_String, newContent_, newName_: Automatic] :=
With[{
rules =
MapThread[
If[#1 === Automatic, Sequence @@ {}, #2 -> #1] &,
{{newContent, newName}, {"content", "filename"}}
]},
FileEditInfo[name -> rules]
];
Clear[makeFileDeleteInfo];
makeFileDeleteInfo[name_String] := FileEditInfo[name -> Null];
ClearAll[makeGistEditInfo];
makeGistEditInfo[fileEdits : {___FileEditInfo},
newDescription_: Automatic] :=
With[{
desc =
If[#1 === Automatic, Sequence @@ {}, #2 -> #1] &[newDescription,
"description"],
files = fileEdits /. FileEditInfo[info_] :> info
},
{
desc,
If[files =!= {}, "files" -> files, Sequence @@ {}]
}
];
makeGistEditInfo[fileEdits : {(_String -> _String) ...},
fileRenamings : {(_String -> _String) ...},
fileRemovals : {___String}, newDescription_: Automatic] :=
makeGistEditInfo[
Join[
Map[makeFileEditInfo[#, # /. fileEdits /. # -> Automatic, # /.
fileRenamings /. # -> Automatic] &,
Union[fileEdits[[All, 1]], fileRenamings[[All, 1]]]
],
Map[makeFileDeleteInfo, fileRemovals]
],
newDescription
];
makeGistEditInfo[___] := throwError[makeGistEditInfo];
Clear[editGistScript];
editGistScript[gistID_String, tempfile_String, jsonFile_String,
isAuth_: True] :=
stringify@StringJoin[
stringify@$curl,
" -k -v ",
If[isAuth, auth[], Sequence @@ {}],
" -X PATCH https://api.github.com/gists/",
gistID,
" --data ",
"@",
stringify@jsonFile,
" -o ",
stringify@tempfile];
ClearAll[editGist];
editGist[gistID_String, newContent_] :=
Module[{tempFile = fullName["temp.txt"],
jsonFile = fullName["gistedit.json"]},
If[FileExistsQ[#], DeleteFile[#]] & /@ {tempFile, jsonFile};
If[makeTemporaryJSONFile[jsonFile, newContent] === $Failed,
Return[$Failed]];
If[Run[editGistScript[gistID, tempFile, jsonFile]] != 0 || !FileExistsQ[tempFile],
Return[$Failed]
];
GistObject@Import[tempFile, "JSON"]]
ClearAll[makeFileCreateInfo]
makeFileCreateInfo[name_String, content_] :=
FileCreateInfo[name -> {"content" -> content}];
ClearAll[makeGistCreateInfo];
makeGistCreateInfo[files : {__FileCreateInfo},
description_: Automatic] :=
{
If[# === Automatic, Sequence @@ {}, "description" -> #] &[
description],
"public" -> True,
"files" -> (files /. FileCreateInfo[x_] :> x)
};
Clear[createGistScript];
createGistScript[tempfile_String, jsonFile_String, isAuth_: True] :=
stringify@StringJoin[
stringify@$curl,
" -k -v ",
If[isAuth, auth[], Sequence @@ {}],
" -X POST https://api.github.com/gists",
" --data ",
"@",
stringify@jsonFile,
" -o ",
stringify@tempfile];
ClearAll[createGist];
createGist[content_] :=
Module[{tempFile = fullName["temp.txt"],
jsonFile = fullName["gistcreate.json"]},
If[FileExistsQ[#], DeleteFile[#]] & /@ {tempFile, jsonFile};
If[makeTemporaryJSONFile[jsonFile, content] === $Failed,
Return[$Failed]];
If[Run[createGistScript[tempFile, jsonFile]] != 0 || !FileExistsQ[tempFile],
Return[$Failed]
];
GistObject@Import[tempFile, "JSON"]]
Clear[deleteGistScript];
deleteGistScript[gistID_String, tempfile_String, isAuth_: True] :=
stringify@StringJoin[
stringify@$curl,
" -k -v ",
If[isAuth, auth[], Sequence @@ {}],
" -X DELETE https://api.github.com/gists/",
gistID,
" 2> ",
stringify@tempfile];
ClearAll[deleteGist];
deleteGist[gistID_String] :=
Module[{tempFile = fullName["temp.txt"]},
If[FileExistsQ[tempFile], DeleteFile[tempFile]];
If[Run[deleteGistScript[gistID, tempFile, True]] != 0 || !FileExistsQ[tempFile],
Return[$Failed]
];
(*Import[tempFile,"Text"]*)
If[getGist[gistID] =!= GistObject[{"message" -> "Not Found"}],
Return[$Failed]
]];
ClearAll[listUserGistsScript];
listUserGistsScript[user_String, tempfile_String,
since : (_String | Automatic) : Automatic] :=
stringify@StringJoin[
stringify@$curl,
" -k -v ",
auth[],
" -X GET https://api.github.com/users/",
user,
"/gists",
" -o ",
stringify@tempfile];
ClearAll[listUserGists];
listUserGists[user_String,
since : (_String | Automatic) : Automatic] :=
Module[{tempFile = fullName["result.txt"]},
If[FileExistsQ[tempFile], DeleteFile[tempFile]];
If[Run[listUserGistsScript[user, tempFile, since]] != 0 || !FileExistsQ[tempFile],
Return[$Failed]
];
GistObject /@ Import[tempFile, "JSON"]]
End[] (* End Private Context *)
EndPackage[]
{
"author"->
{
"name" -> "lshifr",
"email" -> "lshifr@gmail.com",
"url" -> "http://www.mathprogramming-intro.org"
},
"name" -> "GithubGistClient",
"mathematica_version" -> "8.0+",
"description" -> "A Mathematica client for Github gists",
"url" -> "https://gist.github.com/4267071"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment