machineconfig 5.45__py3-none-any.whl → 5.47__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of machineconfig might be problematic. Click here for more details.

@@ -0,0 +1,49 @@
1
+
2
+ # locations to be backed up to the cloud.
3
+
4
+ [thunderbird_windows]
5
+ path = '~/AppData/Roaming/Thunderbird/Profiles'
6
+ encrypt = 'True'
7
+ zip = 'True'
8
+ rel2home = 'True'
9
+ os_specific = 'True'
10
+
11
+
12
+ [thunderbird_linux]
13
+ path = '~/.thunderbird'
14
+ encrypt = 'True'
15
+ zip = 'True'
16
+ rel2home = 'True'
17
+ os_specific = 'True'
18
+
19
+
20
+ [zoxide_windows]
21
+ path = '~/AppData/Local/zoxide/db.zo'
22
+ encrypt = 'False'
23
+ zip = 'False'
24
+ rel2home = 'True'
25
+ os_specific = 'True'
26
+
27
+
28
+ [zoxide_linux]
29
+ path = '~/.local/share/zoxide/db.zo'
30
+ encrypt = 'False'
31
+ zip = 'False'
32
+ rel2home = 'True'
33
+ os_specific = 'True'
34
+
35
+
36
+ #[dotfiles]
37
+ # path = '~/dotfiles'
38
+ # encrypt = 'True'
39
+ # zip = 'True'
40
+ # rel2home = 'True'
41
+ # os_specific = 'True'
42
+
43
+
44
+ [ipython]
45
+ path = '~/.ipython'
46
+ encrypt = 'True'
47
+ zip = 'True'
48
+ rel2home = 'True'
49
+ os_specific = 'False'
@@ -0,0 +1,11 @@
1
+
2
+ # Non-login shells, .bashrc > .profile are read.
3
+ # for login shells, e.g. SSH, .bash_login > .bash_profile > .profile is read.
4
+
5
+ # The strategy to ensure consistent configuration for login and nonlogin shells is to put all the configuration in .bashrc, and then source it from .bash_profile and .profile.
6
+
7
+ # ensure .bash_profile only calls .profile
8
+ # ensure .profile calls .bashrc only at the end.
9
+
10
+ When you login: /etc/profile -> ~/.profile -> ~/.bash_profile -> ~/.bashrc
11
+ When you open a new terminal: ~/.bashrc
@@ -0,0 +1,268 @@
1
+
2
+
3
+ # =================== PRIVATE ================================
4
+
5
+ [git]
6
+ gitconfig = {this = '~/.gitconfig', to_this = '~/dotfiles/creds/git/.gitconfig'}
7
+ gitcred = {this = '~/.git-credentials', to_this = '~/dotfiles/creds/git/.git-credentials'}
8
+
9
+ [ssh]
10
+ keys = {this = '~/.ssh', to_this = '~/dotfiles/creds/.ssh', contents = true}
11
+
12
+ [pypi]
13
+ creds = {this = '~/.pypirc', to_this = '~/dotfiles/creds/msc/.pypirc'}
14
+
15
+ [rclone_linux]
16
+ config = {this = '~/.config/rclone/rclone.conf', to_this = '~/dotfiles/creds/rclone/rclone.conf'}
17
+
18
+ [rclone_windows]
19
+ config = {this = '~/AppData/Roaming/rclone/rclone.conf', to_this = '~/dotfiles/creds/rclone/rclone.conf'}
20
+
21
+ [cloudflare]
22
+ config = {this = '~/.cloudflared', to_this = '~/dotfiles/creds/cloudflare/.cloudflared'}
23
+
24
+ [ngrok_linux]
25
+ config = {this = '~/.config/ngrok/ngrok.yml', to_this = '~/dotfiles/creds/tokens/ngrok.yml'}
26
+
27
+ [ngrok_windows]
28
+ config = {this = '~/AppData/Local/ngrok/ngrok.yml', to_this = '~/dotfiles/creds/tokens/ngrok.yml'}
29
+
30
+ [m365]
31
+ config1 = {this = '~/.cli-m365-msal.json', to_this = '~/dotfiles/creds/tokens/.cli-m365-msal.json'}
32
+ config2 = {this = '~/.cli-m365-all-connections.json', to_this = '~/dotfiles/creds/tokens/.cli-m365-all-connections.json'}
33
+ config3 = {this = '~/.cli-m365-connection.json', to_this = '~/dotfiles/creds/tokens/.cli-m365-connection.json'}
34
+ # config2 = {this = '~/.cli-m365-tokens.json', to_this = '~/dotfiles/creds/tokens/.cli-m365-tokens.json'}
35
+
36
+ [bash_linux]
37
+ bashrc = {this = '~/.inputrc', to_this = '~/dotfiles/shells/bash/.inputrc'}
38
+ [remmina]
39
+ data = {this = '~/.var/app/org.remmina.Remmina/data/remmina', to_this = '~/dotfiles/creds/RDP/remmina/data/remmina'}
40
+
41
+ [webapp_linux]
42
+ brave = {this = '~/.local/share/applications', to_this = '~/dotfiles/config/webapps/linux/brave', contents = true}
43
+
44
+ # [startup_windows]
45
+ # startup = {this = '~/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup', to_this = '~/dotfiles/scripts/windows_startup', contents = true}
46
+
47
+ # [aws]
48
+ # config = {this = '~/.aws/config', to_this = '~/dotfiles/aws/.aws', contents = true}
49
+
50
+ [wt_windows]
51
+ settings = { this = '~/AppData/Local/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState/settings.json', to_this = 'CONFIG_ROOT/settings/shells/wt/settings.json' }
52
+
53
+ # [wsl_windows]
54
+ # home = {this = '~/wsl', to_this = '\\wsl.localhost\Ubuntu-22.04\home\username'}
55
+ # see \\wsl$ and ~\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState
56
+ # config = {this = '~/.wslconfig', to_this = 'CONFIG_ROOT/settings/wsl/.wslconfig'}
57
+
58
+ # [wsl_linux]
59
+ # home = {this = '~/win', to_this = '/mnt/c/Users/username'}
60
+
61
+
62
+ # =================== LLMs ============================
63
+
64
+ [chatgpt]
65
+ config = { this = '~/.config/chatgpt/config.json', to_this = '~/dotfiles/creds/llm/chatgpt_cli/config.json' }
66
+
67
+ [mods]
68
+ config = {this = '~/.config/mods/mods.yml', to_this = '~/dotfiles/creds/llm/mods_cli/mods.yml'}
69
+
70
+ [github_cli_token]
71
+ token = {this = '~/.copilot-cli-access-token', to_this = '~/dotfiles/creds/llm/github_cli/.copilot-cli-access-token'}
72
+
73
+ [aider]
74
+ config = {this = '~/.aider.conf.yml', to_this = '~/dotfiles/creds/llm/aider/.aider.conf.yml'}
75
+
76
+ [marvin]
77
+ config = {this = '~/.marvin/.env', to_this = '~/dotfiles/creds/llm/marvin/.env'}
78
+ threads = {this = '~/.marvin/cli/threads/default.json', to_this = '~/dotfiles/creds/llm/marvin/threads/default.json'}
79
+
80
+ [docker]
81
+ config = {this = '~/.docker/config.json', to_this = '~/dotfiles/creds/docker/config.json'}
82
+
83
+
84
+ # =========================== PUBLIC ======================================
85
+
86
+ [presenterm]
87
+ config = {this = '~/.config/presenterm/config.yaml', to_this = 'CONFIG_ROOT/settings/presenterm/config.yaml'}
88
+
89
+ [keras]
90
+ config = {this = '~/.keras/keras.json', to_this = 'CONFIG_ROOT/settings/keras/keras.json'}
91
+
92
+ [streamlit]
93
+ config = {this = '~/.streamlit/config.toml', to_this = 'CONFIG_ROOT/settings/streamlit/config.toml'}
94
+
95
+
96
+ [procs]
97
+ config = {this = '~/.procs.toml', to_this = 'CONFIG_ROOT/settings/procs/.procs.toml'}
98
+ config_again = {this = '~/.config/procs/config.toml', to_this = 'CONFIG_ROOT/settings/procs/.procs.toml'}
99
+
100
+ [rofi_linux]
101
+ config = {this = '~/.config/rofi/config.rasi', to_this = 'CONFIG_ROOT/settings/rofi/config.rasi'}
102
+
103
+ [yazi_windows]
104
+ yazi = {this = '~/AppData/Roaming/yazi/config/yazi.toml', to_this = 'CONFIG_ROOT/settings/yazi/yazi.toml'}
105
+ keymap = {this = '~/AppData/Roaming/yazi/config/keymap.toml', to_this = 'CONFIG_ROOT/settings/yazi/keymap.toml'}
106
+ theme = {this = '~/AppData/Roaming/yazi/config/theme.toml', to_this = 'CONFIG_ROOT/settings/yazi/theme.toml'}
107
+
108
+ [yazi_linux]
109
+ yazi = {this = '~/.config/yazi/yazi.toml', to_this = 'CONFIG_ROOT/settings/yazi/yazi.toml'}
110
+ keymap = {this = '~/.config/yazi/keymap.toml', to_this = 'CONFIG_ROOT/settings/yazi/keymap.toml'}
111
+ theme = {this = '~/.config/yazi/theme.toml', to_this = 'CONFIG_ROOT/settings/yazi/theme.toml'}
112
+
113
+ [lf_windows]
114
+ config = {this = '~/AppData/Local/lf/lfrc', to_this = 'CONFIG_ROOT/settings/lf/windows/lfrc'}
115
+ colors = {this = '~/AppData/Local/lf/colors', to_this = 'CONFIG_ROOT/settings/lf/windows/colors'}
116
+ icons = {this = '~/AppData/Local/lf/icons', to_this = 'CONFIG_ROOT/settings/lf/windows/icons'}
117
+
118
+ [lf_linux]
119
+ colors = {this = '~/.config/lf/colors', to_this = 'CONFIG_ROOT/settings/lf/linux/colors'}
120
+ config = {this = '~/.config/lf/lfrc', to_this = 'CONFIG_ROOT/settings/lf/linux/lfrc'}
121
+ icons = {this = '~/.config/lf/icons', to_this = 'CONFIG_ROOT/settings/lf/linux/icons'}
122
+
123
+ [broot]
124
+ config = {this = '~/.config/broot/conf.toml', to_this = 'CONFIG_ROOT/settings/broot/conf.toml'}
125
+
126
+ [pistol_linux]
127
+ config = {this = '~/.config/pistol/pistol.conf', to_this = 'CONFIG_ROOT/settings/pistol/pistol.conf'}
128
+
129
+ [glow]
130
+ config = {this = '~/.config/glow/glow.yml', to_this = 'CONFIG_ROOT/settings/glow/glow.yml'}
131
+
132
+ [gromit_linux]
133
+ config = {this = '~/.var/app/net.christianbeier.Gromit-MPX/config/gromit-mpx.cfg', to_this = 'CONFIG_ROOT/settings/gromit-mpx/gromit-mpx.cfg', copy = true}
134
+
135
+ # zoxide can't read symlink files see: https://github.com/ajeetdsouza/zoxide/issues?q=is%3Aissue+is%3Aopen+symlink
136
+ # [zoxide_windows]
137
+ # database = {this = '~/AppData/Local/zoxide/db.zo', to_this = '~/dotfiles/settings/zoxide_windows/db.zo'}
138
+
139
+ # [zoxide_linux]
140
+ # database = {this = '~/.local/share/zoxide/db.zo', to_this = '~/dotfiles/settings/zoxide_linux/db.zo'}
141
+
142
+ #[broot_windows]
143
+ #config = { this = '~/AppData/Roaming/dystroy/config', to_this = 'CONFIG_ROOT/settings/broot/config' }
144
+
145
+ [starship]
146
+ config = {this = '~/.config/starship.toml', to_this = 'CONFIG_ROOT/settings/shells/starship/starship.toml'}
147
+
148
+
149
+ [kanata]
150
+ config = {this = '~/.config/kanata/kanata.kbd', to_this = 'CONFIG_ROOT/settings/keyboard/kanata/kanata.kbd'}
151
+
152
+ [espanso]
153
+ config = {this = '~/.config/espanso/config/default.yml', to_this = 'CONFIG_ROOT/settings/keyboard/espanso/config/default.yml'}
154
+ match = {this = '~/.config/espanso/match/base.yml', to_this = 'CONFIG_ROOT/settings/keyboard/espanso/match/base.yml', copy = true}
155
+
156
+
157
+ [pudb]
158
+ config = {this = '~/.config/pudb/pudb.cfg', to_this = 'CONFIG_ROOT/settings/pudb/pudb.cfg'}
159
+
160
+
161
+ # ============================= shells profiles ==================================
162
+
163
+ # [powershell_windows]
164
+ # CurrentUserCurrentHost = {this = '~/Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1', to_this = '~/dotfiles/shells/windows_powershell/CurrentUserCurrentHost/Microsoft.PowerShell_profile.ps1'}
165
+ # CurrentUserAllHosts = {this = '~/Documents\WindowsPowerShell\profile.ps1', to_this = '~/dotfiles/shells/windows_powershell/CurrentUserAllHosts/profile.ps1'}
166
+ # AllUsersCurrentHost = {this = 'C:\Windows\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1', to_this = '~/dotfiles/shells/powershell/AllUsersCurrentHost/Microsoft.PowerShell_profile.ps1'}
167
+ # AllUsersAllHosts = {this = 'C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1', to_this = '~/dotfiles/shells/windows_powershell/AllUsersAllHosts/profile.ps1'}
168
+
169
+ [pwsh_windows]
170
+ CurrentUserCurrentHost = {this = '~/Documents/PowerShell/Microsoft.PowerShell_profile.ps1', to_this = 'CONFIG_ROOT/settings/shells/pwsh/init.ps1'}
171
+ CurrentUserAllHosts = {this = '~/Documents/PowerShell/profile.ps1', to_this = 'CONFIG_ROOT/settings/shells/pwsh/profile.ps1'}
172
+ AllUsersCurrentHost = {this = 'C:\Program Files\PowerShell\7\Microsoft.PowerShell_profile.ps1', to_this = 'CONFIG_ROOT/settings/shells/pwsh/init.ps1'}
173
+ AllUsersAllHosts = {this = 'C:\Program Files\PowerShell\7\profile.ps1', to_this = 'CONFIG_ROOT/settings/shells/pwsh/init.ps1'}
174
+
175
+ [nushell_windows]
176
+ config = {this = '~/AppData/Roaming/nushell/config.nu', to_this = 'CONFIG_ROOT/settings/shells/nushell/config.nu'}
177
+ env = {this = '~/AppData/Roaming/nushell/env.nu', to_this = 'CONFIG_ROOT/settings/shells/nushell/env.nu'}
178
+
179
+ [nushell_linux]
180
+ config = {this = '~/.config/nushell/config.nu', to_this = 'CONFIG_ROOT/settings/shells/nushell/config.nu'}
181
+ env = {this = '~/.config/nushell/env.nu', to_this = 'CONFIG_ROOT/settings/shells/nushell/env.nu'}
182
+
183
+ [kitty_linux]
184
+ config = {this = '~/.config/kitty/kitty.conf', to_this = 'CONFIG_ROOT/settings/shells/kitty/kitty.conf'}
185
+
186
+ [alacritty_linux]
187
+ config = {this = '~/.config/alacritty/alacritty.toml', to_this = 'CONFIG_ROOT/settings/shells/alacritty/alacritty.toml'}
188
+ config_yaml = {this = '~/.config/alacritty/alacritty.yml', to_this = 'CONFIG_ROOT/settings/shells/alacritty/alacritty.yml'}
189
+
190
+ [alacritty_windows]
191
+ config = {this = '~/AppData/Roaming/alacritty/alacritty.toml', to_this = 'CONFIG_ROOT/settings/shells/alacritty/alacritty.toml'}
192
+
193
+ [hyper_terminal]
194
+ config = {this = '~/.hyper.js', to_this = 'CONFIG_ROOT/settings/shells/hyper/.hyper.js'}
195
+
196
+ [wezterminal]
197
+ config = {this = '~/.config/wezterm/wezterm.lua', to_this = 'CONFIG_ROOT/settings/shells/wezterm/wezterm.lua'}
198
+
199
+ [vtm_windows]
200
+ settings = {this = '~/.config/vtm/settings.xml', to_this = 'CONFIG_ROOT/settings/shells/vtm/settings.xml'}
201
+
202
+ # [ipython_default_config]
203
+ # config = {this = '~/.ipython/profile_default/ipython_config.py', to_this = 'CONFIG_ROOT/settings/shells/ipy/profiles/default/ipython_config.py'}
204
+ # play_extension = {this = '~/.ipython/profile_default/startup/playext.py', to_this = 'CONFIG_ROOT/settings/shells/ipy/profiles/default/startup/playext.py'}
205
+
206
+ [mprocs_windows]
207
+ config = {this = '~/mprocs.yaml', to_this = 'CONFIG_ROOT/settings/mprocs/windows/mprocs.yaml'}
208
+
209
+ # [tmux_linux]
210
+ # config = {this = '~/.tmux.conf', to_this = 'CONFIG_ROOT/settings/tmux/.tmux.conf'}
211
+ # tmate = {this = '~/.tmate.conf', to_this = 'CONFIG_ROOT/settings/tmux/.tmate.conf'}
212
+
213
+
214
+ [zellij_linux]
215
+ config = { this = '~/.config/zellij', to_this = 'CONFIG_ROOT/settings/zellij' }
216
+ #themes = { this = '~/.config/zellij/themes', to_this = 'CONFIG_ROOT/settings/zellij/themes' }
217
+ #layouts = { this = '~/.config/zellij/layouts', to_this = 'CONFIG_ROOT/settings/zellij/layouts' }
218
+
219
+
220
+ # ===================== IDEs ============================
221
+
222
+ [zed_linux]
223
+ settings = {this = '~/.config/zed/settings.json', to_this = 'CONFIG_ROOT/settings/zed/settings.json'}
224
+
225
+ [helix_windows]
226
+ languages = { this = '~/AppData/Roaming/helix/languages.toml', to_this = 'CONFIG_ROOT/settings/helix/languages.toml' }
227
+ config = { this = '~/AppData/Roaming/helix/config.toml', to_this = 'CONFIG_ROOT/settings/helix/config.toml' }
228
+
229
+ [helix_linux]
230
+ languages = { this = '~/.config/helix/languages.toml', to_this = 'CONFIG_ROOT/settings/helix/languages.toml' }
231
+ config = { this = '~/.config/helix/config.toml', to_this = 'CONFIG_ROOT/settings/helix/config.toml' }
232
+
233
+ [lvim_windows]
234
+ config = { this = '~/AppData/Local/lvim/config.lua', to_this = 'CONFIG_ROOT/settings/lvim/windows/config.lua' }
235
+
236
+ [lvim_linux]
237
+ config = { this = '~/.config/lvim/config.lua', to_this = 'CONFIG_ROOT/settings/lvim/linux/config.lua' }
238
+
239
+
240
+ [svim_windows]
241
+ init = { this = '~/.SpaceVim.d/init.toml', to_this = 'CONFIG_ROOT/settings/svim/windows/init.toml' }
242
+
243
+ [svim_linux]
244
+ init = { this = '~/.SpaceVim.d/init.toml', to_this = 'CONFIG_ROOT/settings/svim/linux/init.toml' }
245
+
246
+ [linters]
247
+ flake8 = {this = '~/.flake8', to_this = 'CONFIG_ROOT/settings/linters/.flake8'}
248
+ # as per https://mypy.readthedocs.io/en/stable/config_file.html
249
+ mypy = {this = '~/mypy/config/mypy.ini', to_this = 'CONFIG_ROOT/settings/linters/.mypy.ini'}
250
+ mypy2 = {this = '~/.config/mypy/config', to_this = 'CONFIG_ROOT/settings/linters/.mypy.ini'}
251
+ ruff = {this = '~/.ruff.toml', to_this = 'CONFIG_ROOT/settings/linters/.ruff.toml'}
252
+ pylint = {this = '~/.pylintrc', to_this = 'CONFIG_ROOT/settings/linters/.pylintrc'}
253
+
254
+ # ======================= OS ===============================
255
+
256
+ [apps_windows]
257
+ notepadpp = {this = '~/AppData/Local/Microsoft/WindowsApps/notepad++.exe', to_this = 'C:/Program Files/Notepad++/notepad++.exe'}
258
+ # tesseract = {this = '~/AppData/Local/Microsoft/WindowsApps/tesseract.exe', to_this = '~/AppData/Local/Tesseract-OCR/tesseract.exe'} # doesn't work without whole installation dir is on PATH.
259
+
260
+
261
+ [scripts_linux]
262
+ public = {this = '~/scripts', to_this = 'CONFIG_ROOT/scripts/linux'}
263
+
264
+ [scripts_windows]
265
+ public = {this = '~/scripts', to_this = 'CONFIG_ROOT/scripts/windows'}
266
+
267
+
268
+
@@ -0,0 +1,92 @@
1
+
2
+ <#
3
+ .SYNOPSIS
4
+ Restores a Thunderbird profile from a backup.
5
+
6
+ .DESCRIPTION
7
+ This script automates the restoration of a Thunderbird profile. It finds the
8
+ default backup profile located in ~/.thunderbird and copies its contents to
9
+ the active Thunderbird profile folder in AppData/Roaming.
10
+
11
+ WARNING: This script will overwrite the current active Thunderbird profile.
12
+ Ensure Thunderbird is closed before running.
13
+ #>
14
+
15
+ # --- Configuration ---
16
+ $ErrorActionPreference = "Stop"
17
+
18
+ # --- Script ---
19
+
20
+ # 1. Define the root paths for backup and active profiles
21
+ $thunderbirdBackupRoot = "$env:USERPROFILE\.thunderbird"
22
+ $thunderbirdAppdataRoot = "$env:APPDATA\Thunderbird"
23
+
24
+ Write-Host "Thunderbird Profile Restore Script"
25
+ Write-Host "-----------------------------------"
26
+
27
+ # 2. Find the default profile path from the backup's profiles.ini
28
+ try {
29
+ $backupIniPath = Join-Path $thunderbirdBackupRoot "profiles.ini"
30
+ $backupProfileRelativePath = (Get-Content $backupIniPath | Select-String -Pattern '^Path=' | Select-Object -First 1) -replace '^Path=', ''
31
+ $backupProfileFullPath = Join-Path $thunderbirdBackupRoot $backupProfileRelativePath
32
+ Write-Host "Found backup profile: $backupProfileFullPath" -ForegroundColor Green
33
+ }
34
+ catch {
35
+ Write-Error "Could not find or read the backup profiles.ini at '$backupIniPath'."
36
+ exit 1
37
+ }
38
+
39
+ # 3. Find the default profile path from the active installation's profiles.ini
40
+ try {
41
+ $activeIniPath = Join-Path $thunderbirdAppdataRoot "profiles.ini"
42
+ $activeProfileRelativePath = (Get-Content $activeIniPath | Select-String -Pattern '^Path=' | Select-Object -First 1) -replace '^Path=', ''
43
+ $activeProfileFullPath = Join-Path $thunderbirdAppdataRoot $activeProfileRelativePath
44
+ Write-Host "Found active profile: $activeProfileFullPath" -ForegroundColor Green
45
+ }
46
+ catch {
47
+ Write-Error "Could not find or read the active profiles.ini at '$activeIniPath'."
48
+ exit 1
49
+ }
50
+
51
+ # 4. Safety Check: Confirm both profile paths exist
52
+ if (-not (Test-Path -Path $backupProfileFullPath -PathType Container)) {
53
+ Write-Error "Backup profile directory does not exist: $backupProfileFullPath"
54
+ exit 1
55
+ }
56
+ if (-not (Test-Path -Path $activeProfileFullPath -PathType Container)) {
57
+ Write-Error "Active profile directory does not exist: $activeProfileFullPath"
58
+ exit 1
59
+ }
60
+
61
+ # 5. CRITICAL: Get user confirmation before proceeding
62
+ Write-Warning "This will completely overwrite the profile at '$activeProfileFullPath' with the contents of the backup."
63
+ $confirmation = Read-Host "Are you absolutely sure you want to continue? (y/n)"
64
+
65
+ if ($confirmation -ne 'y') {
66
+ Write-Host "Operation cancelled by user." -ForegroundColor Yellow
67
+ exit 0
68
+ }
69
+
70
+ # 6. Ensure Thunderbird is not running
71
+ Write-Host "Checking for running Thunderbird process..."
72
+ $thunderbirdProcess = Get-Process thunderbird -ErrorAction SilentlyContinue
73
+ if ($thunderbirdProcess) {
74
+ Write-Host "Closing Thunderbird to prevent file conflicts..."
75
+ Stop-Process -InputObject $thunderbirdProcess -Force
76
+ Start-Sleep -Seconds 3 # Give it a moment to close gracefully
77
+ } else {
78
+ Write-Host "Thunderbird is not running. Good."
79
+ }
80
+
81
+ # 7. Copy the backup profile to the active profile directory using robocopy
82
+ Write-Host "Starting profile restoration... (This may take a while)"
83
+ try {
84
+ robocopy $backupProfileFullPath $activeProfileFullPath /MIR /E /IS /IT /NFL /NDL /NJH /NJS /nc /ns /np
85
+ Write-Host "Profile restoration complete!" -ForegroundColor Green
86
+ Write-Host "You can now start Thunderbird."
87
+ }
88
+ catch {
89
+ Write-Error "An error occurred during the file copy operation."
90
+ exit 1
91
+ }
92
+
@@ -0,0 +1,139 @@
1
+ # OneDrive API without rclone
2
+
3
+ This module provides direct OneDrive integration using Microsoft Graph API without requiring rclone.
4
+
5
+ ## Features
6
+
7
+ - ✅ Automatic token refresh when expired
8
+ - ✅ Persistent token storage
9
+ - ✅ Upload/download files with progress tracking
10
+ - ✅ Support for large file uploads (chunked)
11
+ - ✅ Direct OAuth2 authentication setup
12
+
13
+ ## Quick Start
14
+
15
+ ### Option 1: Direct OAuth Setup (Recommended)
16
+
17
+ 1. **Set up Azure App Registration:**
18
+ - Go to [Azure Portal](https://portal.azure.com)
19
+ - Navigate to 'Azure Active Directory' > 'App registrations'
20
+ - Click 'New registration'
21
+ - Name: 'OneDrive API Access'
22
+ - Redirect URI: `http://localhost:8080/callback`
23
+ - Add permissions: `Files.ReadWrite.All` and `offline_access`
24
+
25
+ 2. **Set environment variables:**
26
+ ```bash
27
+ export ONEDRIVE_CLIENT_ID='your_client_id_here'
28
+ export ONEDRIVE_REDIRECT_URI='http://localhost:8080/callback'
29
+ ```
30
+
31
+ 3. **Run initial setup:**
32
+ ```python
33
+ from transaction import setup_oauth_authentication
34
+ setup_oauth_authentication()
35
+ ```
36
+
37
+ ### Option 2: Using existing rclone token
38
+
39
+ If you already have rclone configured, the system will automatically use and refresh your existing tokens.
40
+
41
+ ## Usage Examples
42
+
43
+ ```python
44
+ from transaction import push_to_onedrive, pull_from_onedrive
45
+
46
+ # Upload a file
47
+ success = push_to_onedrive('/path/to/local/file.pdf', '/Documents/file.pdf')
48
+
49
+ # Download a file
50
+ success = pull_from_onedrive('/Documents/file.pdf', '/path/to/local/downloaded.pdf')
51
+ ```
52
+
53
+ ## Token Management
54
+
55
+ ### Automatic Token Refresh
56
+
57
+ The system automatically handles token refresh:
58
+
59
+ ```python
60
+ from transaction import get_access_token
61
+
62
+ # This will automatically refresh if expired
63
+ token = get_access_token()
64
+ ```
65
+
66
+ ### Manual Token Operations
67
+
68
+ ```python
69
+ from transaction import refresh_access_token, save_token_to_file, load_token_from_file
70
+
71
+ # Manually refresh token
72
+ new_token = refresh_access_token()
73
+
74
+ # Save token to file
75
+ save_token_to_file(token_data)
76
+
77
+ # Load token from file
78
+ token_data = load_token_from_file()
79
+ ```
80
+
81
+ ## How Token Renewal Works
82
+
83
+ 1. **Automatic Detection**: The system checks token expiry before each API call
84
+ 2. **Refresh Attempt**: If expired, it automatically uses the refresh token to get a new access token
85
+ 3. **Persistent Storage**: New tokens are saved to `~/.onedrive_token.json` for future use
86
+ 4. **Fallback**: If refresh fails, it provides clear instructions for manual intervention
87
+
88
+ ## No rclone Required
89
+
90
+ This implementation eliminates the need for rclone by:
91
+
92
+ - Using Microsoft Graph API directly
93
+ - Implementing OAuth2 flow natively
94
+ - Managing token lifecycle automatically
95
+ - Providing persistent token storage
96
+
97
+ ## Error Handling
98
+
99
+ The system gracefully handles various scenarios:
100
+
101
+ - Expired tokens → Automatic refresh
102
+ - Network errors → Detailed error messages
103
+ - Missing permissions → Clear setup instructions
104
+ - Invalid tokens → Step-by-step recovery guide
105
+
106
+ ## Files Created
107
+
108
+ - `~/.onedrive_token.json`: Encrypted token storage (chmod 600)
109
+ - Token is automatically loaded on import
110
+
111
+ ## Security
112
+
113
+ - Tokens are stored with restrictive permissions (600)
114
+ - Client secrets are optional (public client mode supported)
115
+ - Refresh tokens are securely managed
116
+ - No sensitive data in logs
117
+
118
+ ## Troubleshooting
119
+
120
+ ### Token Refresh Failed
121
+ ```python
122
+ # Try manual refresh
123
+ from transaction import refresh_access_token
124
+ token = refresh_access_token()
125
+
126
+ # Or re-run OAuth setup
127
+ from transaction import setup_oauth_authentication
128
+ setup_oauth_authentication()
129
+ ```
130
+
131
+ ### Permission Errors
132
+ Make sure your Azure app has the correct permissions:
133
+ - `Files.ReadWrite.All` (Delegated)
134
+ - `offline_access` (Delegated)
135
+
136
+ ### Network Issues
137
+ Check your firewall allows connections to:
138
+ - `https://login.microsoftonline.com`
139
+ - `https://graph.microsoft.com`
@@ -121,6 +121,13 @@ def symlink_map(config_file_default_path: PathExtended, self_managed_config_file
121
121
  action_taken = ""
122
122
  details = ""
123
123
 
124
+ # Handle broken symlinks first - they exist as symlinks but point to non-existent targets
125
+ if config_file_default_path.is_symlink() and not config_file_default_path.exists():
126
+ action_taken = "fixing_broken_link"
127
+ details = "Removed broken symlink and will create new one"
128
+ console.print(Panel(f"🔄 FIXING BROKEN LINK | Removing broken symlink {config_file_default_path}, will create link to {self_managed_config_file_path}", title="Fixing Broken Link", expand=False))
129
+ config_file_default_path.unlink()
130
+
124
131
  # Case analysis based on docstring
125
132
  if config_file_default_path.exists():
126
133
  if self_managed_config_file_path.exists():
@@ -238,6 +245,13 @@ def copy_map(config_file_default_path: PathExtended, self_managed_config_file_pa
238
245
  action_taken = ""
239
246
  details = ""
240
247
 
248
+ # Handle broken symlinks first - they exist as symlinks but point to non-existent targets
249
+ if config_file_default_path.is_symlink() and not config_file_default_path.exists():
250
+ action_taken = "fixing_broken_link"
251
+ details = "Removed broken symlink and will copy new file"
252
+ console.print(Panel(f"🔄 FIXING BROKEN LINK | Removing broken symlink {config_file_default_path}, will copy from {self_managed_config_file_path}", title="Fixing Broken Link", expand=False))
253
+ config_file_default_path.unlink()
254
+
241
255
  match (config_file_default_path.exists(), self_managed_config_file_path.exists()):
242
256
  case (True, True):
243
257
  # Both files exist
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machineconfig
3
- Version: 5.45
3
+ Version: 5.47
4
4
  Summary: Dotfiles management package
5
5
  Author-email: Alex Al-Saffar <programmer@usa.com>
6
6
  License: Apache 2.0
@@ -92,15 +92,19 @@ machineconfig/jobs/windows/archive/openssh-server_copy-ssh-id.ps1,sha256=-7pElYi
92
92
  machineconfig/jobs/windows/msc/cli_agents.bat,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
93
  machineconfig/jobs/windows/msc/cli_agents.ps1,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
94
  machineconfig/profile/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
+ machineconfig/profile/backup.toml,sha256=Hb25sIdKVvLqOF62NgiOpGZxd45I6IhsNHu623RtfQQ,766
96
+ machineconfig/profile/bash_shell_profiles.md,sha256=mio0xkMTwO-F3fikWIfgcdQaPCmQrmkxJMNtZsTe9TI,514
95
97
  machineconfig/profile/create_helper.py,sha256=IKUspFNg4LDeQO4t3elt9rI9Hhi8b37ZHqBkyBNU6Qk,1018
96
98
  machineconfig/profile/create_links.py,sha256=yBqfcujukllbHI1P8M5XDbLXMZ_gb38ZvQK901EPbaA,13962
97
99
  machineconfig/profile/create_links_export.py,sha256=OEmuJE-F7FZX5xvOl1rqJzHg_BWtPKCiWdrq4RPOobs,3173
98
100
  machineconfig/profile/create_shell_profile.py,sha256=ifsEAK90ovvY7ftyxuY5-Xh8f2JuQYX7IMYUXp6x2Sw,9538
101
+ machineconfig/profile/mapper.toml,sha256=oXWCWF8yyVHC8FncFqTPiRGgdHAhgGbpS4tYAjKlw3I,12886
99
102
  machineconfig/profile/records/generic/shares.toml,sha256=FduDztfyQtZcr5bfx-RSKhEEweweQSWfVXkKWnx8hCY,143
100
103
  machineconfig/profile/records/linux/apps_summary_report.csv,sha256=pw9djvaRUPalKDLn2sl3odcbD2_Zx3aEupsQ8UPfaaY,2738
101
104
  machineconfig/profile/records/linux/apps_summary_report.md,sha256=l77oofA6Rliql0ZgKGIZi8bstFoGyyGTxeS8p2PtOj0,5634
102
105
  machineconfig/profile/records/windows/apps_summary_report.csv,sha256=nN5BoACBqXgKNczm2t5KaCLdDnxFCIscX8iRkWBm0a4,47
103
106
  machineconfig/profile/records/windows/apps_summary_report.md,sha256=O5hmAcpObaLmOjYLvHg9kkPJryqFwFaP8OsmfPwfR1o,137
107
+ machineconfig/scripts/Restore-ThunderbirdProfile.ps1,sha256=HYIT48vW_E86QJq7RqfWAV06ZAMqjiZS8EDSET11Y04,3605
104
108
  machineconfig/scripts/__init__.py,sha256=v0cMjnaIo39C3ltLiTf1S0fCTMAqWtEU7zrVenUj4PQ,71
105
109
  machineconfig/scripts/linux/fzf2g,sha256=YK_YLmxCm6zms24ytylgoUHnvWqq8oTdRTiskzDClS0,831
106
110
  machineconfig/scripts/linux/fzfag,sha256=x0rX7vM_YjKLZ822D2Xh0HdaTj5kR_gG3g_5_w6ring,679
@@ -366,7 +370,7 @@ machineconfig/utils/accessories.py,sha256=W_9dLzjwNTW5JQk_pe3B2ijQ1nA2-8Kdg2r7VB
366
370
  machineconfig/utils/code.py,sha256=0sAlozPgbbGwNE0sksK1XiBMyfCBtBt5d_6ExL1K9_8,6489
367
371
  machineconfig/utils/installer.py,sha256=ZnhW_gRmGlq5uXwzNvIn-x1vXuOJxkzVqjNu188f37s,10465
368
372
  machineconfig/utils/io.py,sha256=rzEwAnq-gyT29Y4CDHHGxAA6ddIIFOCxrqZ6dn0ALa4,2255
369
- machineconfig/utils/links.py,sha256=GQExBsMoxewOhwIrNdERuzk9HVKcmWgNUGO-RzPMS6M,22588
373
+ machineconfig/utils/links.py,sha256=KM6vIn3hag9FYEzLSHP5MAM9tU_RStw2mCq2_OvmmZA,23672
370
374
  machineconfig/utils/notifications.py,sha256=tuXIudcip0tEioG-bm8BbLr3FMDve4f6BktlznBhKxM,9013
371
375
  machineconfig/utils/options.py,sha256=vUO4Kej-vDOv64wHr2HNDyu6PATURpjd7xp6N8OOoJg,7083
372
376
  machineconfig/utils/path_extended.py,sha256=Xjdn2AVnB8p1jfNMNe2kJutVa5zGnFFJVGZbw-Bp_hg,53200
@@ -381,6 +385,7 @@ machineconfig/utils/upgrade_packages.py,sha256=H96zVJEWXJW07nh5vhjuSCrPtXGqoUb7x
381
385
  machineconfig/utils/ve.py,sha256=L-6PBXnQGXThiwWgheJMQoisAZOZA6SVCbGw2J-GFnI,2414
382
386
  machineconfig/utils/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
383
387
  machineconfig/utils/ai/generate_file_checklist.py,sha256=ajbmhcBToRugl75c_KZRq2XJumxKgIqQhyf7_YtF5q4,2729
388
+ machineconfig/utils/cloud/onedrive/README.md,sha256=i20oRG110AN0yLF3DARHfWXDJjPBiSgWI8CP2HQAqrk,3774
384
389
  machineconfig/utils/cloud/onedrive/setup_oauth.py,sha256=ZTVkqgrwbV_EoPvyT8dyOTUE0ur3BW4sa9o6QYtt5Bo,2341
385
390
  machineconfig/utils/cloud/onedrive/transaction.py,sha256=m-aNcnWj_gfZVvJOSpkdIqjZxU_3nXx2CA-qKbQgP3I,26232
386
391
  machineconfig/utils/files/ascii_art.py,sha256=cNJaJC07vx94fS44-tzgfbfBeCwXVrgpnWGBLUnfC38,5212
@@ -398,8 +403,8 @@ machineconfig/utils/schemas/fire_agents/fire_agents_input.py,sha256=Xbi59rU35AzR
398
403
  machineconfig/utils/schemas/installer/installer_types.py,sha256=QClRY61QaduBPJoSpdmTIdgS9LS-RvE-QZ-D260tD3o,1214
399
404
  machineconfig/utils/schemas/layouts/layout_types.py,sha256=TcqlZdGVoH8htG5fHn1KWXhRdPueAcoyApppZsPAPto,2020
400
405
  machineconfig/utils/schemas/repos/repos_types.py,sha256=ECVr-3IVIo8yjmYmVXX2mnDDN1SLSwvQIhx4KDDQHBQ,405
401
- machineconfig-5.45.dist-info/METADATA,sha256=8Jq_P38IUHDA8QbTfRifEJMVUuMSo5obI6vp4N-3PXo,3111
402
- machineconfig-5.45.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
403
- machineconfig-5.45.dist-info/entry_points.txt,sha256=z7b9guivf0GSKUG6b8ALgbDoRg2LuPfkGP_p-PxgX9g,469
404
- machineconfig-5.45.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
405
- machineconfig-5.45.dist-info/RECORD,,
406
+ machineconfig-5.47.dist-info/METADATA,sha256=qQlk_75QfjpJwXdd1X07K2Lxsthyie6TtawEv1i3m04,3111
407
+ machineconfig-5.47.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
408
+ machineconfig-5.47.dist-info/entry_points.txt,sha256=z7b9guivf0GSKUG6b8ALgbDoRg2LuPfkGP_p-PxgX9g,469
409
+ machineconfig-5.47.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
410
+ machineconfig-5.47.dist-info/RECORD,,