Skip to content

Commit 03c2f6e

Browse files
committed
Fix RemoteBrowser password attribute initialization and add verbose logging
- Initialize all attributes in __init__ with default values before reload_settings() - Add try-except error handling in reload_settings() to ensure attributes always exist - Add comprehensive verbose logging to test_connection methods for debugging - Log connection parameters at DEBUG level for troubleshooting - Fix AttributeError: 'RemoteBrowser' object had no attribute 'password' - Add support for shares that don't require passwords - Create AI coding agent instructions for future development
1 parent 2621e52 commit 03c2f6e

4 files changed

Lines changed: 449 additions & 20 deletions

File tree

.github/copilot-instructions.md

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# LibreELEC Backupper - AI Coding Agent Instructions
2+
3+
## Project Overview
4+
**LibreELEC Backupper** is a Kodi addon (service.libreelec.backupper) for automated backup/restore of LibreELEC system configuration, addons, and settings. It supports multiple remote storage protocols (SMB, NFS, FTP, SFTP, WebDAV).
5+
6+
**Key Version:** 1.4.1.5 | **Target:** Kodi 20+ | **Python:** 3.x with xbmc/xbmcaddon modules
7+
8+
---
9+
10+
## Architecture & Critical Patterns
11+
12+
### Component Structure
13+
- **`addon.py`** - Main addon entry point, handles UI actions (backup_now, restore, test_connection, browse_remote)
14+
- **`service.py`** - Background scheduler service that runs backup tasks automatically on schedule
15+
- **`resources/lib/backup_utils.py`** - Core `BackupManager` class handling backup/restore logic
16+
- **`resources/lib/remote_browser.py`** - `RemoteBrowser` class for testing connections and browsing remote shares
17+
- **`resources/lib/email_utils.py`** - `EmailNotifier` for sending backup status notifications
18+
- **`resources/lib/settings_handler.py`** - Settings action handlers
19+
20+
### Critical Data Flows
21+
1. **Backup Creation:** `addon.py` (user request) → `BackupManager.create_backup()` → creates tar.gz → uploads to remote via xbmcvfs
22+
2. **Connection Testing:** `addon.py` (test_connection) → `RemoteBrowser.test_connection_with_params()` → protocol-specific test method
23+
3. **Restore Operation:** `addon.py` (restore) → `BackupManager.restore_backup()` → downloads from remote → extracts → handles mount operations
24+
25+
### Key Classes & Their Attributes
26+
27+
**RemoteBrowser** (CRITICAL - must always initialize these):
28+
```python
29+
self.remote_type # int: 0=SMB, 1=NFS, 2=FTP, 3=SFTP, 4=WebDAV
30+
self.remote_path # str: server/path or server:/path
31+
self.username # str: credentials (can be empty)
32+
self.password # str: credentials (can be empty - THIS IS CRITICAL)
33+
self.port # str: port number (gets default if empty)
34+
self.default_ports # dict: protocol→default port mapping
35+
```
36+
37+
**BackupManager**:
38+
```python
39+
self.backup_dir # str: local backup directory path
40+
self.profile_path # str: Kodi profile path
41+
self.addon # xbmcaddon.Addon instance
42+
self.remote_browser # RemoteBrowser instance
43+
```
44+
45+
---
46+
47+
## Essential Patterns & Conventions
48+
49+
### Logging Standards
50+
- **ALWAYS** use verbose logging at DEBUG level for detailed information
51+
- Use the log pattern: `xbmc.log(f"{ADDON_ID}: Message here", xbmc.LOGINFO|LOGDEBUG|LOGERROR)`
52+
- Log at function entry for debugging flows, connection attempts, and before operations that might fail
53+
- CRITICAL: Remote connection test failures must log all connection parameters for troubleshooting
54+
55+
### Attribute Initialization Requirement
56+
**NEVER** assume attributes exist without initializing them. The `RemoteBrowser` class MUST:
57+
1. Initialize all attributes in `__init__` with default values BEFORE calling `reload_settings()`
58+
2. Wrap `reload_settings()` in try-except in `__init__` to catch and log errors
59+
3. In `reload_settings()`, ensure attributes are set even if exceptions occur during settings load
60+
61+
**Example:**
62+
```python
63+
def __init__(self):
64+
# Initialize with defaults FIRST
65+
self.password = ""
66+
self.remote_path = ""
67+
# Then try to reload
68+
try:
69+
self.reload_settings()
70+
except Exception as e:
71+
xbmc.log(f"Error: {e}", xbmc.LOGERROR)
72+
```
73+
74+
### Remote Connection Testing
75+
- All test methods (`_test_smb_connection`, `_test_nfs_connection`, etc.) must:
76+
- Log connection parameters at DEBUG level
77+
- Wrap operations in try-except with detailed error logging
78+
- Show detailed error messages to users in textviewer dialogs
79+
- Handle credentials being optional (no password required scenarios)
80+
81+
### Path Formatting
82+
- **SMB:** `server/share` or `server/share/subpath` (no smb:// prefix in path storage)
83+
- **NFS:** `server:/export/path` (colon is REQUIRED separating server and path)
84+
- **FTP/SFTP:** `server/path`
85+
86+
### Settings Handling
87+
- Always call `xbmc.executebuiltin('UpdateLocalAddons')` after changing settings in code
88+
- Settings are loaded via `ADDON.getSetting('key')` - returns strings, use int() for type conversion
89+
- Use `reload_settings()` in RemoteBrowser to ensure fresh values from Kodi
90+
91+
---
92+
93+
## Common Bug Patterns & Fixes
94+
95+
### Attribute Error: 'RemoteBrowser' object has no attribute 'password'
96+
**Root Cause:** Attributes not initialized in `__init__` before calling `reload_settings()`
97+
**Fix:** Initialize all attributes with empty defaults in `__init__` BEFORE `reload_settings()`
98+
99+
### NFS Mount Failures
100+
**Common Issues:**
101+
- Path format missing colon (needs `server:/path`, not `server/path`)
102+
- Missing `-o nolock` option in mount command for better compatibility
103+
- No temp mount point cleanup between attempts
104+
105+
**Pattern to follow:**
106+
```python
107+
mount_options = ["-t", "nfs", "-o", "soft,timeo=10,retrans=2,nolock"]
108+
subprocess.call(["mount"] + mount_options + [nfs_path, mount_point])
109+
```
110+
111+
### SMB Path Handling
112+
- When browsing, convert back from protocol format to storage format
113+
- Store as `server/share`, not `smb://server/share`
114+
- Convert to full SMB URL only when connecting: `smb://[user:pass@]server/share`
115+
116+
---
117+
118+
## Development Workflow
119+
120+
### Testing Connection Logic
121+
Use the included `test_fix.py` for unit testing RemoteBrowser without Kodi:
122+
```bash
123+
cd /home/nigel/service.libreelec.backupper
124+
python3 test_fix.py
125+
```
126+
127+
### Key Files to Check Before Changes
128+
- **`addon.xml`** - For addon version, dependencies, and settings metadata
129+
- **`resources/settings.xml`** - For available settings names and defaults
130+
- **`changelog.txt`** - For version history and known issues
131+
- **`service.py`** - To understand scheduler timing logic if modifying backup triggers
132+
133+
### Adding New Remote Protocol Support
134+
1. Add protocol option to `addon.xml` settings
135+
2. Add case handler in `test_connection()` method
136+
3. Create `_test_protocol_connection()` method with proper logging
137+
4. Update `reload_settings()` default_ports dict if needed
138+
5. Update error messages to mention the new protocol
139+
140+
---
141+
142+
## Kodi/LibreELEC Specifics
143+
144+
### Important Module Constants
145+
- `xbmc.LOGINFO, LOGDEBUG, LOGERROR, LOGWARNING` - Log levels
146+
- Settings stored in `xbmc.translatePath(ADDON.getAddonInfo('profile'))`
147+
- Paths use `xbmcvfs.translatePath()` for cross-platform compatibility
148+
149+
### Remote Browsing with xbmcvfs
150+
- SMB: `xbmcvfs.listdir("smb://server/share")` returns `(dirs, files)` tuple
151+
- Local operations use standard `os` module
152+
- Network operations use `xbmcvfs` for Kodi-compatible path handling
153+
154+
### Dialog Types in Code
155+
- `xbmcgui.Dialog().ok()` - Simple message dialogs
156+
- `xbmcgui.Dialog().textviewer()` - Scrollable text display (use for connection test results)
157+
- `xbmcgui.DialogProgress()` - Progress dialog with `.create()`, `.update()`, `.close()`
158+
159+
---
160+
161+
## Performance & Reliability Considerations
162+
163+
1. **Connection Tests** - Always provide timeout handling; use low timeouts for remote tests
164+
2. **Large Backups** - Show progress dialogs; allow user cancellation
165+
3. **Path Validation** - Validate paths exist and are accessible before creating backups
166+
4. **Error Recovery** - Clean up temp mount points, temp files on exception
167+
5. **Settings Persistence** - Always reload settings before operations; settings may change in settings UI
168+
169+
---
170+
171+
## DO NOT DO
172+
173+
- ❌ Assume attributes exist without initializing them
174+
- ❌ Use unescaped passwords in logs (log "Set" or "Not Set" instead)
175+
- ❌ Forget to call `xbmc.executebuiltin('UpdateLocalAddons')` after setting changes
176+
- ❌ Mix smb:// protocol prefix in stored paths (store as server/share only)
177+
- ❌ Mount NFS without the `nolock` option
178+
- ❌ Leave temp mount points or test directories without cleanup
179+
- ❌ Show detailed error messages without logging the same details to xbmc.log

.github/instructions/libreelec-addon-development.instructions.md

Whitespace-only changes.

0 commit comments

Comments
 (0)