Skip to content

Commit 86c7dc8

Browse files
author
Fatpandac
committed
🎉 Init
0 parents  commit 86c7dc8

File tree

3 files changed

+358
-0
lines changed

3 files changed

+358
-0
lines changed

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# 🧰 Upgist
2+
3+
> It's a gist-cli tool.
4+
5+
<center><image src="https://link.jscdn.cn/1drv/aHR0cHM6Ly8xZHJ2Lm1zL3UvcyFBdDZScWFPaURhNk5rUlRUb3hucG5nSkdJOUkzP2U9bVV0YlJo.gif"/></center>
6+
7+
## ⚡️ Usage
8+
9+
```
10+
Usage: upgist.exe [OPTIONS] COMMAND [ARGS]...
11+
12+
Upgist is a gist cli tool.
13+
14+
Options:
15+
-v, --version
16+
-h, --help Show this message and exit.
17+
18+
Commands:
19+
config Config upgist
20+
create Create a gist
21+
delete Delete a gist
22+
get Get a gist and save to the current directory
23+
list Show all your gist
24+
modify Modify a gist
25+
view Just view a gist is not saved
26+
```
27+
28+
## ❓ QA
29+
30+
- How to get **YOUR_TOKEN**?
31+
- [click here](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token#creating-a-token)
32+
33+
## 🤝 Contribute
34+
35+
PR, Forks and any Issues are welcome!

requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
requests
2+
click
3+
rich

upgist.py

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
import os,sys
2+
import json
3+
import click
4+
import requests
5+
from rich import box
6+
from rich.table import Table
7+
from rich.syntax import Syntax
8+
from rich.console import Console
9+
10+
console = Console()
11+
12+
gistAPI = "https://api.github.com/gists"
13+
configFolderPath = os.path.expanduser('~') + os.sep +".config" + os.sep + "upgist"
14+
configFileName = "config.txt"
15+
configFilePath = configFolderPath + os.sep + configFileName
16+
17+
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
18+
19+
class GistFile():
20+
21+
def __init__(self, description, public, fileName, content, fileID):
22+
self.fileID = fileID
23+
self.postFile = {
24+
"description" : description,
25+
"public" : public,
26+
"files" : {
27+
fileName : {
28+
"content" : content if content != None else self.__GetContent(fileName),
29+
}
30+
}
31+
}
32+
33+
def __GetContent(self,fileName):
34+
file = open(fileName,"r")
35+
content = file.read()
36+
file.close()
37+
return content
38+
39+
class Gist:
40+
41+
def __init__(self):
42+
self.headers = {
43+
"Authorization" : "token " + self.__GetToken()
44+
}
45+
46+
def GetGistRaw(self, gistID):
47+
fileList = []
48+
result = requests.get(url=gistAPI + "/{gistID}".format(gistID=gistID),headers=self.headers)
49+
if self.__isError(result.status_code):
50+
console.print("[bold red][ERROR][/bold red] {errMsg}".format(errMsg=result.json()['message']))
51+
return
52+
gistInfo = result.json()
53+
for file in gistInfo['files']:
54+
gistFile = open(file,"w+")
55+
gistFile.write(gistInfo['files'][file]['content'])
56+
gistFile.close()
57+
58+
def ViewGist(self, gistID):
59+
fileList = []
60+
result = requests.get(url=gistAPI + "/{gistID}".format(gistID=gistID),headers=self.headers)
61+
if self.__isError(result.status_code):
62+
console.print("[bold red][ERROR][/bold red] {errMsg}".format(errMsg=result.json()['message']))
63+
return
64+
gistInfo = result.json()
65+
table = Table(box=box.ROUNDED,show_lines=True)
66+
table.add_column(":open_file_folder:files",style="cyan")
67+
table.add_column(":memo:content",style="purple")
68+
for file in gistInfo['files']:
69+
table.add_row(gistInfo['files'][file]['filename'],Syntax(gistInfo['files'][file]['content'], gistInfo['files'][file]['language'], theme="vim", line_numbers=True))
70+
return table
71+
72+
def List(self,isShowID):
73+
result = requests.get(url=gistAPI,headers=self.headers)
74+
if self.__isError(result.status_code):
75+
console.print("[bold red][ERROR][/bold red] {errMsg}".format(errMsg=result.json()['message']))
76+
return
77+
if not isShowID:
78+
for gistInfo in result.json():
79+
table = self.ViewGist(gistInfo['id'])
80+
console.print(":link:[bold blue][link={url}]Gist ID[/link][/bold blue]: {gistID}".format(gistID=gistInfo.get('id'),url=gistInfo.get('html_url')))
81+
console.print(table)
82+
else:
83+
table = Table(box=box.ROUNDED,show_lines=True)
84+
table.add_column(":id:ID",style="blue")
85+
table.add_column(":open_file_folder:files",style="cyan")
86+
for gistInfo in result.json():
87+
fileNameList = []
88+
for file in gistInfo['files']:
89+
fileNameList.append(gistInfo['files'][file]['filename'])
90+
table.add_row("[link={url}]{gistID}[/link]".format(gistID=gistInfo.get('id'),url=gistInfo.get('html_url')),"\n".join(fileNameList))
91+
console.print(table)
92+
93+
94+
def Creat(self, file):
95+
result = requests.post(url=gistAPI,data=json.dumps(file.postFile),headers=self.headers)
96+
if self.__isError(result.status_code):
97+
console.print("[bold red][ERROR][/bold red] {errMsg}".format(errMsg=result.json()['message']))
98+
return
99+
console.print(":tada:[bold green]Successfully created[/bold green]: {url}".format(url=result.json()['html_url']))
100+
101+
def Modify(self, file):
102+
result = requests.post(url=gistAPI + "/{id}".format(id=file.fileID), data=json.dumps(file.postFile), headers=self.headers)
103+
if self.__isError(result.status_code):
104+
console.print("[bold red][ERROR][/bold red] {errMsg}".format(errMsg=result.json()['message']))
105+
return
106+
console.print(":tada:[bold green]Successfully modify[/bold green] : {url}".format(url=result.json()['html_url']))
107+
108+
def Delete(self, gistID):
109+
result = requests.delete(url=gistAPI + "/{gistID}".format(gistID=gistID),headers=self.headers)
110+
if self.__isError(result.status_code):
111+
console.print("[bold red][ERROR][/bold red] {errMsg}".format(errMsg=result.json()['message']))
112+
return
113+
114+
def __isError(self, code):
115+
successCode = [200,201,204]
116+
return code not in successCode
117+
118+
def __GetToken(self):
119+
file = os.path.exists(configFilePath)
120+
if not file:
121+
console.print("Pleace use the following command to set your token:\ngist config -tk YOUR_TOKEN")
122+
sys.exit(1)
123+
else:
124+
configFile = open(configFilePath,"r")
125+
token = configFile.read()
126+
return token
127+
128+
def SaveToken(token):
129+
file = os.path.exists(configFolderPath)
130+
if not file:
131+
os.makedirs(configFolderPath)
132+
with open(configFilePath,"w") as configFile:
133+
configFile.write(token)
134+
configFile.close()
135+
136+
def PrintVersion(ctx,param,value):
137+
if not value or ctx.resilient_parsing:
138+
return
139+
print('Version 0.0.1')
140+
ctx.exit()
141+
142+
def Main_Options(f):
143+
version = click.option('--version',
144+
'-v',
145+
is_flag=True,
146+
callback=PrintVersion,
147+
expose_value=False,
148+
is_eager=True)
149+
return version(f)
150+
151+
def Config_Options(f):
152+
token = click.option('--token',
153+
'-tk',
154+
'token',
155+
nargs=1,
156+
required=True,
157+
multiple=False,
158+
help="Set your token to client gist")
159+
return token(f)
160+
161+
def ViewGist_Options(f):
162+
gistid = click.option('--gistid',
163+
'-id',
164+
'gistID',
165+
nargs=1,
166+
required=True,
167+
multiple=False,
168+
help="View a gist by gist ID")
169+
return gistid(f)
170+
171+
def GetGistRaw_Options(f):
172+
gistid = click.option('--gistid',
173+
'-id',
174+
'gistID',
175+
nargs=1,
176+
required=True,
177+
multiple=False,
178+
help="Get a gist and save by gist ID")
179+
return gistid(f)
180+
181+
def DeleteGist_Options(f):
182+
gistid = click.option('--gistid',
183+
'-id',
184+
'gistID',
185+
nargs=1,
186+
required=True,
187+
multiple=False,
188+
help="Delete a gist by gist ID")
189+
return gistid(f)
190+
191+
def CreatGist_Options(f):
192+
file = click.option('--file',
193+
'-f',
194+
'fileName',
195+
nargs=1,
196+
required=True,
197+
multiple=False,
198+
help="File name of gist")
199+
public = click.option('--public',
200+
'-p','public',
201+
nargs=1,
202+
default="true",
203+
multiple=False,
204+
type=click.Choice(["true", "false"]),
205+
show_default=True,
206+
help="Public of gist")
207+
content = click.option('--content',
208+
'-c',
209+
'content',
210+
nargs=1,
211+
multiple=False,
212+
help="Content of gist")
213+
description = click.option('--description',
214+
'-d',
215+
'description',
216+
nargs=1,
217+
default="From upgist by Fatpandac",
218+
show_default=True,
219+
multiple=False,
220+
help="Description of gist")
221+
return file(public(content(description(f))))
222+
223+
def ModifyGist_Options(f):
224+
file = click.option('--file',
225+
'-f',
226+
'fileName',
227+
nargs=1,
228+
required=True,
229+
multiple=False,
230+
help="Modify filename of gist")
231+
public = click.option('--public',
232+
'-p','public',
233+
nargs=1,
234+
default="true",
235+
multiple=False,
236+
type=click.Choice(["true", "false"]),
237+
show_default=True,
238+
help="Modify public of gist")
239+
content = click.option('--content',
240+
'-c',
241+
'content',
242+
nargs=1,
243+
multiple=False,
244+
help="Modify content of gist")
245+
description = click.option('--description',
246+
'-d',
247+
'description',
248+
nargs=1,
249+
default="From upgist by Fatpandac",
250+
show_default=True,
251+
multiple=False,
252+
help="Modify description of gist")
253+
gistid = click.option('--gistid',
254+
'-id',
255+
'gistID',
256+
nargs=1,
257+
required=True,
258+
multiple=False,
259+
help="Modify a gist by gist ID")
260+
return file(public(content(description(gistid(f)))))
261+
262+
def ListGist_Options(f):
263+
isShowID = click.option('--showid/--no-showid',
264+
'-id/-nid',
265+
'isShowID',
266+
default=False,
267+
show_default=True,
268+
help="Just show gist id and filename")
269+
return isShowID(f)
270+
271+
@click.group(context_settings=CONTEXT_SETTINGS)
272+
@Main_Options
273+
def main():
274+
"""Upgist is a gist cli tool."""
275+
276+
@main.command(name="config",help="Config upgist")
277+
@Config_Options
278+
def Config(token):
279+
SaveToken(token)
280+
281+
@main.command(name="get",help="Get a gist and save to the current directory")
282+
@GetGistRaw_Options
283+
def GetGistRaw(gistID):
284+
gist = Gist()
285+
gist.GetGistRaw(gistID)
286+
287+
@main.command(name="view",help="Just view a gist is not saved")
288+
@ViewGist_Options
289+
def ViewGist(gistID):
290+
gist = Gist()
291+
console.print(gist.ViewGist(gistID))
292+
293+
@main.command(name="modify",help="Modify a gist")
294+
@ModifyGist_Options
295+
def ModifyGist(gistID,fileName,content,description,public):
296+
gist = Gist()
297+
file = GistFile(description=description, public=public, fileName=fileName, content=content,fileID=gistID)
298+
gist.Modify(file)
299+
300+
@main.command(name="delete",help="Delete a gist")
301+
@DeleteGist_Options
302+
def DeleteGist(gistID):
303+
gist = Gist()
304+
gist.Delete(gistID)
305+
306+
@main.command(name="list",help="Show all your gist")
307+
@ListGist_Options
308+
def GistList(isShowID):
309+
gist = Gist()
310+
gist.List(isShowID)
311+
312+
@main.command(name="create",help="Create a gist")
313+
@CreatGist_Options
314+
def CreatGist(fileName,content,description,public):
315+
gist = Gist()
316+
file = GistFile(description=description, public=public, fileName=fileName, content=content,fileID=None)
317+
gist.Creat(file)
318+
319+
if __name__ == "__main__":
320+
main()

0 commit comments

Comments
 (0)