Skip to content

Commit 2a885a7

Browse files
authored
Merge pull request #96 from ControlCore-Project/dev
Merge dev with main, to incorporate contribute action
2 parents 1091829 + d0d6d05 commit 2a885a7

6 files changed

Lines changed: 241 additions & 1 deletion

File tree

contribute

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
3+
# Check if the first 3 arguments are provided
4+
if [ -z $1 ] || [ -z $2 ] || [ -z $3 ]; then
5+
echo "Error: The first 3 arguments are mandatory."
6+
echo "Usage: ./contribute <Study-Name> <Full-Path-To-Study> <Author-Name> <Branch-Name> <PR-title> <PR-Body>"
7+
exit 1
8+
fi
9+
10+
# Set the last 3 arguments to "#" if not provided
11+
arg4=$4
12+
arg5=$5
13+
arg6=$6
14+
if [ -z $4 ]; then
15+
arg4="#"
16+
fi
17+
if [ -z $5 ]; then
18+
arg5="#"
19+
fi
20+
if [ -z $6 ]; then
21+
arg6="#"
22+
fi
23+
python3 contribute.py "$1" "$2" "$3" "$arg4" "$arg5" "$arg6"

contribute.bat

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@echo off
2+
3+
REM Check if the first 3 arguments are provided
4+
if "%~1" == "" goto :missing_arg
5+
if "%~2" == "" goto :missing_arg
6+
if "%~3" == "" goto :missing_arg
7+
8+
REM Check and set default values for the last three arguments if not provided
9+
if "%~4"=="" (set arg4="#") else (set arg4=%~4)
10+
if "%~5"=="" (set arg5="#") else (set arg5=%~5)
11+
if "%~6"=="" (set arg6="#") else (set arg6=%~6)
12+
python contribute.py %1 %2 %3 "%arg4%" "%arg5%" "%arg6%"
13+
goto :eof
14+
15+
:missing_arg
16+
echo "Error: The first 3 arguments are mandatory."
17+
echo "Usage: ./contribute.bat <Study-Name> <Full-Path-To-Study> <Author-Name> <Branch-Name> <PR-title> <PR-Body>"
18+
19+
20+

contribute.py

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import github
2+
from github import Github
3+
import os,sys,platform,base64
4+
5+
# Intializing the Variables
6+
# Hashed token
7+
BOT_TOKEN = "Z2l0aHViX3BhdF8xMUFYS0pGVFkwODR5OEhoZlI5VEl1X0VZZnNaNjU0WGw4OU0ycXhJc0h3TXh3RkVIZGFRQ3gwa0daZFhKUUdYbUk2QzRTU1dDNkF4clUyQWRF"
8+
BOT_ACCOUNT = 'concore-bot' #bot account name
9+
REPO_NAME = 'concore-studies' #study repo name
10+
UPSTREAM_ACCOUNT = 'ControlCore-Project' #upstream account name
11+
STUDY_NAME = sys.argv[1]
12+
STUDY_NAME_PATH = sys.argv[2]
13+
AUTHOR_NAME = sys.argv[3]
14+
BRANCH_NAME = sys.argv[4]
15+
PR_TITLE = sys.argv[5]
16+
PR_BODY = sys.argv[6]
17+
18+
# Defining Functions
19+
def checkInputValidity():
20+
if AUTHOR_NAME=="" or STUDY_NAME=="" or STUDY_NAME=="":
21+
print("Please Provide necessary Inputs")
22+
exit(0)
23+
if not os.path.isdir(STUDY_NAME_PATH):
24+
print("Directory doesnot Exists.Invalid Path")
25+
exit(0)
26+
27+
28+
def getPRs(upstream_repo):
29+
try:
30+
return upstream_repo.get_pulls(head=f'{BOT_ACCOUNT}:{BRANCH_NAME}')
31+
except Exception as e:
32+
print("Not able to fetch Status of your example.Please try after some time.")
33+
exit(0)
34+
35+
def printPR(pr):
36+
print(f'Check your example here https://github.com/{UPSTREAM_ACCOUNT}/{REPO_NAME}/pulls/{pr.number}',end="")
37+
38+
def anyOpenPR(upstream_repo):
39+
pr = getPRs(upstream_repo)
40+
openPr=None
41+
for i in pr:
42+
if i.state=="open":
43+
openPr=i
44+
break
45+
return openPr
46+
47+
def commitAndUpdateRef(repo,tree_content,commit,branch):
48+
try:
49+
new_tree = repo.create_git_tree(tree=tree_content,base_tree=commit.commit.tree)
50+
new_commit = repo.create_git_commit("commit study",new_tree,[commit.commit])
51+
if len(repo.compare(base=commit.commit.sha,head=new_commit.sha).files) == 0:
52+
print("Your don't have any new changes.May be your example is already accepted.If this is not the case try with different fields.")
53+
exit(0)
54+
ref = repo.get_git_ref("heads/"+branch.name)
55+
ref.edit(new_commit.sha,True)
56+
except Exception as e:
57+
print("failed to Upload your example.Please try after some time.",end="")
58+
exit(0)
59+
60+
61+
def appendBlobInTree(repo,content,file_path,tree_content):
62+
blob = repo.create_git_blob(content,'utf-8')
63+
tree_content.append( github.InputGitTreeElement(path=file_path,mode="100644",type="blob",sha=blob.sha))
64+
65+
66+
def runWorkflow(repo,upstream_repo):
67+
openPR = anyOpenPR(upstream_repo)
68+
if openPR==None:
69+
workflow_runned = repo.get_workflow(id_or_name="pull_request.yml").create_dispatch(ref=BRANCH_NAME,inputs={'title':f"[BOT]: {PR_TITLE}",'body':PR_BODY,'upstreamRepo':UPSTREAM_ACCOUNT,'botRepo':BOT_ACCOUNT,'repo':REPO_NAME})
70+
if not workflow_runned:
71+
print("Some error occured.Please try after some time")
72+
exit(0)
73+
else:
74+
printPRStatus(upstream_repo)
75+
else:
76+
print("Successfully uploaded all files,your example is in waiting.Please wait for us to accept it.",end="")
77+
printPR(openPR)
78+
79+
def printPRStatus(upstream_repo):
80+
try:
81+
issues = upstream_repo.get_issues()
82+
pulls = upstream_repo.get_pulls(state='all')
83+
max_num = -1
84+
for i in issues:
85+
max_num = max(max_num,i.number)
86+
for i in pulls:
87+
max_num = max(max_num,i.number)
88+
print(f'Check your example here https://github.com/{UPSTREAM_ACCOUNT}/{REPO_NAME}/pulls/{max_num+1}',end="")
89+
except Exception as e:
90+
print("Your example successfully uploaded but unable to fetch status.Please try again")
91+
92+
93+
def isImageFile(filename):
94+
image_extensions = ['.jpeg', '.jpg', '.png','.gif']
95+
return any(filename.endswith(ext) for ext in image_extensions)
96+
97+
98+
# Decode Github Token
99+
def decode_token(encoded_token):
100+
decoded_bytes = base64.b64decode(encoded_token.encode('utf-8'))
101+
decoded_token = decoded_bytes.decode('utf-8')
102+
return decoded_token
103+
104+
105+
# check if directory path is Valid
106+
checkInputValidity()
107+
108+
109+
# Authenticating Github with Access token
110+
try:
111+
if BRANCH_NAME=="#":
112+
BRANCH_NAME=AUTHOR_NAME+"_"+STUDY_NAME
113+
if PR_TITLE=="#":
114+
PR_TITLE=f"Contributing Study {STUDY_NAME} by {AUTHOR_NAME}"
115+
if PR_BODY=="#":
116+
PR_BODY=f"Study Name: {STUDY_NAME} \n Author Name: {AUTHOR_NAME}"
117+
AUTHOR_NAME = AUTHOR_NAME.replace(" ","_")
118+
DIR_PATH = STUDY_NAME
119+
g = Github(decode_token(BOT_TOKEN))
120+
repo = g.get_user(BOT_ACCOUNT).get_repo(REPO_NAME)
121+
upstream_repo = g.get_repo(f'{UPSTREAM_ACCOUNT}/{REPO_NAME}') #controlcore-Project/concore-studies
122+
base_ref = upstream_repo.get_branch(repo.default_branch)
123+
branches = repo.get_branches()
124+
BRANCH_NAME = BRANCH_NAME.replace(" ","_")
125+
DIR_PATH = DIR_PATH.replace(" ","_")
126+
is_present = any(branch.name == BRANCH_NAME for branch in branches)
127+
except Exception as e:
128+
print("Some error occured.Authentication failed",end="")
129+
exit(0)
130+
131+
132+
try:
133+
# If creating PR First Time
134+
# Create New Branch for that exmaple
135+
if not is_present:
136+
repo.create_git_ref(f'refs/heads/{BRANCH_NAME}', base_ref.commit.sha)
137+
# Get current branch
138+
branch = repo.get_branch(branch=BRANCH_NAME)
139+
except Exception as e:
140+
print("Not able to create study for you.Please try again after some time",end="")
141+
exit(0)
142+
143+
144+
tree_content = []
145+
146+
try:
147+
for root, dirs, files in os.walk(STUDY_NAME_PATH):
148+
for filename in files:
149+
path = f"{root}/{filename}"
150+
if isImageFile(filename):
151+
with open(path, 'rb') as file:
152+
image = file.read()
153+
content = base64.b64encode(image).decode('utf-8')
154+
else:
155+
with open(path, 'r') as file:
156+
content = file.read()
157+
file_path = f'{DIR_PATH+path.removeprefix(STUDY_NAME_PATH)}'
158+
if(platform.uname()[0]=='Windows'): file_path=file_path.replace("\\","/")
159+
appendBlobInTree(repo,content,file_path,tree_content)
160+
commitAndUpdateRef(repo,tree_content,base_ref.commit,branch)
161+
runWorkflow(repo,upstream_repo)
162+
except Exception as e:
163+
print("Some error Occured.Please try again after some time.",end="")
164+
exit(0)

fri/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ Flask
22
gunicorn==20.1.0
33
FLASK_CORS
44
jupyterlab
5+
PyGithub

fri/server/main.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import xml.etree.ElementTree as ET
44
import os
55
import subprocess
6-
from subprocess import call
6+
from subprocess import call,check_output
77
from pathlib import Path
88
import json
99
import platform
@@ -294,6 +294,37 @@ def clear(dir):
294294
resp.status_code = 500
295295
return resp
296296

297+
@app.route('/contribute', methods=['POST'])
298+
def contribute():
299+
try:
300+
data = request.json
301+
PR_TITLE = data.get('title')
302+
PR_BODY = data.get('desc')
303+
AUTHOR_NAME = data.get('auth')
304+
STUDY_NAME = data.get('study')
305+
STUDY_NAME_PATH = data.get('path')
306+
BRANCH_NAME = data.get('branch')
307+
if(platform.uname()[0]=='Windows'):
308+
proc=check_output(["contribute",STUDY_NAME,STUDY_NAME_PATH,AUTHOR_NAME,BRANCH_NAME,PR_TITLE,PR_BODY],cwd=concore_path,shell=True)
309+
else:
310+
if len(BRANCH_NAME)==0:
311+
proc = check_output(["./contribute",STUDY_NAME,STUDY_NAME_PATH,AUTHOR_NAME],cwd=concore_path)
312+
else:
313+
proc = check_output(["./contribute",STUDY_NAME,STUDY_NAME_PATH,AUTHOR_NAME,BRANCH_NAME,PR_TITLE,PR_BODY],cwd=concore_path)
314+
output_string = proc.decode()
315+
status=200
316+
if output_string.find("/pulls/")!=-1:
317+
status=200
318+
elif output_string.find("error")!=-1:
319+
status=501
320+
else:
321+
status=400
322+
return jsonify({'message': output_string}),status
323+
except Exception as e:
324+
output_string = "Some Error occured.Please try after some time"
325+
status=501
326+
return jsonify({'message': output_string}),status
327+
297328
# to download /download/<dir>?fetch=<downloadfile>. For example, /download/test?fetchDir=xyz&fetch=u
298329
@app.route('/download/<dir>', methods=['POST', 'GET'])
299330
def download(dir):

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ numpy
55
scipy
66
matplotlib
77
cvxopt
8+
PyGithub

0 commit comments

Comments
 (0)