scratchattach 2.1.10a1__tar.gz → 2.1.10a3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/PKG-INFO +1 -1
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/__init__.py +2 -1
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/_base.py +3 -2
- scratchattach-2.1.10a3/scratchattach/site/browser_cookies.py +55 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/session.py +10 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/user.py +13 -14
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach.egg-info/PKG-INFO +1 -1
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach.egg-info/SOURCES.txt +1 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/setup.py +1 -1
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/LICENSE +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/README.md +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/cloud/__init__.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/cloud/_base.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/cloud/cloud.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/__init__.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/asset.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/backpack_json.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/base.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/block.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/blockshape.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/build_defaulting.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/comment.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/commons.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/extension.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/field.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/inputs.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/meta.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/monitor.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/mutation.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/pallete.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/prim.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/project.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/sbuild.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/sprite.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/twconfig.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/editor/vlb.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/__init__.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/_base.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/cloud_events.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/cloud_recorder.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/cloud_requests.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/cloud_server.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/cloud_storage.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/combine.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/filterbot.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/message_events.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/other/__init__.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/other/other_apis.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/other/project_json_capabilities.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/__init__.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/activity.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/backpack_asset.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/classroom.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/cloud_activity.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/comment.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/forum.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/project.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/site/studio.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/utils/__init__.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/utils/commons.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/utils/encoder.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/utils/enums.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/utils/exceptions.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/utils/requests.py +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach.egg-info/dependency_links.txt +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach.egg-info/requires.txt +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach.egg-info/top_level.txt +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/setup.cfg +0 -0
- {scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/tests/test_import.py +0 -0
|
@@ -19,10 +19,11 @@ from .site.comment import Comment
|
|
|
19
19
|
from .site.cloud_activity import CloudActivity
|
|
20
20
|
from .site.forum import ForumPost, ForumTopic, get_topic, get_topic_list, youtube_link_to_scratch
|
|
21
21
|
from .site.project import Project, get_project, search_projects, explore_projects
|
|
22
|
-
from .site.session import Session, login, login_by_id, login_by_session_string
|
|
22
|
+
from .site.session import Session, login, login_by_id, login_by_session_string, login_by_io, login_by_file, login_from_browser
|
|
23
23
|
from .site.studio import Studio, get_studio, search_studios, explore_studios
|
|
24
24
|
from .site.classroom import Classroom, get_classroom
|
|
25
25
|
from .site.user import User, get_user
|
|
26
26
|
from .site._base import BaseSiteComponent
|
|
27
|
+
from .site.browser_cookies import Browser, ANY, FIREFOX, CHROME, CHROMIUM, VIVALDI, EDGE, EDGE_DEV, SAFARI
|
|
27
28
|
|
|
28
29
|
from . import editor
|
|
@@ -4,9 +4,10 @@ from abc import ABC, abstractmethod
|
|
|
4
4
|
|
|
5
5
|
import requests
|
|
6
6
|
from ..utils import exceptions, commons
|
|
7
|
+
from typing import TypeVar
|
|
7
8
|
from types import FunctionType
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
C = TypeVar("C", bound="BaseSiteComponent")
|
|
10
11
|
class BaseSiteComponent(ABC):
|
|
11
12
|
@abstractmethod
|
|
12
13
|
def __init__(self):
|
|
@@ -51,7 +52,7 @@ class BaseSiteComponent(ABC):
|
|
|
51
52
|
raise exceptions.Unauthenticated(
|
|
52
53
|
"You need to use session.connect_xyz (NOT get_xyz) in order to perform this operation.")
|
|
53
54
|
|
|
54
|
-
def _make_linked_object(self, identificator_id, identificator, Class, NotFoundException) ->
|
|
55
|
+
def _make_linked_object(self, identificator_id, identificator, Class: type[C], NotFoundException) -> C:
|
|
55
56
|
"""
|
|
56
57
|
Internal function for making a linked object (authentication kept) based on an identificator (like a project id or username)
|
|
57
58
|
Class must inherit from BaseSiteComponent
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from http.cookiejar import CookieJar
|
|
3
|
+
from enum import Enum, auto
|
|
4
|
+
browsercookie_err = None
|
|
5
|
+
try:
|
|
6
|
+
import browsercookie
|
|
7
|
+
except Exception as e:
|
|
8
|
+
browsercookie = None
|
|
9
|
+
browsercookie_err = e
|
|
10
|
+
|
|
11
|
+
class Browser(Enum):
|
|
12
|
+
ANY = auto()
|
|
13
|
+
FIREFOX = auto()
|
|
14
|
+
CHROME = auto()
|
|
15
|
+
EDGE = auto()
|
|
16
|
+
SAFARI = auto()
|
|
17
|
+
CHROMIUM = auto()
|
|
18
|
+
EDGE_DEV = auto()
|
|
19
|
+
VIVALDI = auto()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
FIREFOX = Browser.FIREFOX
|
|
23
|
+
CHROME = Browser.CHROME
|
|
24
|
+
EDGE = Browser.EDGE
|
|
25
|
+
SAFARI = Browser.SAFARI
|
|
26
|
+
CHROMIUM = Browser.CHROMIUM
|
|
27
|
+
EDGE_DEV = Browser.EDGE_DEV
|
|
28
|
+
VIVALDI = Browser.VIVALDI
|
|
29
|
+
ANY = Browser.ANY
|
|
30
|
+
|
|
31
|
+
def cookies_from_browser(browser : Browser = ANY) -> dict[str, str]:
|
|
32
|
+
"""
|
|
33
|
+
Import cookies from browser to login
|
|
34
|
+
"""
|
|
35
|
+
if not browsercookie:
|
|
36
|
+
raise browsercookie_err or ModuleNotFoundError()
|
|
37
|
+
cookies : Optional[CookieJar] = None
|
|
38
|
+
if browser == ANY:
|
|
39
|
+
cookies = browsercookie.load()
|
|
40
|
+
elif browser == FIREFOX:
|
|
41
|
+
cookies = browsercookie.firefox()
|
|
42
|
+
elif browser == CHROME:
|
|
43
|
+
cookies = browsercookie.chrome()
|
|
44
|
+
elif browser == EDGE:
|
|
45
|
+
cookies = browsercookie.edge()
|
|
46
|
+
elif browser == SAFARI:
|
|
47
|
+
cookies = browsercookie.safari()
|
|
48
|
+
elif browser == CHROMIUM:
|
|
49
|
+
cookies = browsercookie.chromium()
|
|
50
|
+
elif browser == EDGE_DEV:
|
|
51
|
+
cookies = browsercookie.edge_dev()
|
|
52
|
+
elif browser == VIVALDI:
|
|
53
|
+
cookies = browsercookie.vivaldi()
|
|
54
|
+
assert isinstance(cookies, CookieJar)
|
|
55
|
+
return {cookie.name: cookie.value for cookie in cookies if "scratch.mit.edu" in cookie.domain and cookie.value}
|
|
@@ -41,6 +41,7 @@ from ..utils import commons
|
|
|
41
41
|
from ..utils import exceptions
|
|
42
42
|
from ..utils.commons import headers, empty_project_json, webscrape_count, get_class_sort_mode
|
|
43
43
|
from ..utils.requests import Requests as requests
|
|
44
|
+
from .browser_cookies import Browser, ANY, cookies_from_browser
|
|
44
45
|
|
|
45
46
|
ratelimit_cache: dict[str, list[float]] = {}
|
|
46
47
|
|
|
@@ -1132,3 +1133,12 @@ def login_by_file(file: FileDescriptorOrPath) -> Session:
|
|
|
1132
1133
|
"""
|
|
1133
1134
|
with suppress_login_warning(), open(file, encoding="utf-8") as f:
|
|
1134
1135
|
return login_by_io(f)
|
|
1136
|
+
|
|
1137
|
+
def login_from_browser(browser: Browser = ANY):
|
|
1138
|
+
"""
|
|
1139
|
+
Login from a browser
|
|
1140
|
+
"""
|
|
1141
|
+
cookies = cookies_from_browser(browser)
|
|
1142
|
+
if "scratchsessionsid" in cookies:
|
|
1143
|
+
return login_by_id(cookies["scratchsessionsid"])
|
|
1144
|
+
raise ValueError("Not enough data to log in.")
|
|
@@ -19,6 +19,17 @@ from . import activity
|
|
|
19
19
|
|
|
20
20
|
from ..utils.requests import Requests as requests
|
|
21
21
|
|
|
22
|
+
class Verificator:
|
|
23
|
+
|
|
24
|
+
def __init__(self, user: User, project_id: int):
|
|
25
|
+
self.project = user._make_linked_object("id", project_id, project.Project, exceptions.ProjectNotFound)
|
|
26
|
+
self.projecturl = self.project.url
|
|
27
|
+
self.code = ''.join(random.choices(string.ascii_letters + string.digits, k=8))
|
|
28
|
+
self.username = user.username
|
|
29
|
+
|
|
30
|
+
def check(self) -> bool:
|
|
31
|
+
return bool(list(filter(lambda x : x.author_name == self.username and (x.content == self.code or x.content.startswith(self.code) or x.content.endswith(self.code)), self.project.comments())))
|
|
32
|
+
|
|
22
33
|
class User(BaseSiteComponent):
|
|
23
34
|
|
|
24
35
|
'''
|
|
@@ -799,20 +810,8 @@ class User(BaseSiteComponent):
|
|
|
799
810
|
It will return True if the user commented the code.
|
|
800
811
|
"""
|
|
801
812
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
def __init__(self, user):
|
|
805
|
-
self.project = user._make_linked_object("id", verification_project_id, project.Project, exceptions.ProjectNotFound)
|
|
806
|
-
self.projecturl = self.project.url
|
|
807
|
-
self.code = ''.join(random.choices(string.ascii_letters + string.digits, k=130))
|
|
808
|
-
self.username = user.username
|
|
809
|
-
|
|
810
|
-
def check(self):
|
|
811
|
-
return list(filter(lambda x : x.author_name == self.username, self.project.comments())) != []
|
|
812
|
-
|
|
813
|
-
v = Verificator(self)
|
|
814
|
-
print(f"{self.username} has to go to {v.projecturl} and comment {v.code} to verify their identity")
|
|
815
|
-
return Verificator(self)
|
|
813
|
+
v = Verificator(self, verification_project_id)
|
|
814
|
+
return v
|
|
816
815
|
|
|
817
816
|
# ------ #
|
|
818
817
|
|
|
@@ -49,6 +49,7 @@ scratchattach/site/__init__.py
|
|
|
49
49
|
scratchattach/site/_base.py
|
|
50
50
|
scratchattach/site/activity.py
|
|
51
51
|
scratchattach/site/backpack_asset.py
|
|
52
|
+
scratchattach/site/browser_cookies.py
|
|
52
53
|
scratchattach/site/classroom.py
|
|
53
54
|
scratchattach/site/cloud_activity.py
|
|
54
55
|
scratchattach/site/comment.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/cloud_events.py
RENAMED
|
File without changes
|
{scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/cloud_recorder.py
RENAMED
|
File without changes
|
{scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/cloud_requests.py
RENAMED
|
File without changes
|
{scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/cloud_server.py
RENAMED
|
File without changes
|
{scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/cloud_storage.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/eventhandlers/message_events.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach/other/project_json_capabilities.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scratchattach-2.1.10a1 → scratchattach-2.1.10a3}/scratchattach.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|