(out_dir: Path=None, check_db=False, config: ConfigDict=CONFIG, in_memory_db=False)
| 1344 | |
| 1345 | |
| 1346 | def setup_django(out_dir: Path=None, check_db=False, config: ConfigDict=CONFIG, in_memory_db=False) -> None: |
| 1347 | check_system_config() |
| 1348 | |
| 1349 | output_dir = out_dir or Path(config['OUTPUT_DIR']) |
| 1350 | |
| 1351 | assert isinstance(output_dir, Path) and isinstance(config['PACKAGE_DIR'], Path) |
| 1352 | |
| 1353 | try: |
| 1354 | from django.core.management import call_command |
| 1355 | |
| 1356 | sys.path.append(str(config['PACKAGE_DIR'])) |
| 1357 | os.environ.setdefault('OUTPUT_DIR', str(output_dir)) |
| 1358 | assert (config['PACKAGE_DIR'] / 'core' / 'settings.py').exists(), 'settings.py was not found at archivebox/core/settings.py' |
| 1359 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') |
| 1360 | |
| 1361 | # Check to make sure JSON extension is available in our Sqlite3 instance |
| 1362 | try: |
| 1363 | cursor = sqlite3.connect(':memory:').cursor() |
| 1364 | cursor.execute('SELECT JSON(\'{"a": "b"}\')') |
| 1365 | except sqlite3.OperationalError as exc: |
| 1366 | stderr(f'[X] Your SQLite3 version is missing the required JSON1 extension: {exc}', color='red') |
| 1367 | hint([ |
| 1368 | 'Upgrade your Python version or install the extension manually:', |
| 1369 | 'https://code.djangoproject.com/wiki/JSON1Extension' |
| 1370 | ]) |
| 1371 | |
| 1372 | if in_memory_db: |
| 1373 | # some commands (e.g. oneshot) dont store a long-lived sqlite3 db file on disk. |
| 1374 | # in those cases we create a temporary in-memory db and run the migrations |
| 1375 | # immediately to get a usable in-memory-database at startup |
| 1376 | os.environ.setdefault("ARCHIVEBOX_DATABASE_NAME", ":memory:") |
| 1377 | django.setup() |
| 1378 | call_command("migrate", interactive=False, verbosity=0) |
| 1379 | else: |
| 1380 | # Otherwise use default sqlite3 file-based database and initialize django |
| 1381 | # without running migrations automatically (user runs them manually by calling init) |
| 1382 | django.setup() |
| 1383 | |
| 1384 | from django.conf import settings |
| 1385 | |
| 1386 | # log startup message to the error log |
| 1387 | with open(settings.ERROR_LOG, "a", encoding='utf-8') as f: |
| 1388 | command = ' '.join(sys.argv) |
| 1389 | ts = datetime.now(timezone.utc).strftime('%Y-%m-%d__%H:%M:%S') |
| 1390 | f.write(f"\n> {command}; TS={ts} VERSION={config['VERSION']} IN_DOCKER={config['IN_DOCKER']} IS_TTY={config['IS_TTY']}\n") |
| 1391 | |
| 1392 | if check_db: |
| 1393 | # Enable WAL mode in sqlite3 |
| 1394 | from django.db import connection |
| 1395 | with connection.cursor() as cursor: |
| 1396 | |
| 1397 | # Set Journal mode to WAL to allow for multiple writers |
| 1398 | current_mode = cursor.execute("PRAGMA journal_mode") |
| 1399 | if current_mode != 'wal': |
| 1400 | cursor.execute("PRAGMA journal_mode=wal;") |
| 1401 | |
| 1402 | # Set max blocking delay for concurrent writes and write sync mode |
| 1403 | # https://litestream.io/tips/#busy-timeout |
no test coverage detected