Files
nextcloud-share/.plans/CreateLibNextcloud.md

19 KiB

libnextcloud Shared Library Plan

Created: 2026-01-27
Status: 📋 Planning
Target: Cross-platform C++17 shared library for Nextcloud connectivity
Branch: create-libnextcloud


Overview

Create libnextcloud - a cross-platform C++17 shared library that provides Nextcloud connectivity for embedded devices and homebrew platforms. The library will handle all Nextcloud communication, authentication, file operations, and settings management through a clean, platform-agnostic API.

Design Philosophy:

  • Platform-agnostic: Works on 3DS, Switch, Wii U, Vita, PC, etc.
  • Minimal dependencies: Only libcurl, mbedTLS, and tinyxml2
  • Header-only where possible: nlohmann/json for configuration
  • Modern C++17: Using standard library features
  • Testable: Mock-friendly design with dependency injection
  • Documented: Doxygen API documentation

Project Structure

shared/
├── include/
│   └── nextcloud/
│       ├── client.hpp              # Main client interface
│       ├── webdav_client.hpp       # WebDAV protocol implementation
│       ├── auth.hpp                # Authentication manager
│       ├── upload_manager.hpp      # File upload with chunking
│       ├── folder_manager.hpp      # Remote folder operations
│       ├── config.hpp              # Configuration management
│       ├── types.hpp               # Common types and enums
│       └── version.hpp             # Library version info
├── src/
│   ├── webdav_client.cpp
│   ├── auth.cpp
│   ├── upload_manager.cpp
│   ├── folder_manager.cpp
│   └── config.cpp
├── tests/
│   ├── webdav_client_test.cpp
│   ├── auth_test.cpp
│   ├── upload_manager_test.cpp
│   ├── folder_manager_test.cpp
│   ├── config_test.cpp
│   └── mocks/
│       ├── mock_http_client.hpp
│       └── mock_xml_parser.hpp
├── examples/
│   ├── simple_upload.cpp
│   ├── folder_listing.cpp
│   └── authentication.cpp
├── docs/
│   ├── api.md                      # API documentation
│   ├── architecture.md             # Design overview
│   └── Doxyfile                    # Doxygen configuration
├── CMakeLists.txt
└── README.md

Dependencies

Required

  • libcurl (7.68+): HTTP/HTTPS client
  • mbedTLS (2.16+): SSL/TLS support (works on embedded)
  • tinyxml2 (9.0+): Lightweight XML parsing

Header-Only

  • nlohmann/json (3.10+): JSON parsing/serialization

Testing

  • Google Test (1.11+): Unit testing framework
  • Google Mock (1.11+): Mocking framework

Build Tools

  • CMake (3.15+): Build system
  • C++17 compiler: GCC 7+, Clang 5+, MSVC 2017+

Implementation Phases

Phase 1: Project Scaffolding (Issue #??)

Goal: Set up the library project structure and build system.

Tasks

  • Create shared/ directory structure
  • Set up CMakeLists.txt with:
    • Library target (static/shared)
    • C++17 standard
    • Include directories
    • Dependency linking (curl, mbedtls, tinyxml2)
    • Install rules
    • Export config for downstream projects
  • Create version.hpp with semantic versioning
  • Create types.hpp with common enums and structures:
    • NextcloudError enum
    • UploadProgress struct
    • FileInfo struct
    • FolderInfo struct
  • Set up Google Test framework
  • Create basic README for the library
  • Add pkg-config file generation
  • Verify library compiles as standalone project

Acceptance Criteria

  • CMake builds library successfully
  • Can link against library from test project
  • Version info accessible at runtime
  • Ready for component implementation

Estimated Time: 4-6 hours
Priority: Critical (blocks all other work)


Phase 2: WebDAV Client (Issue #8)

Goal: Implement HTTP/WebDAV communication layer.

Tasks

  • Create webdav_client.hpp interface
  • Implement HTTP wrapper around libcurl:
    • GET, PUT, POST, DELETE, custom methods
    • Request/response headers
    • Request body (string, stream)
    • Response body handling
    • Timeout configuration
    • User-Agent setting
  • Add SSL/TLS support with mbedTLS
  • Implement WebDAV methods:
    • PROPFIND (list files/folders)
    • MKCOL (create folder)
    • PUT (upload file)
    • DELETE (remove file/folder)
    • MOVE (rename/move)
    • COPY (duplicate)
  • Parse WebDAV XML responses (using tinyxml2):
    • Multi-status responses
    • File properties (size, mtime, type)
    • Error responses
  • Implement error handling:
    • HTTP status codes
    • Network errors
    • XML parsing errors
    • Error code mapping
  • Add timeout and retry logic
  • Write unit tests with mocked HTTP
  • Document API in Doxygen format

API Design

class WebDAVClient {
public:
    WebDAVClient(const std::string& baseUrl);
    
    // Core HTTP
    Response get(const std::string& path);
    Response put(const std::string& path, const std::vector<uint8_t>& data);
    Response delete_(const std::string& path);
    
    // WebDAV operations
    std::vector<FileInfo> propfind(const std::string& path, int depth = 1);
    bool mkcol(const std::string& path);
    bool move(const std::string& from, const std::string& to);
    bool copy(const std::string& from, const std::string& to);
    
    // Configuration
    void setTimeout(int seconds);
    void setAuthHeader(const std::string& header);
};

Acceptance Criteria

  • All WebDAV methods implemented
  • SSL/TLS connections working
  • XML responses correctly parsed
  • Error handling comprehensive
  • Unit tests with >80% coverage
  • API documented
  • Works with test Nextcloud servers

Estimated Time: 12-16 hours
Priority: Critical (foundation for all features)
Dependencies: Phase 1 complete


Phase 3: Authentication System (Issue #9)

Goal: Handle authentication with Nextcloud servers.

Tasks

  • Create auth.hpp interface
  • Implement HTTP Basic Authentication:
    • Base64 encoding
    • Authorization header generation
    • Credential storage
  • Add authentication verification:
    • Test connection to server
    • Validate credentials
    • Return meaningful error codes
  • Secure credential handling:
    • In-memory only (no disk storage by default)
    • Platform-specific secure storage hooks
  • Session management:
    • Keep-alive connections
    • Connection pooling
    • Timeout handling
  • Future: OAuth2 support (stubbed for now)
  • Write unit tests for auth flows
  • Document security considerations

API Design

class AuthManager {
public:
    // Basic Auth
    void setBasicAuth(const std::string& username, const std::string& password);
    std::string getAuthHeader() const;
    
    // Verification
    bool verifyConnection(WebDAVClient& client);
    
    // Session management
    void clearCredentials();
    bool hasCredentials() const;
};

Acceptance Criteria

  • Basic auth working with real Nextcloud
  • Credentials never logged or leaked
  • Connection verification works
  • Error messages helpful
  • Unit tests cover edge cases
  • API documented

Estimated Time: 6-8 hours
Priority: High
Dependencies: Phase 2 complete


Phase 4: Upload Manager (Issue #10)

Goal: Implement file upload with chunking and progress tracking.

Tasks

  • Create upload_manager.hpp interface
  • Implement streaming upload:
    • Read file in chunks
    • Send via PUT requests
    • Handle large files (>1GB)
  • Add chunking support:
    • Configurable chunk size (default: 10MB)
    • Resume capability (future)
    • Parallel chunks (future)
  • Progress tracking:
    • Callback interface
    • Bytes uploaded / total
    • Transfer speed
    • Time remaining estimate
  • Error handling and retry:
    • Network failures
    • Server errors (503, 507)
    • Automatic retry with backoff
    • Partial upload cleanup
  • Path handling:
    • URL encoding
    • Special characters
    • Nested folders
  • Write unit tests with mock uploads
  • Document upload best practices

API Design

class UploadManager {
public:
    using ProgressCallback = std::function<void(const UploadProgress&)>;
    
    UploadManager(WebDAVClient& client, AuthManager& auth);
    
    // Upload operations
    bool uploadFile(
        const std::string& localPath,
        const std::string& remotePath,
        ProgressCallback callback = nullptr
    );
    
    // Configuration
    void setChunkSize(size_t bytes);
    void setRetryCount(int count);
    void setTimeout(int seconds);
};

struct UploadProgress {
    std::string filename;
    size_t bytesUploaded;
    size_t totalBytes;
    float percentComplete;
    float bytesPerSecond;
    int secondsRemaining;
};

Acceptance Criteria

  • Uploads files successfully
  • Chunking works for large files
  • Progress callback accurate
  • Handles network failures gracefully
  • Retries work correctly
  • Unit tests with various file sizes
  • API documented

Estimated Time: 10-12 hours
Priority: High
Dependencies: Phases 2, 3 complete


Phase 5: Folder Management (Issue #11)

Goal: Remote folder operations and navigation.

Tasks

  • Create folder_manager.hpp interface
  • Implement folder listing:
    • List contents of remote folder
    • Parse file metadata (size, mtime, type)
    • Recursive listing support
    • Filtering (files only, folders only)
  • Folder creation:
    • Create single folder
    • Create nested folders (mkdir -p)
    • Validate folder names
  • Folder navigation:
    • Path normalization
    • Parent folder detection
    • Breadcrumb generation
  • Caching (optional):
    • Cache folder contents
    • TTL-based invalidation
    • Memory limits
  • Write unit tests
  • Document folder operations

API Design

class FolderManager {
public:
    FolderManager(WebDAVClient& client, AuthManager& auth);
    
    // Folder operations
    std::vector<FileInfo> listFolder(const std::string& path);
    bool createFolder(const std::string& path);
    bool createFolders(const std::string& path);  // mkdir -p
    bool deleteFolder(const std::string& path);
    bool folderExists(const std::string& path);
    
    // Navigation helpers
    std::string getParentFolder(const std::string& path);
    std::vector<std::string> getBreadcrumbs(const std::string& path);
};

struct FileInfo {
    std::string name;
    std::string path;
    bool isDirectory;
    size_t size;
    time_t modifiedTime;
    std::string contentType;
};

Acceptance Criteria

  • Lists folders correctly
  • Creates folders successfully
  • Handles nested paths
  • Metadata parsing accurate
  • Unit tests comprehensive
  • API documented

Estimated Time: 8-10 hours
Priority: Medium
Dependencies: Phases 2, 3 complete


Phase 6: Favorites and Recent Folders (Issue #12)

Goal: Persistence layer for user preferences.

Tasks

  • Create config.hpp interface
  • Implement favorites management:
    • Add favorite folder
    • Remove favorite folder
    • List favorites
    • Reorder favorites
  • Implement recent folders tracking:
    • Auto-track used folders
    • Configurable limit (default: 5)
    • LRU eviction
    • Duplicate detection
  • JSON persistence:
    • Save to file
    • Load from file
    • Handle missing/corrupt files
    • Migration support
  • Platform-specific paths:
    • Linux: ~/.config/nextcloud-share/
    • 3DS: /nextcloud-share/
    • Switch: /switch/nextcloud-share/
  • Write unit tests
  • Document config format

API Design

class Config {
public:
    Config(const std::string& configPath = "");
    
    // Favorites
    void addFavorite(const std::string& path, const std::string& name = "");
    void removeFavorite(const std::string& path);
    std::vector<FolderInfo> getFavorites() const;
    
    // Recent folders
    void addRecentFolder(const std::string& path);
    std::vector<std::string> getRecentFolders() const;
    void setMaxRecentFolders(int count);
    
    // Persistence
    bool load();
    bool save();
};

struct FolderInfo {
    std::string path;
    std::string displayName;
    time_t lastUsed;
};

Acceptance Criteria

  • Favorites persist across restarts
  • Recent folders tracked correctly
  • JSON format clean and readable
  • Handles missing config gracefully
  • Unit tests cover edge cases
  • API documented

Estimated Time: 6-8 hours
Priority: Low
Dependencies: None (standalone)


Phase 7: Testing and Documentation (Issue #13)

Goal: Comprehensive test coverage and documentation.

Tasks

  • Achieve >80% code coverage
  • Integration tests with real Nextcloud:
    • Test against cloud.tomusan.com
    • Test against disobedient.cloud
    • Verify all operations work
  • Mock server for offline testing:
    • Mock HTTP responses
    • Simulate errors
    • Test edge cases
  • Performance testing:
    • Large file uploads
    • Many small files
    • Concurrent operations
  • Generate Doxygen documentation
  • Write architecture document
  • Create usage examples
  • Document build process
  • Add API reference

Documentation Structure

docs/
├── api.md                  # Full API reference
├── architecture.md         # Library design and internals
├── building.md            # Build instructions
├── examples.md            # Usage examples
├── testing.md             # How to run tests
├── contributing.md        # Contribution guidelines
└── changelog.md           # Version history

Acceptance Criteria

  • All classes have Doxygen comments
  • Code coverage >80%
  • Integration tests pass
  • Documentation complete
  • Examples compile and run
  • Ready for platform integration

Estimated Time: 10-12 hours
Priority: High
Dependencies: All phases complete


Issues to Create

Based on this plan, create the following Gitea issues:

Issue: Initialize libnextcloud Project Structure

Labels: library, setup, priority:critical
Description:

Set up the shared library project structure and build system for libnextcloud.

## Tasks
- [ ] Create `shared/` directory structure
- [ ] Set up CMakeLists.txt for library
- [ ] Create version.hpp and types.hpp
- [ ] Set up Google Test framework
- [ ] Create basic README
- [ ] Add pkg-config file generation
- [ ] Verify library compiles standalone

## Dependencies
- libcurl 7.68+
- mbedTLS 2.16+
- tinyxml2 9.0+
- Google Test 1.11+

## Acceptance Criteria
- [ ] CMake builds library successfully
- [ ] Can link against library from test project
- [ ] Version info accessible at runtime
- [ ] Ready for component implementation

Estimated: 4-6 hours
Blocks: #8, #9, #10, #11, #12, #13

Keep Existing Issues (Update Dependencies)

Issue #8: Design and implement WebDAV client

  • Add dependency: "Requires libnextcloud scaffolding (new issue)"
  • Priority: High
  • Estimated: 12-16 hours

Issue #9: Implement authentication system

  • Add dependency: "Requires #8"
  • Priority: High
  • Estimated: 6-8 hours

Issue #10: Implement file upload functionality

  • Add dependency: "Requires #8, #9"
  • Priority: High
  • Estimated: 10-12 hours

Issue #11: Implement folder management

  • Add dependency: "Requires #8, #9"
  • Priority: Medium
  • Estimated: 8-10 hours

Issue #12: Implement favorites and recent folders

  • Priority: Low
  • Estimated: 6-8 hours

Issue #13: Write unit tests for shared library

  • Add dependency: "Requires #8-#12"
  • Priority: High
  • Estimated: 10-12 hours

Build System Design

CMakeLists.txt Structure

cmake_minimum_required(VERSION 3.15)
project(libnextcloud VERSION 0.1.0 LANGUAGES CXX)

# C++17 required
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Library sources
add_library(nextcloud
    src/webdav_client.cpp
    src/auth.cpp
    src/upload_manager.cpp
    src/folder_manager.cpp
    src/config.cpp
)

# Include directories
target_include_directories(nextcloud
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
)

# Dependencies
find_package(CURL REQUIRED)
find_package(MbedTLS REQUIRED)
find_package(tinyxml2 REQUIRED)

target_link_libraries(nextcloud
    PUBLIC
        CURL::libcurl
        MbedTLS::mbedtls
        tinyxml2::tinyxml2
)

# Testing
if(BUILD_TESTING)
    enable_testing()
    add_subdirectory(tests)
endif()

# Install rules
install(TARGETS nextcloud EXPORT nextcloudTargets)
install(DIRECTORY include/ DESTINATION include)
install(EXPORT nextcloudTargets
    FILE nextcloudTargets.cmake
    NAMESPACE nextcloud::
    DESTINATION lib/cmake/nextcloud
)

Platform-Specific Considerations

Nintendo 3DS:

  • Static library only (no shared objects)
  • mbedTLS available via dkp-pacman
  • libcurl with 3DS patches
  • Filesystem: /nextcloud-share/config.json

Nintendo Switch:

  • Static library
  • Standard libcurl and mbedTLS
  • Filesystem: /switch/nextcloud-share/config.json

Linux/PC:

  • Shared library (.so) or static
  • System libcurl and mbedTLS
  • Filesystem: ~/.config/nextcloud-share/config.json

Testing Strategy

Unit Tests

  • Mock all external dependencies (HTTP, filesystem)
  • Test each class in isolation
  • Cover edge cases and error conditions
  • Fast execution (<1 second total)

Integration Tests

  • Real HTTP requests to test Nextcloud servers
  • Require valid credentials from config.json
  • Test full workflows end-to-end
  • Can be skipped if credentials not available

Performance Tests

  • Upload 1GB file and measure time
  • Upload 1000 small files
  • Concurrent uploads
  • Memory usage profiling

Test Configuration

{
  "test": {
    "servers": [
      {
        "name": "tomusan",
        "url": "https://cloud.tomusan.com",
        "username": "test",
        "password": "xxx"
      },
      {
        "name": "disobedient",
        "url": "https://disobedient.cloud/nextcloud",
        "username": "test",
        "password": "xxx"
      }
    ]
  }
}

Timeline Estimate

Total Estimated Time: 56-74 hours

Phase Tasks Estimated Time
1. Scaffolding Project setup 4-6 hours
2. WebDAV Client HTTP/WebDAV implementation 12-16 hours
3. Authentication Auth system 6-8 hours
4. Upload Manager File uploads 10-12 hours
5. Folder Management Folder operations 8-10 hours
6. Favorites/Recent Config persistence 6-8 hours
7. Testing/Docs Tests and docs 10-12 hours

Realistic Timeline: 2-3 weeks working part-time (15-20 hrs/week)


Success Criteria

The library is complete when:

  • All phases implemented and tested
  • Code coverage >80%
  • Integration tests pass with real Nextcloud
  • API documentation complete
  • Examples compile and run
  • Can be integrated into 3DS app
  • Ready for additional platforms (Switch, Wii U, etc.)

Next Steps

  1. Review this plan - Adjust scope, estimates, priorities
  2. Create Gitea issues - One for scaffolding, update existing issues
  3. Start Phase 1 - Set up project structure
  4. Implement phases sequentially - Each phase depends on previous
  5. Test continuously - Don't defer testing to the end

Ready to proceed? Let's create the issues and start building!