Compare commits
3 commits
24718ced1b
...
d6a84c40a3
Author | SHA1 | Date | |
---|---|---|---|
d6a84c40a3 | |||
0bee055a14 | |||
238961799d |
9 changed files with 117 additions and 7 deletions
37
backend/aci/proxy.py
Normal file
37
backend/aci/proxy.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
import aiohttp
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
from .utils import format_checkin_date
|
||||
|
||||
router = APIRouter(prefix='/3p-proxy')
|
||||
|
||||
def reformat_reject_date(date: str):
|
||||
return format_checkin_date(datetime.strptime(date, '%a %b %d %Y'))
|
||||
|
||||
@router.get('/reject')
|
||||
async def reject_proxy(date: str, time: str, activity: str, space: str):
|
||||
"""We proxy the rejectdopamine API to maintain user pivacy (the extension does not transmit user IP addresses to third-party services)"""
|
||||
async with aiohttp.ClientSession(headers={'User-Agent': 'Mozilla 5.0 (compatible); aci-backend/1.0 (+https://git.ashhhleyyy.dev/ash/aci)'}) as session:
|
||||
async with session.get('https://rejectdopamine.com/api/app/active/yrk/cs/1') as resp:
|
||||
response = await resp.json()
|
||||
activities = []
|
||||
for session in response['sessions']:
|
||||
if reformat_reject_date(session['startDate']) == date and time == f'{session["startTime"]} - {session["endTime"]}' and session['location'] in space:
|
||||
# Likely a correct result, let's return it
|
||||
return {
|
||||
'date': date,
|
||||
'time': time,
|
||||
'space': space,
|
||||
'activity': activity,
|
||||
'codes': list(map(lambda c: {'code': f'{c["checkinCode"]:06}', 'score': 0}, session['codes']))
|
||||
}
|
||||
return {
|
||||
'date': date,
|
||||
'time': time,
|
||||
'space': space,
|
||||
'activity': activity,
|
||||
'codes': [],
|
||||
}
|
|
@ -3,4 +3,7 @@ from datetime import datetime
|
|||
|
||||
def today() -> str:
|
||||
now = datetime.now()
|
||||
return f"{now.strftime('%A')} {now.day:02} {now.strftime('%B')}"
|
||||
return format_checkin_date(now)
|
||||
|
||||
def format_checkin_date(dt: datetime):
|
||||
return f"{dt.strftime('%A')} {dt.day:02} {dt.strftime('%B')}"
|
||||
|
|
|
@ -13,6 +13,7 @@ from aci.db import get_db
|
|||
from aci.migrate import run_migrations
|
||||
from aci.models import CodeSubmission
|
||||
from aci import utils
|
||||
from aci import proxy
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
@ -82,6 +83,8 @@ def query_codes(date: str, time: str, activity: str, space: str, db: sqlite3.Cur
|
|||
'codes': list(map(lambda c: {'code': c[0], 'score': c[1]}, code_scores.items()))
|
||||
}
|
||||
|
||||
app.include_router(proxy.router)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_migrations()
|
||||
uvicorn.run(app, host='0.0.0.0')
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "aci",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"description": "auto checkin",
|
||||
"content_scripts":[
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
|||
}
|
||||
],
|
||||
"permissions": [
|
||||
"storage",
|
||||
"webRequest",
|
||||
"*://aci-api.ashhhleyyy.dev/*",
|
||||
"*://checkin.york.ac.uk/*"
|
||||
|
@ -22,6 +23,9 @@
|
|||
"browser_action": {
|
||||
"default_popup": "src/popup.html"
|
||||
},
|
||||
"options_ui": {
|
||||
"page": "src/config.html"
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"update_url": "https://git.ashhhleyyy.dev/ash/aci/raw/branch/main/addon_updates.json",
|
||||
|
|
12
extension/src/config-page.js
Normal file
12
extension/src/config-page.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
(async function() {
|
||||
const rejectCheckbox = document.querySelector('#enable-reject');
|
||||
chrome.storage.sync.get('enable_reject', (data) => {
|
||||
rejectCheckbox.checked = data.enable_reject;
|
||||
});
|
||||
rejectCheckbox.addEventListener('change', async function() {
|
||||
await chrome.storage.sync.set({
|
||||
enable_reject: rejectCheckbox.checked,
|
||||
});
|
||||
});
|
||||
rejectCheckbox.disabled = false;
|
||||
})();
|
22
extension/src/config.html
Normal file
22
extension/src/config.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Checkin Codes</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="ash.css">
|
||||
<script src="config-page.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-container">
|
||||
<main class="content" id="root">
|
||||
<label>
|
||||
<input id="enable-reject" type="checkbox" disabled>
|
||||
Enable fetching codes from rejectdopamine.com (3rd party service)
|
||||
</label>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,2 +1,2 @@
|
|||
this.SERVER_URL = 'https://aci-api.ashhhleyyy.dev';
|
||||
//this.SERVER_URL = 'http://localhost:8000';
|
||||
//this.SERVER_URL = 'https://aci-api.ashhhleyyy.dev';
|
||||
this.SERVER_URL = 'http://localhost:8000';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(async function() {
|
||||
chrome.storage.sync.get(['enable_reject'], async function(config) {
|
||||
const root = document.querySelector('#root');
|
||||
|
||||
function codeTable(codes) {
|
||||
|
@ -97,12 +97,39 @@
|
|||
message(`Something went wrong: ${e}`);
|
||||
console.error(e);
|
||||
});
|
||||
removeLoading();
|
||||
if (!res.ok) {
|
||||
removeLoading();
|
||||
message('Server returned error code ' + res.status + ': ' + res.statusText, true);
|
||||
return;
|
||||
}
|
||||
const activity = await res.json();
|
||||
|
||||
if (config.enable_reject) {
|
||||
const rejectRes = await fetch(SERVER_URL + '/3p-proxy/reject?' + query).catch((e) => {
|
||||
message(`Something went wrong: ${e}`);
|
||||
console.error(e);
|
||||
});
|
||||
if (!rejectRes.ok) {
|
||||
message('Warning: failed to fetch codes from reject');
|
||||
} else {
|
||||
const extraActivity = await rejectRes.json();
|
||||
for (const code of extraActivity.codes) {
|
||||
let found = false;
|
||||
for (const code2 of activity.codes) {
|
||||
if (code.code === code2.code) {
|
||||
code2.score += code.score;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
activity.codes.push(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeLoading();
|
||||
if (activity.codes.length === 0) {
|
||||
message('No codes are available right now :/');
|
||||
} else {
|
||||
|
@ -133,4 +160,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
|
|
@ -13,10 +13,12 @@
|
|||
dependencies = ps: with ps; [
|
||||
fastapi
|
||||
uvicorn
|
||||
aoihttp
|
||||
];
|
||||
devDependencies = ps: with ps; [
|
||||
fastapi
|
||||
uvicorn
|
||||
aiohttp
|
||||
python-lsp-server
|
||||
];
|
||||
version = self.shortRev or self.dirtyShortDev or "dirty-inputs";
|
||||
|
|
Loading…
Reference in a new issue