Skip to content

Instantly share code, notes, and snippets.

@ttycelery
Created January 19, 2023 07:41
Show Gist options
  • Save ttycelery/049698fe2609047c073ea2b2d0e28f32 to your computer and use it in GitHub Desktop.
Save ttycelery/049698fe2609047c073ea2b2d0e28f32 to your computer and use it in GitHub Desktop.
auto-edom -- automatically fill your lecturer evaluation questionnaires on SIMASTER UGM
"""
auto-edom -- automatically fill your lecturer evaluation questionnaires
on SIMASTER UGM
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2023 Faiz Jazadi <me@lcat.dev>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
"""
import re
import sys
import requests
BASE_URL = "https://simaster.ugm.ac.id"
LOGIN_URL = f"{BASE_URL}/services/simaster/service_login"
HEADERS = {"UGMFWSERVICE": "1", "User-Agent": "SimasterICS/1.0.0"}
EDOM_URL = f"{BASE_URL}/akademik/mhs_evaluasi_dosen"
QUES_URL = f"{EDOM_URL}/quesioner"
INSTRUMENT_ANSWER = "1" # 1 = sangat baik, 2 = baik, ...
def get_simaster_session(username, password):
ses = requests.Session()
req = ses.post(
LOGIN_URL,
data={
"aId": "",
"username": username,
"password": password,
},
headers=HEADERS,
)
if req.status_code != 200:
return None
return ses
def abort(message):
print(message)
print("exiting...")
sys.exit(1)
def get_hidden_input_value(res, name):
result = re.findall(
f'hidden" name="{name}" value="(.+?)">',
res.text, re.M)
if not result:
return None
# return the last input found
return result[-1]
def main(username, password):
# simaster session
print("trying to get simaster session... ", end="")
ses = get_simaster_session(username, password)
if not ses:
abort("failed!")
print("success!")
# edom links
print("getting edom urls... ", end="")
res = ses.get(EDOM_URL)
edom_urls = re.findall(
r"(https.*mhs_evaluasi_dosen/[a-zA-Z0-9=/_-]+)", res.text, re.M)
if not edom_urls:
abort("failed")
print(f"grabbed {len(edom_urls)} urls")
for url in edom_urls:
print(f"current edom url: {url}")
res = ses.get(url)
q_urls = re.findall(
r"(https.*quesioner/[a-zA-Z0-9=/_-]+)", res.text, re.M)
if not q_urls:
print('looks like edom is already done for this url!')
for q_i, q_url in enumerate(q_urls):
res = ses.get(q_url)
post_data = {}
hidden_inputs = ("simasterUGM_token", "sesiId", "mkKelasId",
"mkKelasGabunganId", "dosenId", "evalKe")
for i in range(1, 13):
post_data[f"jawabanInstrumenPilihan[{i}]"] = INSTRUMENT_ANSWER
for name in hidden_inputs:
post_data[name] = get_hidden_input_value(res, name)
print(f"sending response for questionnaire #{q_i}... ", end="")
ses.post(QUES_URL, data=post_data)
print("done!")
if __name__ == "__main__":
if len(sys.argv) != 3:
print(f"usage: {sys.argv[0]} <username> <password>")
sys.exit(1)
main(sys.argv[1], sys.argv[2])
@BlueBeret
Copy link

I think using un-echoed input is better because it ensure that passwords are not visible on the screen and can help prevent potential security threats such as password theft or unauthorized access.
history | grep auto_edom

@ttycelery
Copy link
Author

Nice suggestion. I just discovered that my history file is actually a big pile of passwords 💀. I will consider adding an alternative behavior i.e. to use password input when no arguments are supplied.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment