Developer Overview#
This document provides a high-level overview of the main modules in the
overleaf_fs package and their responsibilities. It is intended as a
starting point for new contributors and as a quick reminder for future
maintenance and refactoring work.
Package layout#
The package is organized into a small core layer (data model, config, persistence, scraping, and index construction) and a GUI layer (Qt-based desktop application), plus minimal top-level entry points.
Top-level package (overleaf_fs)#
overleaf_fs/__init__.pyLightweight package initializer. Currently provides package metadata (such as the version) and a convenient place for any future top-level imports or helpers that should be exposed as
overleaf_fs.*.overleaf_fs/app.pyGUI application bootstrap. Creates the Qt application object, constructs the main window, and starts the event loop. This is the canonical way to launch the desktop GUI from Python code.
overleaf_fs/cli.pyCommand-line entry points. Provides the functions that are wired up by packaging (e.g. console scripts) and can be extended with additional subcommands for scripting or headless utilities.
Core layer (overleaf_fs.core)#
The core layer contains configuration handling, persistent metadata storage, the data model, and logic for connecting Overleaf’s project information with local directory-structure data.
overleaf_fs/core/__init__.pyMarks the
coresubpackage and may re-export a small number of public helpers in the future. At the moment it is intentionally minimal to keep the public surface explicit.overleaf_fs/core/config.pyCentral configuration and path logic.
Knows where the profile root directory lives on disk.
Defines the canonical filenames for the per-profile JSON files:
projects-info JSON file:
overleaf_projects_info.jsondirectory-structure JSON file:
local_directory_structure.jsonprofile-config JSON file:
profile_config.json
Provides helpers such as
get_active_profile_data_dir(),get_projects_info_path(), andget_directory_structure_path()so that other modules never hard-code paths or filenames.Contains
FILE_FORMAT_VERSIONand related constants that control the on-disk layout.
overleaf_fs/core/metadata_store.pyPersistence for local directory-structure data.
Defines
LocalState, which holds:folders: explicit list of known folder paths (e.g."CT","Teaching/2025"), used to persist empty folders.projects: mapping from project id toProjectLocal(folder, notes, pinned/hidden flags).
Implements
load_directory_structure()andsave_directory_structure()which read/write the directory-structure JSON file located atget_directory_structure_path().Does not know about the Overleaf-side projects-info JSON; it is strictly responsible for local-only metadata.
overleaf_fs/core/models.pyCore data model definitions.
ProjectRemote: Overleaf-side fields for a project, as stored in the projects-info JSON file.ProjectLocal: local-only directory-structure fields for a project, as stored in the directory-structure JSON file.ProjectRecord: in-memory combination ofremoteandlocaldata for a single project id.ProjectsIndex: type alias for the mappingDict[str, ProjectRecord]that represents all known projects.
overleaf_fs/core/overleaf_scraper.pyScraping and synchronization with the Overleaf project dashboard.
Builds an authenticated HTTP session from a browser Cookie header.
Scrapes the Overleaf projects dashboard and converts the results to
OverleafProjectDTOobjects.Writes the projects-info JSON file at
get_projects_info_path().Exposes an entry point used by the GUI to refresh the cached projects-info data for the active profile.
overleaf_fs/core/project_index.pyConstruction of the in-memory projects index.
Loads the projects-info JSON (remote metadata) and the directory-structure JSON (local metadata).
Merges these two sources into a
ProjectsIndexmapping from project id toProjectRecord.The merge is keyed by Overleaf project id:
ProjectRecord.remoteis overwritten on each refresh from Overleaf.ProjectRecord.localis preserved across refreshes and reflects the user’s local organization and annotations.
overleaf_fs/core/profiles.pyProfile management and profile-level storage configuration.
Defines
ProfileInfoand helpers for discovering, creating, renaming, and deleting profiles under the profile root directory.Stores and retrieves the active profile via
active_profile.json.Provides
get_active_profile_info()and related helpers used at startup to ensure that an active profile always exists.Encapsulates all logic for paths and filenames inside profile-level subdirectories.
GUI layer (overleaf_fs.gui)#
The GUI layer provides the Qt-based desktop application. It is split into a main window, a login dialog, and supporting widgets plus their models.
overleaf_fs/gui/__init__.pyMarks the
guisubpackage. Kept minimal so that importing the GUI layer is explicit and does not accidentally pull in Qt when used as a library.overleaf_fs/gui/main_window.pyThe main application window and high-level GUI controller.
Owns the project tree (folders) and project table widgets.
Initializes the profile subsystem: ensures a valid profile root exists and calls
get_active_profile_info()so that an active profile is always available on startup.Connects user actions (selection, drag-and-drop, sync buttons) to core-layer operations such as
load_projects_index(),load_directory_structure(), and Overleaf refresh calls.Implements external-change detection for the metadata JSON files and offers to reload when they change on disk.
overleaf_fs/gui/profile_manager.pyProfile selection and management dialog.
Allows the user to select, create, rename, delete, or open a profile.
Provides a “Move…” action to relocate the entire profile-storage folder, using shared UI helpers.
Ensures that the current active profile is restored when the user presses Cancel.
Delegates disk‑level path changes to the core config layer.
overleaf_fs/gui/profile_root_ui.pyShared UI helpers for selecting or relocating the profile root directory.
Presents the explanatory message shown when choosing a profile storage folder.
Configures a non-native directory chooser dialog with cloud-storage sidebar entries.
Provides
choose_profile_root_directory()for both first‑run setup and the profile manager’s Move… flow.Includes
looks_like_profile_root()which detects whether a folder already contains OverleafFS profile data.
overleaf_fs/gui/overleaf_login.pyLogin / cookie-entry dialog.
Provides a small dialog where the user can paste a browser Cookie header used to authenticate with Overleaf.
Hands the Cookie header off to
overleaf_scraperto refresh the projects-info JSON.Can be extended in the future to support richer authentication flows.
overleaf_fs/gui/project_table.pyProject table widget and related utilities.
Contains the Qt widget that displays the list of projects in tabular form.
Handles interactions such as row selection and double-click behavior, delegating data access to the table model.
overleaf_fs/gui/project_table_model.pyQt table model for projects.
Implements
QAbstractTableModel(or a subclass) backed by theProjectsIndex.Provides the data needed by the project table widget: project name, owner, folder, last modified time, pinned/hidden flags, etc.
Encapsulates sorting and column configuration logic.
overleaf_fs/gui/project_tree.pyProject folder tree widget.
Represents the folder hierarchy (Home, subfolders, pinned/archived views) as a Qt tree widget.
Supports folder selection, expansion/collapse, and drag-and-drop of projects between folders.
Works in concert with the main window to keep the tree in sync with the current directory-structure metadata.
Notes for future maintenance#
Keep file and directory names centralized in
config.pyso other modules do not hard-code paths or filenames.Treat
metadata_storeas the single source of truth for the directory-structure JSON file, andproject_indexas the place where remote (Overleaf) and local (directory-structure) metadata are merged.When evolving the on-disk format, update
FILE_FORMAT_VERSIONand document any migration steps here so that future refactors remain understandable.Keep profile-handling logic centralized in
profiles.pyand route all profile‑root selection throughprofile_root_ui.pyto avoid duplicating UI flows.