diff --git a/pytox/toxcore/tox.pxd b/pytox/toxcore/tox.pxd index d144b54..4099251 100644 --- a/pytox/toxcore/tox.pxd +++ b/pytox/toxcore/tox.pxd @@ -476,9 +476,9 @@ cdef extern from "tox/tox.h": cdef void tox_options_set_hole_punching_enabled(Tox_Options* self, bool hole_punching_enabled) cdef Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options* self) cdef void tox_options_set_savedata_type(Tox_Options* self, Tox_Savedata_Type savedata_type) - cdef size_t tox_options_get_savedata_length(const Tox_Options* self) - cdef const uint8_t* tox_options_get_savedata_data(const Tox_Options* self) - cdef bool tox_options_set_savedata_data(Tox_Options* self, const uint8_t* savedata_data, size_t length) + cdef bool tox_options_get_savedata(const Tox_Options* self, uint8_t* savedata) + cdef size_t tox_options_get_savedata_size(const Tox_Options* self) + cdef bool tox_options_set_savedata(Tox_Options* self, const uint8_t* savedata_data, size_t length) cdef bool tox_options_get_experimental_owned_data(const Tox_Options* self) cdef void tox_options_set_experimental_owned_data(Tox_Options* self, bool experimental_owned_data) cdef bool tox_options_get_experimental_thread_safety(const Tox_Options* self) diff --git a/pytox/toxcore/tox.pyi b/pytox/toxcore/tox.pyi index 2bd1cfb..9efb87f 100644 --- a/pytox/toxcore/tox.pyi +++ b/pytox/toxcore/tox.pyi @@ -100,7 +100,7 @@ class Tox_Options_Ptr: proxy_host: str proxy_port: int proxy_type: Tox_Proxy_Type - savedata_data: bytes + savedata: bytes savedata_type: Tox_Savedata_Type start_port: int tcp_port: int diff --git a/pytox/toxcore/tox.pyx b/pytox/toxcore/tox.pyx index 81f5da2..e8a6e8a 100644 --- a/pytox/toxcore/tox.pyx +++ b/pytox/toxcore/tox.pyx @@ -320,12 +320,20 @@ cdef class Tox_Options_Ptr: tox_options_set_savedata_type(self._get(), savedata_type) @property - def savedata_data(self) -> bytes: - return tox_options_get_savedata_data(self._get())[:tox_options_get_savedata_length(self._get())] + def savedata(self) -> bytes: + cdef size_t size = tox_options_get_savedata_size(self._get()) + cdef uint8_t* data = malloc(size) + if data is NULL: + raise MemoryError() + try: + tox_options_get_savedata(self._get(), data) + return bytes(data[:size]) + finally: + free(data) - @savedata_data.setter - def savedata_data(self, savedata_data: bytes): - tox_options_set_savedata_data(self._get(), savedata_data, len(savedata_data)) + @savedata.setter + def savedata(self, savedata: bytes): + tox_options_set_savedata(self._get(), savedata, len(savedata)) @property def experimental_owned_data(self) -> bool: @@ -475,6 +483,8 @@ cdef class Tox_Ptr: def savedata(self) -> bytes: cdef size_t size = tox_get_savedata_size(self._get()) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_get_savedata(self._get(), data) return data[:size] @@ -508,6 +518,8 @@ cdef class Tox_Ptr: def address(self) -> bytes: cdef size_t size = tox_address_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_self_get_address(self._get(), data) return data[:size] @@ -518,6 +530,8 @@ cdef class Tox_Ptr: def public_key(self) -> bytes: cdef size_t size = tox_public_key_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_self_get_public_key(self._get(), data) return data[:tox_public_key_size()] @@ -528,6 +542,8 @@ cdef class Tox_Ptr: def dht_id(self) -> bytes: cdef size_t size = tox_public_key_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_self_get_dht_id(self._get(), data) return data[:tox_public_key_size()] @@ -554,6 +570,8 @@ cdef class Tox_Ptr: def secret_key(self) -> bytes: cdef size_t size = tox_secret_key_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_self_get_secret_key(self._get(), data) return data[:tox_secret_key_size()] @@ -564,6 +582,8 @@ cdef class Tox_Ptr: def name(self) -> bytes: cdef size_t size = tox_self_get_name_size(self._get()) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_self_get_name(self._get(), data) return data[:size] @@ -581,6 +601,8 @@ cdef class Tox_Ptr: def status_message(self) -> bytes: cdef size_t size = tox_self_get_status_message_size(self._get()) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_self_get_status_message(self._get(), data) return data[:size] @@ -631,6 +653,8 @@ cdef class Tox_Ptr: def friend_list(self) -> list[Tox_Friend_Number]: cdef size_t size = tox_self_get_friend_list_size(self._get()) cdef Tox_Friend_Number *data = malloc(size * sizeof(Tox_Friend_Number)) + if data is NULL: + raise MemoryError() try: tox_self_get_friend_list(self._get(), data) return [data[i] for i in range(size)] @@ -640,6 +664,8 @@ cdef class Tox_Ptr: def friend_get_public_key(self, friend_number: Tox_Friend_Number) -> bytes: cdef size_t size = tox_public_key_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() cdef Tox_Err_Friend_Get_Public_Key err = TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK try: tox_friend_get_public_key(self._get(), friend_number, data, &err) @@ -662,6 +688,8 @@ cdef class Tox_Ptr: if err: raise ApiException(Tox_Err_Friend_Query(err)) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_friend_get_status_message(self._get(), friend_number, data, &err) if err: @@ -676,6 +704,8 @@ cdef class Tox_Ptr: if err: raise ApiException(Tox_Err_Friend_Query(err)) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_friend_get_name(self._get(), friend_number, data, &err) if err: @@ -734,6 +764,8 @@ cdef class Tox_Ptr: cdef Tox_Err_File_Get err = TOX_ERR_FILE_GET_OK cdef size_t size = tox_file_id_length() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_file_get_file_id(self._get(), friend_number, file_number, data, &err) if err: @@ -806,6 +838,8 @@ cdef class Tox_Ptr: if err: raise ApiException(Tox_Err_Conference_Title(err)) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_conference_get_title(self._get(), conference_number, data, &err) if err: @@ -846,6 +880,8 @@ cdef class Tox_Ptr: if err: raise ApiException(Tox_Err_Conference_Peer_Query(err)) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_conference_peer_get_name(self._get(), conference_number, peer_number, data, &err) if err: @@ -860,6 +896,8 @@ cdef class Tox_Ptr: if err: raise ApiException(Tox_Err_Conference_Peer_Query(err)) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_conference_offline_peer_get_name(self._get(), conference_number, offline_peer_number, data, &err) if err: @@ -872,6 +910,8 @@ cdef class Tox_Ptr: cdef Tox_Err_Conference_Peer_Query err = TOX_ERR_CONFERENCE_PEER_QUERY_OK cdef size_t size = tox_public_key_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_conference_peer_get_public_key(self._get(), conference_number, peer_number, data, &err) if err: @@ -884,6 +924,8 @@ cdef class Tox_Ptr: cdef Tox_Err_Conference_Peer_Query err = TOX_ERR_CONFERENCE_PEER_QUERY_OK cdef size_t size = tox_public_key_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_conference_offline_peer_get_public_key(self._get(), conference_number, offline_peer_number, data, &err) if err: @@ -910,6 +952,8 @@ cdef class Tox_Ptr: def conference_chatlist(self) -> list[Tox_Conference_Number]: cdef size_t size = tox_conference_get_chatlist_size(self._get()) cdef Tox_Conference_Number *data = malloc(size * sizeof(Tox_Conference_Number)) + if data is NULL: + raise MemoryError() try: tox_conference_get_chatlist(self._get(), data) return [data[i] for i in range(size)] @@ -919,6 +963,8 @@ cdef class Tox_Ptr: def conference_get_id(self, conference_number: Tox_Conference_Number) -> bytes: cdef size_t size = tox_conference_id_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: if not tox_conference_get_id(self._get(), conference_number, data): raise ApiException(0) # TODO(iphydf): There's no error enum for this. Make one. @@ -947,6 +993,8 @@ cdef class Tox_Ptr: if err: raise ApiException(Tox_Err_Group_Self_Query(err)) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_group_self_get_name(self._get(), group_number, data, &err) if err: @@ -992,6 +1040,8 @@ cdef class Tox_Ptr: cdef Tox_Err_Group_Self_Query err = TOX_ERR_GROUP_SELF_QUERY_OK cdef size_t size = tox_public_key_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_group_self_get_public_key(self._get(), group_number, data, &err) if err: @@ -1006,6 +1056,8 @@ cdef class Tox_Ptr: if err: raise ApiException(Tox_Err_Group_Peer_Query(err)) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_group_peer_get_name(self._get(), group_number, peer_id, data, &err) if err: @@ -1045,6 +1097,8 @@ cdef class Tox_Ptr: cdef Tox_Err_Group_Peer_Query err = TOX_ERR_GROUP_PEER_QUERY_OK cdef size_t size = tox_public_key_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_group_peer_get_public_key(self._get(), group_number, peer_id, data, &err) if err: @@ -1059,6 +1113,8 @@ cdef class Tox_Ptr: if err: raise ApiException(Tox_Err_Group_State_Query(err)) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_group_get_topic(self._get(), group_number, data, &err) if err: @@ -1079,6 +1135,8 @@ cdef class Tox_Ptr: if err: raise ApiException(Tox_Err_Group_State_Query(err)) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_group_get_name(self._get(), group_number, data, &err) if err: @@ -1091,6 +1149,8 @@ cdef class Tox_Ptr: cdef Tox_Err_Group_State_Query err = TOX_ERR_GROUP_STATE_QUERY_OK cdef size_t size = tox_group_chat_id_size() cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_group_get_chat_id(self._get(), group_number, data, &err) if err: @@ -1160,6 +1220,8 @@ cdef class Tox_Ptr: if err: raise ApiException(Tox_Err_Group_State_Query(err)) cdef uint8_t *data = malloc(size * sizeof(uint8_t)) + if data is NULL: + raise MemoryError() try: tox_group_get_password(self._get(), group_number, data, &err) if err: diff --git a/test/tox_options_test.py b/test/tox_options_test.py index 52ff573..89bc943 100644 --- a/test/tox_options_test.py +++ b/test/tox_options_test.py @@ -54,8 +54,8 @@ def test_options(self) -> None: opts.savedata_type = c.TOX_SAVEDATA_TYPE_TOX_SAVE self.assertEqual(opts.savedata_type, c.TOX_SAVEDATA_TYPE_TOX_SAVE) - opts.savedata_data = b"test" - self.assertEqual(opts.savedata_data, b"test") + opts.savedata = b"test" + self.assertEqual(opts.savedata, b"test") self.assertFalse(opts.experimental_thread_safety) opts.experimental_thread_safety = True diff --git a/tools/groupbot/api.py b/tools/groupbot/api.py index 06da070..d17ede0 100644 --- a/tools/groupbot/api.py +++ b/tools/groupbot/api.py @@ -71,7 +71,7 @@ def parse_args() -> Config: default=(os.path.join( BUILD_WORKSPACE_DIRECTORY, "tools", - "toktok-backup", + "backup", ) if BUILD_WORKSPACE_DIRECTORY is not None else None), ) return Config(**vars(parser.parse_args())) diff --git a/tools/groupbot/groupbot.py b/tools/groupbot/groupbot.py index d0e1909..f13318a 100644 --- a/tools/groupbot/groupbot.py +++ b/tools/groupbot/groupbot.py @@ -47,7 +47,7 @@ def __init__(self, config: api.Config) -> None: options.proxy_port = 9050 options.proxy_type = core.TOX_PROXY_TYPE_SOCKS5 if data: - options.savedata_data = data + options.savedata = data options.savedata_type = core.TOX_SAVEDATA_TYPE_TOX_SAVE super().__init__(config, options) diff --git a/tools/groupbot/groupbot.tox b/tools/groupbot/groupbot.tox index cce8014..41f879b 100644 Binary files a/tools/groupbot/groupbot.tox and b/tools/groupbot/groupbot.tox differ diff --git a/tools/groupbot/plugins/github.py b/tools/groupbot/plugins/github.py index 83e0aa5..08c93eb 100644 --- a/tools/groupbot/plugins/github.py +++ b/tools/groupbot/plugins/github.py @@ -8,6 +8,8 @@ """ import json import os +import subprocess # nosec +import time from dataclasses import dataclass from functools import cache as memoize from typing import Any @@ -105,6 +107,7 @@ def fromJSON(path: IssuePath, issue: dict[str, Any]) -> "Issue": @dataclass class GitHub(api.Handler): path: str + last_update: float = 0 @staticmethod def new(config: api.Config) -> "GitHub": @@ -147,6 +150,8 @@ def handle_cli(self, message: tuple[str, ...]) -> Optional[api.Reply]: if len(message) == 1 and "#" in message[0]: repo_name, issue_id = message[0].split("#", 1) return self.handle_issue(repo_name, issue_id) + if len(message) == 1 and message[0] == "update": + return self.handle_update() return None @@ -200,6 +205,25 @@ def handle_issue(self, repo_name: Optional[str], return api.Reply(f"{issue.emoji} {issue.title} by {issue.user.login} " f"({issue.repo}#{issue.number}, {issue.state})") + def handle_update(self) -> api.Reply: + """Pull the backup directory.""" + if time.time() - self.last_update < 60: + return api.Reply("Not updating yet, try again later") + self.last_update = time.time() + output = subprocess.run( # nosec + ["git", "pull", "--rebase"], + cwd=self.path, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ).stdout.decode().split("\n")[0] + self._clear_cache() + return api.Reply(output) + + def _clear_cache(self) -> None: + """Clear the memoization cache.""" + for func in (self.load_issue, self.issues, self.repos): + func.cache_clear() + @memoize def load_issue(self, issue: IssuePath) -> Issue: """Get the issue/PR information.""" @@ -247,8 +271,7 @@ def issues(self, repo: RepoPath) -> list[IssuePath]: api.BUILD_WORKSPACE_DIRECTORY = os.path.abspath( os.path.dirname( os.path.dirname(os.path.dirname(os.path.dirname(__file__))))) - github_path = os.path.join(api.BUILD_WORKSPACE_DIRECTORY, "tools", - "toktok-backup") + github_path = os.path.join(api.BUILD_WORKSPACE_DIRECTORY, "tools", "backup") gh = GitHub(github_path) reply = gh.handle_cli(tuple(sys.argv[1:]))