diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000..8492389 --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,40 @@ +name: Integration + +on: + pull_request: + branches: + - master + +jobs: + integration: + uses: djachenko/repokit/.github/workflows/python-integration.yml@0.5 + secrets: inherit + + publish: + needs: integration + runs-on: ubuntu-latest + permissions: + id-token: write + + steps: + - uses: actions/download-artifact@v8 + with: + name: dist + path: dist/ + + - name: Publish to TestPyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + skip-existing: true + + - name: Smoke test + run: | + PACKAGE=$(ls dist/*.whl | head -1 | xargs basename | sed 's/-[0-9].*//') + VERSION=$(ls dist/*.tar.gz | sed 's/.*-\(.*\)\.tar\.gz/\1/') + for i in {1..5}; do + pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ $PACKAGE==$VERSION && break + echo "Attempt $i failed, retrying in 10s..." + sleep 10 + done + python -c "import $PACKAGE" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ba13376 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release + +on: + push: + branches: + - master + +jobs: + release: + uses: djachenko/repokit/.github/workflows/python-release.yml@0.5 + secrets: inherit + permissions: + contents: write + + publish: + needs: release + if: needs.release.outputs.released == 'true' + runs-on: ubuntu-latest + permissions: + id-token: write + + steps: + - uses: actions/download-artifact@v8 + with: + name: dist + path: dist/ + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + + - name: Smoke test + run: | + PACKAGE=$(ls dist/*.whl | head -1 | xargs basename | sed 's/-[0-9].*//') + VERSION=$(ls dist/*.tar.gz | sed 's/.*-\(.*\)\.tar\.gz/\1/') + for i in {1..5}; do + pip install $PACKAGE==$VERSION && break + echo "Attempt $i failed, retrying in 10s..." + sleep 10 + done + python -c "import $PACKAGE" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..85d3924 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,13 @@ +name: Tests + +on: + push: + branches: + - '**' + tags-ignore: + - '**' + +jobs: + tests: + uses: djachenko/repokit/.github/workflows/python-tests.yml@0.5 + secrets: inherit diff --git a/.gitignore b/.gitignore index b8e48de..4a0419f 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ pyvko\.egg-info/ test_photos/ build/ +.repokit diff --git a/BACKLOG.md b/BACKLOG.md new file mode 100644 index 0000000..1dfc085 --- /dev/null +++ b/BACKLOG.md @@ -0,0 +1,7 @@ +# Backlog + + + +## mypy exclusions (нужно вернуть) + +- `pyvko/pyvko_runner.py` — исключён через `[[tool.mypy.overrides]] ignore_errors = true` в pyproject.toml. Файл содержит старый демо-код с ~20 реальными ошибками (устаревший API, неверные типы). Нужно либо выпилить файл, либо привести в соответствие с текущим API. diff --git a/pyproject.toml b/pyproject.toml index cbd0a14..f555595 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,48 +1,48 @@ [build-system] -requires = ["setuptools>=61.0", "wheel"] +requires = ["setuptools>=77.0.3"] build-backend = "setuptools.build_meta" [project] name = "pyvko" -version = "0.1.11" -description = "VK API utilities" +version = "0.1.0" +description = "VK API typed wrapper library" readme = "README.md" -authors = [ - { name = "Harry Djachenko", email = "i.s.djachenko@gmail.com" } -] license = { text = "MIT" } -classifiers = [ - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: 3.14", +authors = [{ name = "Igor Djachenko" }] +requires-python = ">=3.10" + +[project.optional-dependencies] +test = [ + "pytest", + "ruff", + "mypy", ] -keywords = ["vk", "api", "social"] -dependencies = [ - "vk_api", - "requests>=2.25.0", +release = [ + "build", + "python-semantic-release", ] [project.urls] -Homepage = "https://github.com/yourusername/pyvko" -"Bug Tracker" = "https://github.com/yourusername/pyvko/issues" -"Source Code" = "https://github.com/yourusername/pyvko" +Homepage = "https://github.com/djachenko/pyvko" +Repository = "https://github.com/djachenko/pyvko" +Issues = "https://github.com/djachenko/pyvko/issues" -[project.optional-dependencies] -dev = ["pytest>=8.0"] +[tool.setuptools.packages.find] +where = ["src"] + +[[tool.mypy.overrides]] +module = "vk_api.*" +ignore_missing_imports = true -[tool.setuptools] -include-package-data = true +[[tool.mypy.overrides]] +module = "pyvko.pyvko_runner" +ignore_errors = true -[tool.pytest.ini_options] -testpaths = ["tests"] -markers = [ - "smoke: базовая связность, read-only", - "create: создаёт ресурс в VK", - "destructive: удаляет ресурс в VK", -] \ No newline at end of file +[tool.semantic_release] +version_toml = ["pyproject.toml:project.version"] +branch = "master" +build_command = "pip install build && python -m build" +changelog_file = "CHANGELOG.md" +commit_message = "chore(release): v{version} [no ci]" +major_on_zero = false +allow_zero_version = true \ No newline at end of file diff --git a/pyvko/__init__.py b/src/pyvko/__init__.py similarity index 100% rename from pyvko/__init__.py rename to src/pyvko/__init__.py diff --git a/pyvko/api_based.py b/src/pyvko/api_based.py similarity index 65% rename from pyvko/api_based.py rename to src/pyvko/api_based.py index 745633e..ba818eb 100644 --- a/pyvko/api_based.py +++ b/src/pyvko/api_based.py @@ -5,7 +5,7 @@ class RequestRoot: - def get_request(self, parameters: Dict = None): + def get_request(self, parameters: Dict | None = None): return parameters or {} @@ -15,8 +15,12 @@ class ApiMixin(RequestRoot, ABC): def new_api(self) -> VkApi: pass + @property + def api(self) -> Any: + assert False, f"{type(self).__name__} still uses unmigrated api — switch to new_api" + @abstractmethod - def get_request(self, parameters: Dict = None) -> Dict: + def get_request(self, parameters: Dict | None = None) -> Dict: return super().get_request(parameters) @@ -32,13 +36,17 @@ def __init__(self, api: Any) -> None: def new_api(self) -> Any: return self.__api + @property + def api(self) -> Any: + assert False, f"{type(self).__name__} still uses unmigrated api — switch to new_api" + @staticmethod def __get_default_object(): return { # "v": ApiBased.__VERSION, } - def get_request(self, parameters: Dict = None) -> Dict: + def get_request(self, parameters: Dict | None = None) -> Dict: if parameters is None: parameters = {} diff --git a/pyvko/aspects/__init__.py b/src/pyvko/aspects/__init__.py similarity index 100% rename from pyvko/aspects/__init__.py rename to src/pyvko/aspects/__init__.py diff --git a/pyvko/aspects/albums.py b/src/pyvko/aspects/albums.py similarity index 93% rename from pyvko/aspects/albums.py rename to src/pyvko/aspects/albums.py index d0eb1ef..3bcb20e 100644 --- a/pyvko/aspects/albums.py +++ b/src/pyvko/aspects/albums.py @@ -2,7 +2,6 @@ from pathlib import Path from typing import Any, Dict, List -from vk_api import VkApi from pyvko.api_based import ApiMixin, ApiBased from pyvko.attachment.attachment import Attachment @@ -40,7 +39,7 @@ def get_photos(self) -> List[Photo]: return photos - def get_request(self, parameters: Dict = None) -> dict: + def get_request(self, parameters: Dict | None = None) -> dict: if parameters is None: parameters = {} @@ -86,7 +85,7 @@ class Albums(ApiMixin, ABC): def id(self) -> int: pass - def __get_albums(self, parameters: Dict = None) -> List[Album]: + def __get_albums(self, parameters: Dict | None = None) -> List[Album]: request = self.__get_owned_request(parameters) result = self.api.photos.getAlbums(**request) @@ -125,7 +124,7 @@ def create_album(self, name: str) -> Album: return created_album - def __get_owned_request(self, parameters: Dict = None) -> dict: + def __get_owned_request(self, parameters: Dict | None = None) -> dict: if parameters is None: parameters = {} else: diff --git a/pyvko/aspects/comments.py b/src/pyvko/aspects/comments.py similarity index 95% rename from pyvko/aspects/comments.py rename to src/pyvko/aspects/comments.py index 764c2e7..1bb6b51 100644 --- a/pyvko/aspects/comments.py +++ b/src/pyvko/aspects/comments.py @@ -3,8 +3,6 @@ from datetime import datetime from typing import List, Dict, Any -API = Any - from pyvko.api_based import ApiMixin, ApiBased from pyvko.attachment.attachment import Attachment from pyvko.attachment.attachment_parser import AttachmentParser @@ -17,7 +15,7 @@ class CommentModel: text: str from_group: int = 0 - attachments: List[Attachment] = None + attachments: List[Attachment] | None = None def to_request(self): request = {} @@ -61,12 +59,12 @@ def date(self) -> datetime: def __init__( self, - api: API, + api: Any, comment_id: int, owner_id: int, date: datetime, text: str, - attachments: List[Attachment] + attachments: List[Attachment] | None ) -> None: super().__init__(api) @@ -77,7 +75,7 @@ def __init__( self.__attachments = attachments @classmethod - def from_api_object(cls, api_object: Dict, api: API) -> 'Comment': + def from_api_object(cls, api_object: Dict, api: Any) -> 'Comment': if "attachments" in api_object: parser = AttachmentParser.shared() diff --git a/pyvko/aspects/events.py b/src/pyvko/aspects/events.py similarity index 91% rename from pyvko/aspects/events.py rename to src/pyvko/aspects/events.py index b0a29ec..194d3bd 100644 --- a/pyvko/aspects/events.py +++ b/src/pyvko/aspects/events.py @@ -79,29 +79,25 @@ def __init__(self, api: Any, event_object: Dict, settings_object: Dict | None) - self.is_closed = bool(event_object["is_closed"]) self.url = event_object["screen_name"] - self.event_category: Event.Category | None - - if settings_object is None: - self.event_category = None - self.__sections: Dict[Event.Section, Event.SectionState] = {} - self.main_section = None - self.secondary_section = None - self.organiser = None - else: + self.event_category: Event.Category | None = None + self.__sections: Dict[Event.Section, Event.SectionState] = {} + self.main_section: Event.Section | None = None + self.secondary_section: Event.Section | None = None + self.organiser: int | None = None + + if settings_object is not None: category_value = settings_object["public_category"] if category_value != 0: self.event_category = Event.Category(category_value) - else: - self.event_category = None - self.__sections: Dict[Event.Section, Event.SectionState] = { + self.__sections = { s: Event.SectionState(settings_object[s.value]) for s in Event.Section } self.main_section = Event.Section.from_index(settings_object["main_section"]) self.secondary_section = Event.Section.from_index(settings_object["secondary_section"]) - self.organiser: int | None = settings_object.get("event_object_id") + self.organiser = settings_object.get("event_object_id") @property def id(self) -> int: @@ -165,6 +161,8 @@ def create_event(self, title: str) -> Event: event = self.get_event(response["id"]) + assert event is not None + return event def get_event(self, url: str | int) -> Event | None: diff --git a/pyvko/aspects/groups.py b/src/pyvko/aspects/groups.py similarity index 88% rename from pyvko/aspects/groups.py rename to src/pyvko/aspects/groups.py index 682b3fb..d2bcf3a 100644 --- a/pyvko/aspects/groups.py +++ b/src/pyvko/aspects/groups.py @@ -1,5 +1,5 @@ from abc import ABC -from typing import Dict, List, Any, TYPE_CHECKING +from typing import Any, Dict, List, TYPE_CHECKING if TYPE_CHECKING: from pyvko.entities.user import User @@ -8,6 +8,7 @@ from pyvko.aspects.albums import Albums from pyvko.aspects.events import Events, Event from pyvko.aspects.posts import Posts +from pyvko.entities.user import User from pyvko.shared.utils import get_all @@ -43,8 +44,6 @@ def url(self) -> str: return self.__url def get_members(self) -> List['User']: - from pyvko.entities.user import User - parameters = { "group_id": self.id, "sort": "time_desc", @@ -55,9 +54,9 @@ def get_members(self) -> List['User']: parameters = self.get_request(parameters) - users_descriptions = get_all(parameters, self.api.groups.getMembers) + users_descriptions = get_all(parameters, self.new_api.groups.getMembers) - users = [User(api=self.api, user_object=description) for description in users_descriptions] + users = [User(api=self.new_api, user_object=description) for description in users_descriptions] return users diff --git a/pyvko/aspects/likes.py b/src/pyvko/aspects/likes.py similarity index 95% rename from pyvko/aspects/likes.py rename to src/pyvko/aspects/likes.py index 5c84ef4..124bb2a 100644 --- a/pyvko/aspects/likes.py +++ b/src/pyvko/aspects/likes.py @@ -56,7 +56,7 @@ def like(self) -> None: self.api.likes.add(**request) - def get_request(self, parameters: Dict = None) -> Dict: + def get_request(self, parameters: Dict | None = None) -> Dict: return super().get_request() | { "type": self.like_object_type, "owner_id": self.owner_id, diff --git a/pyvko/aspects/posts.py b/src/pyvko/aspects/posts.py similarity index 88% rename from pyvko/aspects/posts.py rename to src/pyvko/aspects/posts.py index e6faec5..2736dbf 100644 --- a/pyvko/aspects/posts.py +++ b/src/pyvko/aspects/posts.py @@ -5,8 +5,6 @@ from pathlib import Path from typing import List, Dict, Any -API = Any - from pyvko.api_based import ApiBased, ApiMixin from pyvko.aspects.comments import Comments from pyvko.aspects.likes import Likes @@ -20,12 +18,12 @@ @dataclass class PostModel: - text: str = None - attachments: List[Attachment] = None - date: datetime = None + text: str | None = None + attachments: List[Attachment] | None = None + date: datetime | None = None def to_request(self) -> dict: - request = { + request: dict[str, Any] = { "primary_attachments_mode": "grid", } @@ -48,18 +46,20 @@ def like_object_type(self) -> str: @property def item_id(self) -> int: + assert self.id is not None return self.id @property def post_id(self) -> int: + assert self.id is not None return self.id @property def owner_id(self) -> int: return self.__owner_id - def __init__(self, api: Any, owner_id: int, text: str = None, attachments: List[Attachment] = None, - date: datetime = None) -> None: + def __init__(self, api: Any, owner_id: int, text: str | None = None, attachments: List[Attachment] | None = None, + date: datetime | None = None) -> None: super().__init__(api) if attachments is None: @@ -68,11 +68,11 @@ def __init__(self, api: Any, owner_id: int, text: str = None, attachments: List[ if not text: text = None - self.date = date - self.attachments = attachments - self.id = None - self.text = text - self.timer_id = None + self.date: datetime | None = date + self.attachments: List[Attachment] = attachments + self.id: int | None = None + self.text: str | None = text + self.timer_id: int | None = None self.__owner_id = owner_id def __str__(self) -> str: @@ -103,7 +103,7 @@ def from_post_object(post_object: Dict, api: Any) -> 'Post': return post def to_request(self) -> dict: - request = { + request: dict[str, Any] = { "primary_attachments_mode": "grid", } @@ -178,6 +178,8 @@ def add_post(self, post: PostModel) -> Post: created_post = self.get_post(post_id) + assert created_post is not None + return created_post def update_post(self, post: Post): @@ -213,7 +215,7 @@ def __get_post_request(self, post: PostModel | Post): return request - def __get_owned_request(self, parameters: Dict = None) -> dict: + def __get_owned_request(self, parameters: Dict | None = None) -> dict: if parameters is None: parameters = {} else: diff --git a/pyvko/aspects/reposts.py b/src/pyvko/aspects/reposts.py similarity index 90% rename from pyvko/aspects/reposts.py rename to src/pyvko/aspects/reposts.py index 8ba483c..fa5883c 100644 --- a/pyvko/aspects/reposts.py +++ b/src/pyvko/aspects/reposts.py @@ -9,9 +9,7 @@ class Reposts(ApiMixin, ABC): 100, ] - __IGNORE_GROUPS = [ - - ] + __IGNORE_GROUPS: List[int] = [] @property def __ignore_groups(self) -> List[int]: @@ -39,9 +37,7 @@ def get_reposters(self): groups = response["groups"] groups = [group for group in groups if group["id"] not in self.__ignore_groups] - a = 7 - - def get_request(self, parameters: Dict = None) -> Dict: + def get_request(self, parameters: Dict | None = None) -> Dict: return super().get_request() | { "owner_id": self.owner_id, "post_id": self.post_id, diff --git a/pyvko/aspects/utils.py b/src/pyvko/aspects/utils.py similarity index 100% rename from pyvko/aspects/utils.py rename to src/pyvko/aspects/utils.py diff --git a/pyvko/attachment/__init__.py b/src/pyvko/attachment/__init__.py similarity index 100% rename from pyvko/attachment/__init__.py rename to src/pyvko/attachment/__init__.py diff --git a/pyvko/attachment/attachment.py b/src/pyvko/attachment/attachment.py similarity index 100% rename from pyvko/attachment/attachment.py rename to src/pyvko/attachment/attachment.py diff --git a/pyvko/attachment/attachment_parser.py b/src/pyvko/attachment/attachment_parser.py similarity index 84% rename from pyvko/attachment/attachment_parser.py rename to src/pyvko/attachment/attachment_parser.py index 19fa24b..5e8df6e 100644 --- a/pyvko/attachment/attachment_parser.py +++ b/src/pyvko/attachment/attachment_parser.py @@ -1,8 +1,6 @@ from functools import cache from typing import Any -API = Any - from pyvko.aspects.albums import Album from pyvko.attachment.attachment import Attachment from pyvko.attachment.photo import Photo @@ -35,15 +33,15 @@ def __init__(self, url: str) -> None: @property def type(self) -> str: - pass + raise NotImplementedError @property def owner_id(self) -> int: - pass + raise NotImplementedError @property def media_id(self) -> int: - pass + raise NotImplementedError def to_attach(self) -> str: return self.__url @@ -55,13 +53,13 @@ class AttachmentParser: def shared(cls): return cls() - def parse_photo(self, api_object: dict, api: API) -> Photo: + def parse_photo(self, api_object: dict, api: Any) -> Photo: return Photo.from_photo_object(api, api_object) - def parse_album(self, api_object: dict, api: API) -> Album: + def parse_album(self, api_object: dict, api: Any) -> Album: return Album(api, api_object) - def parse_object(self, api_object: dict, api: API) -> Attachment | None: + def parse_object(self, api_object: dict, api: Any) -> Attachment | None: if "photo" in api_object: return self.parse_photo(api_object["photo"], api) elif "album" in api_object: diff --git a/pyvko/attachment/photo.py b/src/pyvko/attachment/photo.py similarity index 94% rename from pyvko/attachment/photo.py rename to src/pyvko/attachment/photo.py index d7b56eb..5ae3b6d 100644 --- a/pyvko/attachment/photo.py +++ b/src/pyvko/attachment/photo.py @@ -4,7 +4,6 @@ from pyvko.api_based import ApiBased from pyvko.aspects.likes import Likes from pyvko.attachment.attachment import Attachment -from pyvko.shared.utils import Json class Photo(ApiBased, Attachment, Likes): @@ -62,7 +61,7 @@ def item_id(self) -> int: return self.__id @classmethod - def from_photo_object(cls, api: API, photo_object: Json): + def from_photo_object(cls, api: Any, photo_object: Any): id_ = photo_object["id"] owner_id = photo_object["owner_id"] diff --git a/pyvko/config/__init__.py b/src/pyvko/config/__init__.py similarity index 100% rename from pyvko/config/__init__.py rename to src/pyvko/config/__init__.py diff --git a/pyvko/config/config.py b/src/pyvko/config/config.py similarity index 100% rename from pyvko/config/config.py rename to src/pyvko/config/config.py diff --git a/pyvko/entities/__init__.py b/src/pyvko/entities/__init__.py similarity index 100% rename from pyvko/entities/__init__.py rename to src/pyvko/entities/__init__.py diff --git a/pyvko/entities/user.py b/src/pyvko/entities/user.py similarity index 79% rename from pyvko/entities/user.py rename to src/pyvko/entities/user.py index f3b3b7c..fd53cb8 100644 --- a/pyvko/entities/user.py +++ b/src/pyvko/entities/user.py @@ -1,7 +1,5 @@ from typing import List, Dict, Any -API = Any - from pyvko.api_based import ApiBased from pyvko.aspects.events import Event from pyvko.aspects.groups import Group @@ -34,7 +32,7 @@ def url(self) -> str: else: return f"https://vk.com/id{self.__id}" - def __init__(self, api: API, user_object: Dict) -> None: + def __init__(self, api: Any, user_object: Dict) -> None: super().__init__(api) self.__id = user_object["id"] @@ -49,11 +47,11 @@ def groups(self) -> List[Group]: "extended": 1, }) - groups_response = self.api.groups.get(**request) + groups_response = self.new_api.groups.get(**request) groups_objects = groups_response["items"] - groups = [Group(api=self.api, group_object=group_object) for group_object in groups_objects] + groups = [Group(api=self.new_api, group_object=group_object) for group_object in groups_objects] return groups @@ -66,6 +64,8 @@ def events(self) -> List[Event]: ]), } - response = list(get_all(request, self.api.groups.get)) + response = list(get_all(request, self.new_api.groups.get)) + + events = [Event(self.new_api, event, None) for event in response] - events = [Event(self.api, event, None) for event in response] \ No newline at end of file + return events \ No newline at end of file diff --git a/pyvko/pyvko_main.py b/src/pyvko/pyvko_main.py similarity index 87% rename from pyvko/pyvko_main.py rename to src/pyvko/pyvko_main.py index 51d4513..f957a76 100644 --- a/pyvko/pyvko_main.py +++ b/src/pyvko/pyvko_main.py @@ -10,7 +10,6 @@ from pyvko.aspects.utils import Utils from pyvko.config.config import Config from pyvko.entities.user import User -from pyvko.shared.utils import Throttler class Pyvko(ApiBased, Utils, Events, Groups): @@ -35,11 +34,11 @@ def captcha_handler(captcha: Captcha): def current_user(self) -> User: request = self.get_request() - user_response = self.api.users.get(**request) + user_response = self.new_api.users.get(**request) user_id = user_response[0] - user = User(api=self.api, user_object=user_id) + user = User(api=self.new_api, user_object=user_id) return user @@ -54,13 +53,13 @@ def get_user(self, url: str) -> User: ], }) - user_response = self.api.users.get(**user_request) + user_response = self.new_api.users.get(**user_request) - user = User(api=self.api, user_object=user_response[0]) + user = User(api=self.new_api, user_object=user_response[0]) return user - def get_by_url(self, url: str) -> Group | User | None: + def get_by_url(self, url: str) -> Group | User | Event | None: name_type = self.resolve_name(url) if name_type == "group": @@ -103,7 +102,7 @@ def execute(self, code: str): "code": code, } - response = self.api.execute(**request) + response = self.new_api.execute(**request) return response diff --git a/pyvko/pyvko_runner.py b/src/pyvko/pyvko_runner.py similarity index 91% rename from pyvko/pyvko_runner.py rename to src/pyvko/pyvko_runner.py index 23dd1ac..adfdda4 100644 --- a/pyvko/pyvko_runner.py +++ b/src/pyvko/pyvko_runner.py @@ -1,4 +1,3 @@ -import json import random from datetime import timedelta, datetime, date, time from pathlib import Path @@ -6,8 +5,8 @@ from pyvko.aspects.albums import Album from pyvko.aspects.events import Event -from pyvko.config.config import Config from pyvko.aspects.posts import Post +from pyvko.config.config import Config from pyvko.pyvko_main import Pyvko @@ -44,6 +43,8 @@ def create_scheduled_posts(): date=post_datetime ) + print(post) + # test_group.add_post(post) @@ -81,12 +82,12 @@ def test_posting_album(pyvko: Pyvko): photoset_path = Path("C:/Users/justin/photos/stages/stage2.develop/20.12.05.miss_stc/progress/") - post_config_path = photoset_path / "post_config.json" + # post_config_path = photoset_path / "post_config.json" - with post_config_path.open() as post_config_file: - post_config = json.load(post_config_file) + # with post_config_path.open() as post_config_file: + # post_config = json.load(post_config_file) - cover_name = post_config["cover"] + # cover_name = post_config["cover"] photos_folder = photoset_path / "justin" photo_paths = list(photos_folder.iterdir())[:10] @@ -114,12 +115,11 @@ def test_posting_album(pyvko: Pyvko): def get_all_members(pyvko: Pyvko): - group = pyvko.get_by_url("test") + pass + # group = pyvko.get_by_url("test") - members = group.get_members() - posts = group.get_posts() - - a = 7 + # members = group.get_members() + # posts = group.get_posts() def create_event(pyvko: Pyvko): @@ -159,8 +159,6 @@ def main(): append_album(pyvko) - a = 7 - if __name__ == '__main__': main() diff --git a/pyvko/shared/__init__.py b/src/pyvko/shared/__init__.py similarity index 100% rename from pyvko/shared/__init__.py rename to src/pyvko/shared/__init__.py diff --git a/pyvko/shared/photos_uploader.py b/src/pyvko/shared/photos_uploader.py similarity index 89% rename from pyvko/shared/photos_uploader.py rename to src/pyvko/shared/photos_uploader.py index 1c465a1..0ccd4ea 100644 --- a/pyvko/shared/photos_uploader.py +++ b/src/pyvko/shared/photos_uploader.py @@ -2,7 +2,7 @@ from abc import abstractmethod from functools import cache from pathlib import Path -from typing import Callable, Dict, List, Iterable, Any +from typing import Callable, Dict, Iterable, Any import requests as requests from vk_api import VkUpload @@ -14,12 +14,12 @@ class PhotoUploader(ApiBased): @property @abstractmethod - def server_provider(self) -> Callable[[Dict], Dict[str, str]]: + def server_provider(self) -> Callable[..., Any]: pass @property @abstractmethod - def saver(self) -> Callable[[Dict], List[Dict]]: + def saver(self) -> Callable[..., Any]: pass @property @@ -94,11 +94,11 @@ def __init__(self, api: Any, group_id: int) -> None: self.__group_id = group_id @property - def server_provider(self) -> Callable[[Dict], str]: + def server_provider(self) -> Callable[..., Any]: return self.new_api.photos.getWallUploadServer @property - def saver(self) -> Callable[[Dict], str]: + def saver(self) -> Callable[..., Any]: return self.new_api.photos.saveWallPhoto @property @@ -123,11 +123,11 @@ def __init__(self, api: Any, album_id: int, group_id: int) -> None: self.__group_id = group_id @property - def server_provider(self) -> Callable[[Dict], str]: + def server_provider(self) -> Callable[..., Any]: return self.new_api.photos.getUploadServer @property - def saver(self) -> Callable[[Dict], List[Dict]]: + def saver(self) -> Callable[..., Any]: return self.new_api.photos.save @property diff --git a/pyvko/shared/utils.py b/src/pyvko/shared/utils.py similarity index 90% rename from pyvko/shared/utils.py rename to src/pyvko/shared/utils.py index 84e2009..06b682f 100644 --- a/pyvko/shared/utils.py +++ b/src/pyvko/shared/utils.py @@ -4,8 +4,8 @@ Json = Dict[str, 'Json'] | List['Json'] | str | int -def get_all(parameters: Dict, get_response: Callable[[Json], Json], count_key: str = "count") -> \ - Iterable[Dict]: +def get_all(parameters: Dict, get_response: Callable[..., Any], count_key: str = "count") -> \ + Iterable[Any]: parameters = parameters.copy() total = 0 @@ -13,7 +13,7 @@ def get_all(parameters: Dict, get_response: Callable[[Json], Json], count_key: s parameters["offset"] = total # noinspection PyArgumentList - response = get_response(**parameters) + response: Any = get_response(**parameters) assert "items" in response assert "count" in response