Skip to content
This repository has been archived by the owner on Aug 19, 2024. It is now read-only.

Commit

Permalink
Moved default state dir to .TriblerExperimental
Browse files Browse the repository at this point in the history
  • Loading branch information
qstokkink committed Apr 17, 2024
1 parent 9a67e31 commit 0f484c6
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 20 deletions.
27 changes: 18 additions & 9 deletions src/run_tribler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,30 @@

import argparse
import asyncio
import typing
from pathlib import Path
import encodings.idna # noqa: F401 (https://github.com/pyinstaller/pyinstaller/issues/1113)
import logging.config
import os
import sys

# https://github.com/pyinstaller/pyinstaller/issues/1113
import encodings.idna # pylint: disable=unused-import
import typing
from pathlib import Path

logger = logging.getLogger(__name__)


class Arguments(typing.TypedDict):
"""
The possible command-line arguments to the core process.
"""

torrent: str
core: bool
log_level: str


def parse_args() -> Arguments:
"""
Parse the command-line arguments.
"""
parser = argparse.ArgumentParser(prog='Tribler [Experimental]', description='Run Tribler BitTorrent client')
parser.add_argument('torrent', help='torrent file to download', default='', nargs='?')
parser.add_argument('--core', action="store_true", help="run core process")
Expand All @@ -33,20 +38,24 @@ def get_root_state_directory(requested_path: os.PathLike | None) -> Path:
"""
Get the default application state directory.
"""
root_state_dir = Path(requested_path) if os.path.isabs(requested_path) else Path(os.getcwd(), requested_path)
root_state_dir = (Path(requested_path) if os.path.isabs(requested_path)
else (Path(os.environ.get("APPDATA", "~")) / ".TriblerExperimental").expanduser().absolute())
root_state_dir.mkdir(parents=True, exist_ok=True)
return root_state_dir


def main():
def main() -> None:
"""
The main script entry point for either the GUI or the core process.
"""
asyncio.set_event_loop(asyncio.SelectorEventLoop())

parsed_args = parse_args()
logging.basicConfig(level=getattr(logging, parsed_args["log_level"]), stream=sys.stdout)
logger.info(f'Run Tribler: {parsed_args}')
logger.info("Run Tribler: %s", parsed_args)

root_state_dir = get_root_state_directory(os.environ.get('TSTATEDIR', 'state_directory'))
logger.info(f'Root state dir: {root_state_dir}')
logger.info("Root state dir: %s", root_state_dir)

api_port, api_key = int(os.environ.get('CORE_API_PORT', '-1')), os.environ.get('CORE_API_KEY')

Expand Down
11 changes: 8 additions & 3 deletions src/tribler/core/start_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@

import logging.config
from asyncio import run
from pathlib import Path
from typing import TYPE_CHECKING

from tribler.core.session import Session
from tribler.tribler_config import TriblerConfigManager

if TYPE_CHECKING:
from pathlib import Path

logger = logging.getLogger(__name__)
CONFIG_FILE_NAME = 'triblerd.conf'


async def run_session(config: TriblerConfigManager) -> None:
"""
Start the Session and wait for it to shut itself down.
"""
session = Session(config)
await session.start()
await session.shutdown_event.wait()
Expand All @@ -26,7 +31,7 @@ def run_core(api_port: int, api_key: str | None, state_dir: Path) -> None:
Returns an exit code value, which is non-zero if the Tribler session finished with an error.
"""
logger.info(f'Start tribler core. API port: "{api_port}". API key: "{api_key}". State dir: "{state_dir}".')
logger.info("Start tribler core. API port: %d. API key: %s. State dir: %s.", api_port, api_key, state_dir)

config = TriblerConfigManager(state_dir / "configuration.json")
config.set("state_dir", str(state_dir))
Expand Down
78 changes: 70 additions & 8 deletions src/tribler/tribler_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import json
import logging
import os
from json import JSONDecodeError
from os import PathLike
from pathlib import Path
from typing import TypedDict

Expand All @@ -13,6 +13,10 @@


class ApiConfig(TypedDict):
"""
Settings for the API key component.
"""

key: str
http_enabled: bool
http_port: int
Expand All @@ -23,22 +27,42 @@ class ApiConfig(TypedDict):


class ContentDiscoveryCommunityConfig(TypedDict):
"""
Settings for the content discovery component.
"""

enabled: bool


class DHTDiscoveryCommunityConfig(TypedDict):
"""
Settings for the DHT discovery component.
"""

enabled: bool


class KnowledgeCommunityConfig(TypedDict):
"""
Settings for the knowledge component.
"""

enabled: bool


class DatabaseConfig(TypedDict):
"""
Settings for the database component.
"""

enabled: bool


class DownloadDefaultsConfig(TypedDict):
"""
Settings for default downloads, used by libtorrent.
"""

anonymity_enabled: bool
number_hops: int
safeseeding_enabled: bool
Expand All @@ -51,6 +75,10 @@ class DownloadDefaultsConfig(TypedDict):


class LibtorrentConfig(TypedDict):
"""
Settings for the libtorrent component.
"""

socks_listen_ports: list[int]
port: int
proxy_type: int
Expand All @@ -70,26 +98,46 @@ class LibtorrentConfig(TypedDict):


class RendezvousConfig(TypedDict):
"""
Settings for the rendezvous component.
"""

enabled: bool


class TorrentCheckerConfig(TypedDict):
"""
Settings for the torrent checker component.
"""

enabled: bool


class TunnelCommunityConfig(TypedDict):
"""
Settings for the tunnel community component.
"""

enabled: bool
min_circuits: int
max_circuits: int


class UserActivityConfig(TypedDict):
"""
Settings for the user activity component.
"""

enabled: bool
max_query_history: int
health_check_interval: float


class TriblerConfig(TypedDict):
"""
The main Tribler settings and all of its components' sub-settings.
"""

api: ApiConfig

ipv8: dict
Expand Down Expand Up @@ -157,7 +205,7 @@ class TriblerConfig(TypedDict):
"tunnel_community": TunnelCommunityConfig(enabled=True, min_circuits=1, max_circuits=8),
"user_activity": UserActivityConfig(enabled=True, max_query_history=500, health_check_interval=5.0),

"state_dir": ".",
"state_dir": str((Path(os.environ.get("APPDATA", "~")) / ".TriblerExperimental").expanduser().absolute()),
"memory_db": False
}
DEFAULT_CONFIG["ipv8"]["keys"].append({
Expand All @@ -167,33 +215,44 @@ class TriblerConfig(TypedDict):
})
DEFAULT_CONFIG["ipv8"]["overlays"] = [overlay for overlay in DEFAULT_CONFIG["ipv8"]["overlays"]
if overlay["class"] == "DiscoveryCommunity"]
DEFAULT_CONFIG["ipv8"]["working_directory"] = str(
(Path(os.environ.get("APPDATA", "~")) / ".TriblerExperimental").expanduser().absolute())


class TriblerConfigManager:
"""
A class that interacts with a JSON configuration file.
"""

def __init__(self, config_file: Path = Path("configuration.json")) -> None:
"""
Load a config from a file
Load a config from a file.
"""
super().__init__()
self.config_file = config_file

logger.info(f'Load: {self.config_file}.')
logger.info("Load: %s.", self.config_file)
self.configuration = {}
if config_file.exists():
try:
with open(self.config_file, "r") as f:
with open(self.config_file) as f:
self.configuration = json.load(f)
except JSONDecodeError as e:
except JSONDecodeError:
logger.exception("Failed to load stored configuration. Falling back to defaults!")
if not self.configuration:
self.configuration = DEFAULT_CONFIG

def write(self) -> None:
"""
Write the configuration to disk.
"""
with open(self.config_file, "w") as f:
json.dump(self.configuration, f, indent=4)

def get(self, option: PathLike | str) -> dict | list | str | int | float | bool | None:
def get(self, option: os.PathLike | str) -> dict | list | str | float | bool | None:
"""
Get a config option based on the path-like descriptor.
"""
out = self.configuration
for part in Path(option).parts:
if part in out:
Expand All @@ -206,7 +265,10 @@ def get(self, option: PathLike | str) -> dict | list | str | int | float | bool
break
return out

def set(self, option: PathLike | str, value: dict | list | str | int | float | bool | None) -> None:
def set(self, option: os.PathLike | str, value: dict | list | str | float | bool | None) -> None:
"""
Set a config option value based on the path-like descriptor.
"""
current = self.configuration
for part in Path(option).parts[:-1]:
current = current[part]
Expand Down

0 comments on commit 0f484c6

Please sign in to comment.