Skip to content

Commit 32e7a82

Browse files
committed
load cookies from leetcode.com
1 parent 36e33ce commit 32e7a82

File tree

9 files changed

+157
-35
lines changed

9 files changed

+157
-35
lines changed

jupyterlab_leetcode/handlers.py

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from jupyter_server.utils import url_path_join
2+
3+
from .base_handler import BaseHandler
4+
from .cookie_handler import GetCookieHandler
5+
6+
7+
def setup_handlers(web_app):
8+
host_pattern = ".*$"
9+
base_url = web_app.settings["base_url"]
10+
handlers: list[type[BaseHandler]] = [GetCookieHandler]
11+
12+
web_app.add_handlers(
13+
host_pattern,
14+
list(
15+
map(
16+
lambda h: (url_path_join(base_url, "jupyterlab-leetcode", h.route), h),
17+
handlers,
18+
)
19+
),
20+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from jupyter_server.base.handlers import APIHandler
2+
3+
4+
class BaseHandler(APIHandler):
5+
"""Base handler for JupyterLab LeetCode extension.
6+
This class extends APIHandler to provide a base for other handlers.
7+
It can be used to define common functionality or properties for all handlers.
8+
"""
9+
10+
route = r""
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import json
2+
3+
import browser_cookie3
4+
import tornado
5+
6+
from .base_handler import BaseHandler
7+
8+
BROWSER_COOKIE_METHOD_MAP = {
9+
"chrome": browser_cookie3.chrome,
10+
"chromium": browser_cookie3.chromium,
11+
"opera": browser_cookie3.opera,
12+
"opera_gx": browser_cookie3.opera_gx,
13+
"brave": browser_cookie3.brave,
14+
"edge": browser_cookie3.edge,
15+
"vivaldi": browser_cookie3.vivaldi,
16+
"firefox": browser_cookie3.firefox,
17+
"librewolf": browser_cookie3.librewolf,
18+
"safari": browser_cookie3.safari,
19+
"arc": browser_cookie3.arc,
20+
}
21+
22+
23+
class GetCookieHandler(BaseHandler):
24+
route = r"cookies/[a-zA-Z0-9_-]+"
25+
26+
@tornado.web.authenticated
27+
def get(self):
28+
self.log.info("Loading all cookies for LeetCode...")
29+
browser = self.get_query_argument("browser", "", strip=True)
30+
if not browser:
31+
self.set_status(400)
32+
self.finish(json.dumps({"message": "Browser parameter is required"}))
33+
return
34+
35+
if browser not in BROWSER_COOKIE_METHOD_MAP:
36+
self.set_status(400)
37+
self.finish(json.dumps({"message": f"Unsupported browser: {browser}"}))
38+
return
39+
40+
cj = BROWSER_COOKIE_METHOD_MAP[browser](domain_name="leetcode.com")
41+
42+
self.finish(
43+
json.dumps(
44+
dict(
45+
map(
46+
lambda c: (
47+
c.name,
48+
{"name": c.name, "domain": c.domain, "value": c.value},
49+
),
50+
cj,
51+
)
52+
)
53+
)
54+
)

src/components/BrowserCookie.tsx

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,68 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
2+
import { getCookie } from '../services/cookie';
23

34
const BrowserCookie = () => {
5+
const browsers = [
6+
'Chrome',
7+
'Firefox',
8+
'Safari',
9+
'Edge',
10+
'Opera',
11+
'Brave',
12+
'Vivaldi',
13+
'Chromium',
14+
'Arc',
15+
'LibreWolf',
16+
'Opera GX'
17+
];
18+
19+
const [browser, setBrowser] = useState('');
20+
const [checked, setChecked] = useState(false);
21+
422
const loadCookies = () => {
5-
console.log('Loading cookies from leetcode.com');
23+
if (!browser) {
24+
alert('Please select a browser.');
25+
return;
26+
}
27+
if (browser === 'safari') {
28+
alert(
29+
'Safari does not support loading cookies from the browser. Please use another browser.'
30+
);
31+
return;
32+
}
33+
34+
getCookie('all', browser).then(cookies => {
35+
if (cookies && cookies['LEETCODE_SESSION'] && cookies['csrftoken']) {
36+
setChecked(true);
37+
}
38+
});
639
};
740

841
return (
942
<div>
43+
<label htmlFor="browser-selector">
44+
Choose your browser that has LeetCode logged in:
45+
</label>
46+
<select
47+
id="browser-selector"
48+
required
49+
value={browser}
50+
onChange={e => setBrowser(e.target.value)}
51+
>
52+
<option value="" disabled>
53+
Select a browser
54+
</option>
55+
{browsers.map(browser => (
56+
<option
57+
key={browser.toLowerCase()}
58+
value={browser.toLowerCase().replace(/\s+/g, '_')}
59+
>
60+
{browser}
61+
</option>
62+
))}
63+
</select>
1064
<button onClick={loadCookies}>Load</button>
65+
<p>Checked: {checked ? 'Yes' : 'No'}</p>
1166
</div>
1267
);
1368
};

src/index.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ const plugin: JupyterFrontEndPlugin<void> = {
2121
palette: ICommandPalette,
2222
restorer: ILayoutRestorer | null
2323
) => {
24-
console.log('JupyterLab extension jupyterlab-leetcode is activated!');
25-
2624
let leetcodeWidget: LeetCodeWidget;
2725

2826
const command = 'leetcode-widget:open';
@@ -47,7 +45,6 @@ const plugin: JupyterFrontEndPlugin<void> = {
4745
namespace: 'leetcode-widget'
4846
});
4947
if (restorer) {
50-
console.log('Restoring layout for jupyterlab-leetcode plugin');
5148
restorer.restore(tracker, { command, name: () => 'leetcode' });
5249
}
5350
}

src/services/cookie.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { requestAPI } from './handler';
2+
3+
export async function getCookie(
4+
name: string,
5+
browser: string
6+
): Promise<{ [key: string]: any }> {
7+
return requestAPI<{ [key: string]: any }>(
8+
`/cookies/${name}?browser=${browser}`
9+
).catch(() => ({}));
10+
}
File renamed without changes.

src/widget.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@ import React from 'react';
33
import BrowserCookie from './components/BrowserCookie';
44

55
const LeetCodeComponent = (): JSX.Element => {
6+
const options: JSX.Element[] = [<BrowserCookie />];
67
return (
78
<div>
89
<p>Welcome to JupyterLab LeetCode Widget.</p>
9-
<BrowserCookie />
10+
<p>
11+
For this plugin to work, you may choose one of these {options.length}{' '}
12+
methods to allow this plugin to log into LeetCode.
13+
</p>
14+
{...options}
1015
</div>
1116
);
1217
};

0 commit comments

Comments
 (0)