-
Notifications
You must be signed in to change notification settings - Fork 199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check if Include folders/files do exists (in case they are removed) #1718
base: dev
Are you sure you want to change the base?
Conversation
Solution b) when start taking a snapshot the include list should be checked of existence first and warn about missings. reference: bit-team#1586
This is not complete yet, but if possible I would like some feedback before finishing it. Are the messages good? And I am wondering if the qt warning is ok (it is asking a confirmation before continuing instead of just warning). And I didn't implement a) for no big reason. I am still getting familiar with the code and b) was something that was more clear for me. I could try a) in a future PR. And how you normally do translations? I was planning to translate all other languages using some automated tool (Copilot) but I wanted to confirm how you guys do it normally... |
Dear Rafael, I added some comments and suggestions to the code. I am not sure about the whole solution. I would suggest to further discuss it in the related issue #1586. I will set the PR into Draft mode to state the the solution is not finished. Best, |
Co-authored-by: buhtz <[email protected]>
Co-authored-by: buhtz <[email protected]>
Co-authored-by: buhtz <[email protected]>
Co-authored-by: buhtz <[email protected]>
I appreciate a lot for the review. It clarified a lot of questions and taught me some good lessons (I would never have thought about RTL issues on translations). And I am happy about not use the camel case :) I will do the fixes from the review and wait for any suggestion in the original issue. Thank you very much 🙏 |
refactor btn snapshot & improve translate message Co-authored-by: buhtz <[email protected]>
Does anyone know how to trigger the systray-icon message-bubbles via BIT? I tried with "Snapshot.setTakeSnapshotMessage(1, 'FOO BAR')" but without success. This message appears in the status bar of the main window. |
Me neither. When I started to work on the translation task I thougt it is easy. I learned things like that from translators and the community around them while trying to attract translators to BIT. |
I am still checking on Systray. TBH I didn't know we had a systray (it is not running fine here). But I will keep trying to understand it in order to make the fix. |
Our systray icon started as stand-alone process backintime/qt/plugins/systrayiconplugin.py Lines 86 to 93 in 99081af
and it calls every second a function to update the status: backintime/qt/qtsystrayicon.py Lines 160 to 201 in 99081af
It reads the current "snapshot message" from a file: backintime/common/snapshots.py Line 96 in 99081af
So to change the status message of the systray icon the message file's content must be changed, I guess (= not tried) with: backintime/common/snapshots.py Line 151 in 99081af
The message is only shown while a snapshot is taken otherwise the systray icon is closed again (it is not running permanently - which is what I would implement in the future to also get rid of the root systray icon issues due to hijacking the X11 session of a user). |
@rafaelhdr Thanks a lot for your contribution and helping us to improve BiT! @rafaelhdr @buhtz I am wondering if the validation logic to check for existing includes does really work in every scenario, esp. when the include path is mounted via a I know this a quite rare scenario (using a For a simple The BiT function to mount for using a profile is this: backintime/common/pluginmanager.py Line 165 in 99081af
|
I do see. This is a longer story. |
BTW: I think to correctly test the mount/unmount user-callback calls via the BiT GUI my old patch must be applied: Perhaps it is time to push this patch now as work-around (even though it is in-efficient because it mounts/unmounts far too often)... |
You mean if the "backup source" is an external drive for example and present all the time? |
Yes, check for existing include folders after the user-callback script was called to "mount" everything. Or another example: The source is an encrypted container (TrueCrypt/VeraCrypt) and shall be mounted only for backups |
Thank you for all your help, guys 🙏 About the Systray, I think I got the idea. I was able to run it locally, and I will try to add something.Thank you for the directions. BTW, I just noticed the systray after you guys mentioned it. I was able to make it work after adding an extension to Gnome (https://extensions.gnome.org/extension/615/appindicator-support/). Do you think it is worth mentioning in the docs? About the user-callback suggestion, I think I got it... Just to be sure, these are the logs from my local tests: $ backintime backup --profile-id 4
> Back In Time
> Version: 1.4.4-dev.7472f54d
(...)
> WARNING: The following folders are missing: /home/rafaelhdr/Mocks2
> INFO: Lock
> INFO: Mountpoint /home/rafaelhdr/.local/share/backintime/mnt/7AE1B8E6/mountpoint is already mounted
> INFO: Take a new snapshot. Profile: 4 khadas 2
(...) So, this |
Hey guys, Thank you for all the support. I was able to display the error with this: We could consider it as an error, right? (if not, I could replace the And I moved the check for after the mount. I hope it is good. Let me know if you think we could change it, but also feel free to change anything :) |
FYI: I am AFK for one week and will review this PR when I am back... |
Hello Rafael, |
Copy & Paste ... Using Firstly, excessive Additionally, it's often unnecessary to mention admins or moderators directly, as they are usually subscribed to relevant issues or pull requests and will receive notifications automatically. |
I apologize about the mention :( |
I had no time for longer than expected but I plan to do the review tomorrow (sorry for not informing you earlier!). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rafaelhdr I have done the code review with some (more or less cosmetic) findings only. Could you please check my review findings and pull the changes (or discuss different solutions here)? THX a lot :-)
PS: I will do some manual tests on my own then using my personal testing profiles...
common/backintime.py
Outdated
@@ -48,6 +48,16 @@ | |||
|
|||
parsers = {} | |||
|
|||
|
|||
def warning_on_take_snapshot(config): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure it this function should be placed into snapshots.py
or instead (or some other code file that is more appropriate) since
backintime.py` is the "main" code file and already quite crowded.
Also: I would prefer a name like eg. validate_profile()
or validate_on_take_snapshot()
because this is the major purpose of the function (issuing a warning is "just" a final action and does not always happen).
Finally I am wondering if this logic could be implemented into
Lines 338 to 341 in 99081af
def checkConfig(self): | |
profiles = self.profiles() | |
for profile_id in profiles: |
where it naturally fits but that function is doing to much at the moment (checks all profiles/configs so it is a mis-nomer - should be checkConfig()
and call a separate checkProfile()
for each single profile of a configuration so that the logic of warning_on_take_snapshots()
could be added there and called as done below...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I have checked the implementation and think using the config.py#checkConfig()
is too complicated at the moment (requires some refactorings and better documentation)...
@@ -1182,12 +1182,27 @@ def updateTimeLine(self, refreshSnapshotsList = True): | |||
item = self.timeLine.addSnapshot(sid) | |||
self.timeLine.checkSelection() | |||
|
|||
def validate_on_take_snapshot(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
excellent function name 👍 !!!
common/snapshots.py
Outdated
@@ -3109,6 +3109,25 @@ def lastSnapshot(cfg): | |||
return sids[0] | |||
|
|||
|
|||
def has_missing(included): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add what is missing to make the purpose of the function clear: has_missing_includes()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I suggest to rename the function to has_missing_includes()
common/snapshots.py
Outdated
|
||
if missing: | ||
msg = ', '.join(missing) | ||
msg = f'The following folders are missing: {msg}' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think "includes" could be folders but also files so I would add "... following **files/**folders are missing..." to the message
msg = ', '.join(missing) | ||
msg = f'The following folders are missing: {msg}' | ||
logger.warning(msg) | ||
self.setTakeSnapshotMessage(1, msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"1" means "error" ("0" would be "info"), but we do not yet have a value for "warnings".
I am not quite sure about the impact of using "error" here (eg. does this mean that the taken snapshot is reported as "error"?). I have to test this...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I think I used 1 in order to show properly in the Systray (but now systray is not working fine for me anymore :/)
But sure. Let me know if you want me to change :)
common/snapshots.py
Outdated
@@ -698,6 +698,15 @@ def remove(self, sid): | |||
|
|||
return True | |||
|
|||
def _warning_on_take_snapshot(self, config): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great to add a comment header to describe the purpose and arguments of the function
common/snapshots.py
Outdated
@@ -698,6 +698,15 @@ def remove(self, sid): | |||
|
|||
return True | |||
|
|||
def _warning_on_take_snapshot(self, config): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function name (_warning_on_take_snapshot
) does indicate that a warning is issued but it is unclear under which condition (or what is checked).
I suggest to rename the function to eg. _check_included_sources_exist_on_take_snapshot
(perhaps you find a better word than "sources")
""" | ||
not_found = [] | ||
for path, info in included: | ||
if not os.path.exists(path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if os.path.exists()
does also work for files (though folders are files), could you please (manually) check this with a configuration that contains a "missing" and an "existing" file (positive and negative test)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I just did it and it worked fine :)
I tested via CLI:
➜ /tmp cd /tmp /0.0s
➜ /tmp touch test.txt /0.0s
➜ /tmp python
Python 3.12.4 (main, Jun 7 2024, 06:33:07) [GCC 14.1.1 20240522] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.path.exists("/tmp")
True
>>> os.path.exists("/tmp/test.txt")
True
>>> os.path.exists("/wrong")
False
>>> os.path.exists("/tmp/wrong.txt")
False
I tested w/ CLI, and got correct results w/ this warning:
WARNING: The following **files/**folders are missing: /home/rafaelhdr/RMFolder, /home/rafaelhdr/RMFIle
And also via GUI with real snapshots (w/ existent folder, removed folder, existent file and removed file).
missing = snapshots.has_missing(self.config.include()) | ||
if missing: | ||
msg_missing = '\n'.join(missing) | ||
msg = _('The following folders are missing: {folders} Do you want to proceed?'.format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The def _warning_on_take_snapshot()
in snapshots.py also has a similar message creation logic so this code partially looks like duplicated code (and "includes" could also be files so I would add "files/folders` here too.
If you'd find a simple way to de-duplicate the code it would be great but if it is too complicated I could live with the existing code here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About this, a similar code was made with the missing = snapshots.has_missing(self.config.include())
(which is now renamed to has_missing_includes
)
Only the text generation is different (also not translated the CLI version) and how we warn the user.
Ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for the review. I made the improvements suggested and answered/tested per requests.
""" | ||
not_found = [] | ||
for path, info in included: | ||
if not os.path.exists(path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I just did it and it worked fine :)
I tested via CLI:
➜ /tmp cd /tmp /0.0s
➜ /tmp touch test.txt /0.0s
➜ /tmp python
Python 3.12.4 (main, Jun 7 2024, 06:33:07) [GCC 14.1.1 20240522] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.path.exists("/tmp")
True
>>> os.path.exists("/tmp/test.txt")
True
>>> os.path.exists("/wrong")
False
>>> os.path.exists("/tmp/wrong.txt")
False
I tested w/ CLI, and got correct results w/ this warning:
WARNING: The following **files/**folders are missing: /home/rafaelhdr/RMFolder, /home/rafaelhdr/RMFIle
And also via GUI with real snapshots (w/ existent folder, removed folder, existent file and removed file).
missing = snapshots.has_missing(self.config.include()) | ||
if missing: | ||
msg_missing = '\n'.join(missing) | ||
msg = _('The following folders are missing: {folders} Do you want to proceed?'.format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About this, a similar code was made with the missing = snapshots.has_missing(self.config.include())
(which is now renamed to has_missing_includes
)
Only the text generation is different (also not translated the CLI version) and how we warn the user.
Ok?
msg = ', '.join(missing) | ||
msg = f'The following folders are missing: {msg}' | ||
logger.warning(msg) | ||
self.setTakeSnapshotMessage(1, msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I think I used 1 in order to show properly in the Systray (but now systray is not working fine for me anymore :/)
But sure. Let me know if you want me to change :)
Solution b) when start taking a snapshot the include list should be checked of existence first and warn about missings.
reference: #1586