Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into feat/quick-mount
Browse files Browse the repository at this point in the history
TheLazron authored Mar 8, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 317cd0b + b2cf5b1 commit ac624ed
Showing 192 changed files with 8,155 additions and 3,525 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -13,5 +13,5 @@ trim_trailing_whitespace = true
[Makefile]
indent_style = tab

[.github/**.yml]
[**.{yml,yaml}]
indent_size = 2
3 changes: 3 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Migrate code style to Black
b6a24debb78b953117a3f637db18942f370a4b85

# Run pre-commit after adding ruff
24e1dd5c561bc3da972e41e6fd61961f12a2fc9f
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_form.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: "Bug Report Form"
description: "Report a bug or a similiar issue."
description: "Report a bug or a similar issue."
body:
- type: markdown
attributes:
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Bug Report
about: Report a bug or a similiar issue - the classic way
about: Report a bug or a similar issue - the classic way
title: ''
labels: ''
assignees: ''
@@ -18,7 +18,7 @@ If you want to suggest a feature or have any other question, please use our
#### Description

<!-- Description
Please decribe your issue and its context in a clear and concise way.
Please describe your issue and its context in a clear and concise way.
Please try to reproduce the issue and provide the steps to reproduce it.
-->

4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: Feature Request
about: Suggest an idea for this project.
title: 'FR: '
labels: 'type:enhancement'
title: ''
labels: ''
assignees: ''

---
22 changes: 22 additions & 0 deletions .github/actions/install-dependencies/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Install Dependencies
description: Installs system dependencies

runs:
using: "composite"
steps:
- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
sudo apt update && sudo apt install -y \
xvfb libssl-dev openssl libacl1-dev libacl1 fuse3 build-essential \
libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \
libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 \
libegl1 libxcb-cursor0 libfuse-dev libsqlite3-dev libfuse3-dev pkg-config \
python3-pkgconfig libxxhash-dev borgbackup
- name: Install system dependencies (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
brew install openssl readline xz xxhash pkg-config borgbackup
62 changes: 62 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Setup
description: Sets up python and pre-commit

# note:
# this is a local composite action
# documentation: https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
# code example: https://github.com/GuillaumeFalourd/poc-github-actions/blob/main/.github/actions/local-action/action.yaml

inputs:
pre-commit:
description: Whether pre-commit shall be setup, too
required: false
default: "" # == false
python-version:
description: The python version to install
required: true
default: "3.10"
install-nox:
description: Whether nox shall be installed
required: false
default: "" # == false
runs:
using: "composite"
steps:
- name: Set up Python ${{ inputs.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ inputs.python-version }}

- name: Get pip cache dir
shell: bash
id: pip-cache
run: |
echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
- name: pip cache
uses: actions/cache@v3
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-pip-${{ hashFiles('setup.cfg', 'requirements.d/**') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install pre-commit
shell: bash
run: pip install pre-commit

- name: Install nox
if: ${{ inputs.install-nox }}
shell: bash
run: pip install nox

- name: Hash python version
if: ${{ inputs.setup-pre-commit }}
shell: bash
run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV

- name: Caching for Pre-Commit
if: ${{ inputs.setup-pre-commit }}
uses: actions/cache@v3
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@
- [ ] All new and existing tests passed.


*I provide my contribution under the terms of the [license](./../../LICENSE.txt) of this repository and I affirm the [Developer Certificate of Origin][dco].*
*I provide my contribution under the terms of the [license](./../LICENSE.txt) of this repository and I affirm the [Developer Certificate of Origin][dco].*

[dco]: https://developercertificate.org/

30 changes: 30 additions & 0 deletions .github/scripts/generate-matrix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
event_name="$1"
branch_name="$2"

if [[ "$event_name" == "workflow_dispatch" ]] || [[ "$branch_name" == "master" ]]; then
echo '{
"python-version": ["3.8", "3.9", "3.10", "3.11"],
"os": ["ubuntu-latest", "macos-latest"],
"borg-version": ["1.2.4"]
}' | jq -c . > matrix-unit.json

echo '{
"python-version": ["3.8", "3.9", "3.10", "3.11"],
"os": ["ubuntu-latest", "macos-latest"],
"borg-version": ["1.1.18", "1.2.2", "1.2.4", "2.0.0b5"],
"exclude": [{"borg-version": "2.0.0b5", "python-version": "3.8"}]
}' | jq -c . > matrix-integration.json

elif [[ "$event_name" == "push" ]] || [[ "$event_name" == "pull_request" ]]; then
echo '{
"python-version": ["3.8", "3.9", "3.10", "3.11"],
"os": ["ubuntu-latest", "macos-latest"],
"borg-version": ["1.2.4"]
}' | jq -c . > matrix-unit.json

echo '{
"python-version": ["3.10"],
"os": ["ubuntu-latest"],
"borg-version": ["1.2.4"]
}' | jq -c . > matrix-integration.json
fi
62 changes: 33 additions & 29 deletions .github/stale.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
name: Close stale issues
on:
schedule:
- cron: '50 1 * * *'

# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
with:
days-before-issue-stale: 60
days-before-pr-stale: -1
days-before-issue-close: 7
# days-before-pr-close: 10

# Issues with these labels will never be considered stale
exemptLabels:
- "status:idea"
- "status:planning"
- "status:on hold"
- "status:ready"
- "type:bug"
- "type:docs"
- "type:enhancement"
- "type:feature"
- "type:refactor"
- "type:task"
stale-issue-label: "status:stale"
stale-pr-label: "status:stale"

# Label to use when marking an issue as stale
staleLabel: "status:stale"
exempt-issue-labels: >
status:idea,
status:planning,
status:on hold,
status:ready,
type:bug,
type:docs,
type:enhancement,
type:feature,
type:refactor,
type:task,
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

# Limit to only `issues` or `pulls`
only: issues
stale-issue-message: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
close-issue-message: >
This issue was closed because it has been stalled for 7 days with no activity.
1 change: 1 addition & 0 deletions .github/workflows/build-macos.yml
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@ jobs:
CERTIFICATE_NAME: ${{ secrets.MACOS_CERTIFICATE_NAME }}
APPLE_ID_USER: ${{ secrets.APPLE_ID_USER }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
security create-keychain -p 123 build.keychain
198 changes: 123 additions & 75 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -7,92 +7,140 @@ on:
inputs:
debug_enabled:
type: boolean
description: 'Run the build with tmate debugging enabled'
description: "Run the build with tmate debugging enabled"
required: false
default: false

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@2c3dd9e7e29afd70cc0950079bde6c979d1f69f9 # v4.3.1
with:
python-version: 3.8
- name: Install Vorta
run: |
pip install .
pip install -r requirements.d/dev.txt
- name: Test formatting with Flake8, isort and Black
run: make lint
# - name: Run PyLint (info only)
# run: pylint --rcfile=setup.cfg src --exit-zero


test:
- uses: actions/checkout@v3
- name: Setup python, vorta and dev deps
uses: ./.github/actions/setup
with:
python-version: 3.11
pre-commit: true

- name: Test formatting with Flake8, ruff and Black
shell: bash
run: make lint

prepare-matrix:
runs-on: ubuntu-latest
outputs:
matrix-unit: ${{ steps.set-matrix-unit.outputs.matrix }}
matrix-integration: ${{ steps.set-matrix-integration.outputs.matrix }}
steps:
- uses: actions/checkout@v3

- name: Give execute permission to script
run: chmod +x ./.github/scripts/generate-matrix.sh

- name: Generate matrices
run: |
./.github/scripts/generate-matrix.sh "${{ github.event_name }}" "${GITHUB_REF##refs/heads/}"
- name: Set matrix for unit tests
id: set-matrix-unit
run: echo "matrix=$(cat matrix-unit.json)" >> $GITHUB_OUTPUT

- name: Set matrix for integration tests
id: set-matrix-integration
run: echo "matrix=$(cat matrix-integration.json)" >> $GITHUB_OUTPUT

test-unit:
needs: prepare-matrix
timeout-minutes: 20
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix: ${{fromJson(needs.prepare-matrix.outputs.matrix-unit)}}

steps:
- uses: actions/checkout@v3

- name: Install system dependencies
uses: ./.github/actions/install-dependencies

- name: Setup python, vorta and dev deps
uses: ./.github/actions/setup
with:
python-version: ${{ matrix.python-version }}
install-nox: true

- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}

matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
os: [ubuntu-latest, macos-latest]
- name: Run Unit Tests with pytest (Linux)
if: runner.os == 'Linux'
env:
BORG_VERSION: ${{ matrix.borg-version }}
run: |
xvfb-run --server-args="-screen 0 1024x768x24+32" \
-a dbus-run-session -- make test-unit
- name: Run Unit Tests with pytest (macOS)
if: runner.os == 'macOS'
env:
BORG_VERSION: ${{ matrix.borg-version }}
PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig
run: echo $PKG_CONFIG_PATH && make test-unit

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
env:
OS: ${{ runner.os }}
python: ${{ matrix.python-version }}
with:
token: ${{ secrets.CODECOV_TOKEN }}
env_vars: OS, python

test-integration:
needs: prepare-matrix
timeout-minutes: 20
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix: ${{fromJson(needs.prepare-matrix.outputs.matrix-integration)}}

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@2c3dd9e7e29afd70cc0950079bde6c979d1f69f9 # v4.3.1
with:
python-version: ${{ matrix.python-version }}

- name: Get pip cache dir
id: pip-cache
run: |
echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
- name: pip cache
uses: actions/cache@v2
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-pip-${{ hashFiles('setup.cfg', 'requirements.d/**') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt update && sudo apt install -y \
xvfb libssl-dev openssl libacl1-dev libacl1 build-essential borgbackup \
libxkbcommon-x11-0 dbus-x11 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \
libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0
- name: Install system dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew install openssl readline xz borgbackup
- name: Install Vorta
run: |
pip install -e .
pip install -r requirements.d/dev.txt
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}

- name: Test with pytest (Linux)
if: runner.os == 'Linux'
run: |
xvfb-run --server-args="-screen 0 1024x768x24+32" \
-a dbus-run-session -- make test
- name: Test with pytest (macOS)
if: runner.os == 'macOS'
run: make test

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
env:
OS: ${{ runner.os }}
python: ${{ matrix.python-version }}
with:
token: ${{ secrets.CODECOV_TOKEN }}
env_vars: OS, python
- uses: actions/checkout@v3

- name: Install system dependencies
uses: ./.github/actions/install-dependencies

- name: Setup python, vorta and dev deps
uses: ./.github/actions/setup
with:
python-version: ${{ matrix.python-version }}
install-nox: true

- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true'}}

- name: Run Integration Tests with pytest (Linux)
if: runner.os == 'Linux'
env:
BORG_VERSION: ${{ matrix.borg-version }}
run: |
xvfb-run --server-args="-screen 0 1024x768x24+32" \
-a dbus-run-session -- make test-integration
- name: Run Integration Tests with pytest (macOS)
if: runner.os == 'macOS'
env:
BORG_VERSION: ${{ matrix.borg-version }}
PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig
run: echo $PKG_CONFIG_PATH && make test-integration

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
env:
OS: ${{ runner.os }}
python: ${{ matrix.python-version }}
with:
token: ${{ secrets.CODECOV_TOKEN }}
env_vars: OS, python
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -20,9 +20,12 @@ env
venv
.env
.venv
# dirs created by the --development option
.dev_config/
# Avoid adding translations of source language
# Files are still used by Transifex
src/vorta/i18n/ts/vorta.en.ts
src/vorta/i18n/ts/vorta.en_US.ts
flatpak/app/
flatpak/.flatpak-builder/
.vscode
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -28,19 +28,19 @@ repos:
# sort requirements.txt files
- id: requirements-txt-fixer

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: "v0.0.257"
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]

# format python files
- repo: https://github.com/psf/black
rev: 22.12.0
hooks:
- id: black
files: ^(src/vorta/|tests)

# sort python imports
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort

# # run black on code embedded in docstrings
# - repo: https://github.com/asottile/blacken-docs
# rev: v1.12.1
1 change: 0 additions & 1 deletion .tx/config
Original file line number Diff line number Diff line change
@@ -7,4 +7,3 @@ source_file = src/vorta/i18n/ts/vorta.en.ts
source_lang = en
type = QT
minimum_perc = 80

23 changes: 17 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -2,15 +2,22 @@ export VORTA_SRC := src/vorta
export APPSTREAM_METADATA := src/vorta/assets/metadata/com.borgbase.Vorta.appdata.xml
VERSION := $(shell python -c "from src.vorta._version import __version__; print(__version__)")

.PHONY : help
.PHONY : help clean lint test
.DEFAULT_GOAL := help

# Set Homebrew location to /opt/homebrew on Apple Silicon, /usr/local on Intel
ifeq ($(shell uname -m),arm64)
export HOMEBREW = /opt/homebrew
else
export HOMEBREW = /usr/local
endif

clean:
rm -rf dist/*

dist/Vorta.app: ## Build macOS app locally (without Borg)
pyinstaller --clean --noconfirm package/vorta.spec
cp -R /usr/local/Caskroom/sparkle/*/Sparkle.framework dist/Vorta.app/Contents/Frameworks/
cp -R ${HOMEBREW}/Caskroom/sparkle/*/Sparkle.framework dist/Vorta.app/Contents/Frameworks/
rm -rf build/vorta dist/vorta

dist/Vorta.dmg: dist/Vorta.app ## Create notarized macOS DMG for distribution.
@@ -57,12 +64,16 @@ flatpak-install: translations-to-qm
install -D src/vorta/assets/metadata/com.borgbase.Vorta.desktop ${FLATPAK_DEST}/share/applications/com.borgbase.Vorta.desktop

lint:
flake8
isort --check-only .
black --check .
pre-commit run --all-files --show-diff-on-failure

test:
pytest --cov=vorta
nox -- --cov=vorta

test-unit:
nox -- --cov=vorta tests/unit

test-integration:
nox -- --cov=vorta tests/integration

help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -11,11 +11,9 @@
<br>
<br>

🤝 **This project is part of the [Google Summer of Code](https://summerofcode.withgoogle.com/) 2023 program. Apply or learn more [here](https://github.com/borgbase/vorta/wiki/Google-Summer-of-Code-2023-Ideas)!**

Vorta is a backup client for macOS and Linux desktops. It integrates the mighty [BorgBackup](https://borgbackup.readthedocs.io) with your desktop environment to protect your data from disk failure, ransomware and theft.

![](https://files.qmax.us/vorta/screencast-8-small.gif)
https://github.com/m3nu/vorta/assets/3916435/a622a148-5373-4ae0-87bc-4ca1d6f6202e

## Why is this great? 🤩

@@ -30,15 +28,16 @@ Learn more on [Vorta's website](https://vorta.borgbase.com).
## Installation
Vorta should work on all platforms that support Qt and Borg. This includes macOS, Ubuntu, Debian, Fedora, Arch Linux and many others. Windows is currently not supported by Borg, but this may change in the future.

See our website for [download links and and install instructions](https://vorta.borgbase.com/install).
See our website for [download links and install instructions](https://vorta.borgbase.com/install).

## Connect and Contribute
- To discuss everything around using, improving, packaging and translating Vorta, join the [discussion on Github](https://github.com/borgbase/vorta/discussions).
- Report bugs by opening a new [Github issue](https://github.com/borgbase/vorta/issues/new/choose).
- Want to contribute to Vorta? Great! See our [contributor guide](https://vorta.borgbase.com/contributing/) on how to help out with coding, translation and packaging.
- We currently have students from the Google Summer Of Code 2023 Program contributing to this project.

## License and Credits
- See [CONTRIBUTORS.md](CONTRIBUTORS.md) to see who programmed and translated Vorta.
- Licensed under [GPLv3](LICENSE.txt). © 2018-2020 Manuel Riel and Vorta contributors
- Licensed under [GPLv3](LICENSE.txt). © 2018-2023 Manuel Riel and Vorta contributors
- Based on [PyQt](https://riverbankcomputing.com/software/pyqt/intro) and [Qt](https://www.qt.io).
- Icons by [FontAwesome](https://fontawesome.com)
- Icons by [Fork Awesome](https://forkaweso.me/) (licensed under [SIL Open Font License](https://scripts.sil.org/OFL), Version 1.1) and Material Design icons by Google (licensed under [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)). See the `src/vorta/assets/icons` folder for a copy of applicable licenses.
56 changes: 56 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import os
import re
import sys

import nox

borg_version = os.getenv("BORG_VERSION")

if borg_version:
# Use specified borg version
supported_borgbackup_versions = [borg_version]
else:
# Generate a list of borg versions compatible with system installed python version
system_python_version = tuple(sys.version_info[:3])

supported_borgbackup_versions = [
borgbackup
for borgbackup in ("1.1.18", "1.2.2", "1.2.4", "2.0.0b6")
# Python version requirements for borgbackup versions
if (borgbackup == "1.1.18" and system_python_version >= (3, 5, 0))
or (borgbackup == "1.2.2" and system_python_version >= (3, 8, 0))
or (borgbackup == "1.2.4" and system_python_version >= (3, 8, 0))
or (borgbackup == "2.0.0b6" and system_python_version >= (3, 9, 0))
]


@nox.session
@nox.parametrize("borgbackup", supported_borgbackup_versions)
def run_tests(session, borgbackup):
# install borgbackup
if sys.platform == 'darwin':
# in macOS there's currently no fuse package which works with borgbackup directly
session.install(f"borgbackup=={borgbackup}")
elif borgbackup == "1.1.18":
# borgbackup 1.1.18 doesn't support pyfuse3
session.install("llfuse")
session.install(f"borgbackup[llfuse]=={borgbackup}")
else:
session.install(f"borgbackup[pyfuse3]=={borgbackup}")

# install dependencies
session.install("-r", "requirements.d/dev.txt")
session.install("-e", ".")

# check versions
cli_version = session.run("borg", "--version", silent=True).strip()
cli_version = re.search(r"borg (\S+)", cli_version).group(1)
python_version = session.run("python", "-c", "import borg; print(borg.__version__)", silent=True).strip()

session.log(f"Borg CLI version: {cli_version}")
session.log(f"Borg Python version: {python_version}")

assert cli_version == borgbackup
assert python_version == borgbackup

session.run("pytest", *session.posargs, env={"BORG_VERSION": borgbackup})
24 changes: 12 additions & 12 deletions package/fix_app_qt_folder_names_for_codesign.py
Original file line number Diff line number Diff line change
@@ -18,13 +18,13 @@ def create_symlink(folder: Path) -> None:
"""Create the appropriate symlink in the MacOS folder
pointing to the Resources folder.
"""
sibbling = Path(str(folder).replace("MacOS", ""))
sibling = Path(str(folder).replace("MacOS", ""))

# PyQt5/Qt/qml/QtQml/Models.2
root = str(sibbling).partition("Contents")[2].lstrip("/")
# PyQt6/Qt/qml/QtQml/Models.2
root = str(sibling).partition("Contents")[2].lstrip("/")
# ../../../../
backward = "../" * (root.count("/") + 1)
# ../../../../Resources/PyQt5/Qt/qml/QtQml/Models.2
# ../../../../Resources/PyQt6/Qt/qml/QtQml/Models.2
good_path = f"{backward}Resources/{root}"

folder.symlink_to(good_path)
@@ -41,7 +41,7 @@ def fix_dll(dll: Path) -> None:

def match_func(pth: str) -> Optional[str]:
"""Callback function for MachO.rewriteLoadCommands() that is
called on every lookup path setted in the DLL headers.
called on every lookup path set in the DLL headers.
By returning None for system libraries, it changes nothing.
Else we return a relative path pointing to the good file
in the MacOS folder.
@@ -51,7 +51,7 @@ def match_func(pth: str) -> Optional[str]:
return None
return f"@loader_path{good_path}/{basename}"

# Resources/PyQt5/Qt/qml/QtQuick/Controls.2/Fusion
# Resources/PyQt6/Qt/qml/QtQuick/Controls.2/Fusion
root = str(dll.parent).partition("Contents")[2][1:]
# /../../../../../../..
backward = "/.." * (root.count("/") + 1)
@@ -73,7 +73,7 @@ def find_problematic_folders(folder: Path) -> Generator[Path, None, None]:
"""Recursively yields problematic folders (containing a dot in their name)."""
for path in folder.iterdir():
if not path.is_dir() or path.is_symlink():
# Skip simlinks as they are allowed (even with a dot)
# Skip symlinks as they are allowed (even with a dot)
continue
if "." in path.name:
yield path
@@ -83,18 +83,18 @@ def find_problematic_folders(folder: Path) -> Generator[Path, None, None]:

def move_contents_to_resources(folder: Path) -> Generator[Path, None, None]:
"""Recursively move any non symlink file from a problematic folder
to the sibbling one in Resources.
to the sibling one in Resources.
"""
for path in folder.iterdir():
if path.is_symlink():
continue
if path.name == "qml":
yield from move_contents_to_resources(path)
else:
sibbling = Path(str(path).replace("MacOS", "Resources"))
sibbling.parent.mkdir(parents=True, exist_ok=True)
shutil.move(path, sibbling)
yield sibbling
sibling = Path(str(path).replace("MacOS", "Resources"))
sibling.parent.mkdir(parents=True, exist_ok=True)
shutil.move(path, sibling)
yield sibling


def main(args: List[str]) -> int:
40 changes: 8 additions & 32 deletions package/macos-package-app.sh
Original file line number Diff line number Diff line change
@@ -7,7 +7,8 @@ APP_BUNDLE_ID="com.borgbase.client.macos"
APP_BUNDLE="Vorta"
# CERTIFICATE_NAME="Developer ID Application: Joe Doe (XXXXXX)"
# APPLE_ID_USER="name@example.com"
# APPLE_ID_PASSWORD="@keychain:Notarization"
# APPLE_ID_PASSWORD="CHANGEME"
# APPLE_TEAM_ID="CNMSCAXT48"


# Sign app bundle, Sparkle and Borg
@@ -37,38 +38,13 @@ create-dmg \
"Vorta.dmg" \
"Vorta.app"


# Notarize DMG
RESULT=$(xcrun altool --notarize-app --type osx \
--primary-bundle-id $APP_BUNDLE_ID \
--username $APPLE_ID_USER --password $APPLE_ID_PASSWORD \
--file "$APP_BUNDLE.dmg" --output-format xml)

REQUEST_UUID=$(echo "$RESULT" | xpath5.18 "//key[normalize-space(text()) = 'RequestUUID']/following-sibling::string[1]/text()" 2> /dev/null)

# Poll for notarization status
echo "Submitted notarization request $REQUEST_UUID, waiting for response..."
sleep 60
while true
do
RESULT=$(xcrun altool --notarization-info "$REQUEST_UUID" \
--username "$APPLE_ID_USER" \
--password "$APPLE_ID_PASSWORD" \
--output-format xml)
STATUS=$(echo "$RESULT" | xpath5.18 "//key[normalize-space(text()) = 'Status']/following-sibling::string[1]/text()" 2> /dev/null)

if [ "$STATUS" = "success" ]; then
echo "Notarization of $APP_BUNDLE succeeded!"
break
elif [ "$STATUS" = "in progress" ]; then
echo "Notarization in progress..."
sleep 20
else
echo "Notarization of $APP_BUNDLE failed:"
echo "$RESULT"
exit 1
fi
done
xcrun notarytool submit \
--output-format plist --wait --timeout 10m \
--apple-id $APPLE_ID_USER \
--password $APPLE_ID_PASSWORD \
--team-id $APPLE_TEAM_ID \
"$APP_BUNDLE.dmg"

# Staple the notary ticket
xcrun stapler staple $APP_BUNDLE.dmg
1 change: 1 addition & 0 deletions package/vorta.spec
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ a = Analysis([os.path.join(SRC_DIR, '__main__.py')],
datas=[
(os.path.join(SRC_DIR, 'assets/UI/*'), 'assets/UI'),
(os.path.join(SRC_DIR, 'assets/icons/*'), 'assets/icons'),
(os.path.join(SRC_DIR, 'assets/exclusion_presets/*'), 'assets/exclusion_presets'),
(os.path.join(SRC_DIR, 'i18n/qm/*'), 'vorta/i18n/qm'),
],
hiddenimports=[
13 changes: 5 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -4,14 +4,11 @@ skip-string-normalization = true
target-version = ['py39']
include = "(src/vorta/|tests).*.py$"

[tool.isort]
profile = "black"
line_length = 120
skip_gitignore = true
multi_line_output = 3
lines_between_sections = 0
src_paths = ["src", "tests"]

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[tool.ruff]
select = ["T", "I"]
exclude = ["package"]
fixable = ["I"]
6 changes: 4 additions & 2 deletions requirements.d/dev.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
pre-commit
black==22.*
coverage
flake8
isort
macholib
nox
pkgconfig
pre-commit
pyinstaller
pylint
pytest
pytest-cov
pytest-faulthandler
pytest-mock
pytest-qt
ruff
tox
twine
wheel
20 changes: 10 additions & 10 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -35,19 +35,19 @@ packages = find:
package_dir =
=src
include_package_data = true
python_requires = >=3.7
python_requires = >=3.8
install_requires =
platformdirs >=3.0.0, <4.0.0; sys_platform == 'darwin' # for macOS: breaking changes in 3.0.0,
platformdirs >=2.6.0, <4.0.0; sys_platform != 'darwin' # for others: 2.6+ works consistently.
paramiko
pyqt5
platformdirs >=3.0.0, <5.0.0; sys_platform == 'darwin' # for macOS: breaking changes in 3.0.0,
platformdirs >=2.6.0, <5.0.0; sys_platform != 'darwin' # for others: 2.6+ works consistently.
pyqt6
peewee
psutil
setuptools
secretstorage; sys_platform != 'darwin'
pyobjc-core; sys_platform == 'darwin'
pyobjc-framework-Cocoa; sys_platform == 'darwin'
pyobjc-framework-LaunchServices; sys_platform == 'darwin'
pyobjc-core < 10; sys_platform == 'darwin'
pyobjc-framework-Cocoa < 10; sys_platform == 'darwin'
pyobjc-framework-LaunchServices < 10; sys_platform == 'darwin'
pyobjc-framework-CoreWLAN < 10; sys_platform == 'darwin'
tests_require =
pytest
pytest-qt
@@ -78,7 +78,7 @@ max-line-length = 120
extend-ignore = E203,E121,E123,E126,E226,E24,E704,W503,W504
exclude =
build,dist,.git,.idea,.cache,.tox,.eggs,
./src/vorta/__init__.py,.direnv
./src/vorta/__init__.py,.direnv,env

[tox:tox]
envlist = py36,py37,py38,flake8
@@ -101,7 +101,7 @@ commands=flake8 src tests
max_line_length = 120

[pylint.master]
extension-pkg-whitelist=PyQt5
extension-pkg-whitelist=PyQt6
load-plugins=

[pylint.messages control]
25 changes: 20 additions & 5 deletions src/vorta/__main__.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import os
import signal
import sys

from peewee import SqliteDatabase

# Need to import config as a whole module instead of individual variables
# because we will be overriding the modules variables
from vorta import config
from vorta._version import __version__
from vorta.config import SETTINGS_DIR
from vorta.i18n import trans_late, translate
from vorta.log import init_logger, logger
from vorta.store.connection import init_db
from vorta.updater import get_updater
from vorta.utils import parse_args
from vorta.utils import DEFAULT_DIR_FLAG, parse_args


def main():
def exception_handler(type, value, tb):
from traceback import format_exception
from PyQt5.QtWidgets import QMessageBox

from PyQt6.QtWidgets import QMessageBox

logger.critical(
"Uncaught exception, file a report at https://github.com/borgbase/vorta/issues/new/choose",
@@ -45,20 +50,30 @@ def exception_handler(type, value, tb):

want_version = getattr(args, 'version', False)
want_background = getattr(args, 'daemonize', False)
want_development = getattr(args, 'development', False)

if want_version:
print(f"Vorta {__version__}")
print(f"Vorta {__version__}") # noqa: T201
sys.exit()

if want_background:
if os.fork():
sys.exit()

if want_development:
# if we're using the default dev dir
if want_development is DEFAULT_DIR_FLAG:
config.init_dev_mode(config.default_dev_dir())
else:
# if we're not using the default dev dir and
# instead we're using whatever dir is passed as an argument
config.init_dev_mode(want_development)

init_logger(background=want_background)

# Init database
sqlite_db = SqliteDatabase(
SETTINGS_DIR / 'settings.db',
config.SETTINGS_DIR / 'settings.db',
pragmas={
'journal_mode': 'wal',
},
2 changes: 1 addition & 1 deletion src/vorta/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.8.10'
__version__ = '0.9.1'
58 changes: 33 additions & 25 deletions src/vorta/application.py
Original file line number Diff line number Diff line change
@@ -3,13 +3,15 @@
import sys
from pathlib import Path
from typing import Any, Dict, List, Tuple
from PyQt5 import QtCore
from PyQt5.QtWidgets import QMessageBox

from PyQt6 import QtCore
from PyQt6.QtWidgets import QMessageBox

from vorta import config
from vorta.borg.break_lock import BorgBreakJob
from vorta.borg.create import BorgCreateJob
from vorta.borg.jobs_manager import JobsManager
from vorta.borg.version import BorgVersionJob
from vorta.config import PROFILE_BOOTSTRAP_FILE, TEMP_DIR
from vorta.i18n import init_translations, translate
from vorta.notifications import VortaNotifications
from vorta.profile_export import ProfileExport
@@ -23,7 +25,7 @@

logger = logging.getLogger(__name__)

APP_ID = TEMP_DIR / "socket"
APP_ID = config.TEMP_DIR / "socket"


class VortaApp(QtSingleApplication):
@@ -119,7 +121,7 @@ def create_backup_action(self, profile_id=None):
translate('messages', msg['message']),
level='error',
)
self.backup_progress_event.emit(translate('messages', msg['message']))
self.backup_progress_event.emit(f"[{profile.name}] {translate('messages', msg['message'])}")
return None

def open_main_window_action(self):
@@ -171,18 +173,19 @@ def set_borg_details_result(self, result):
"""
if 'version' in result['data']:
borg_compat.set_version(result['data']['version'], result['data']['path'])
self.main_window.miscTab.set_borg_details(borg_compat.version, borg_compat.path)
self.main_window.aboutTab.set_borg_details(borg_compat.version, borg_compat.path)
self.main_window.repoTab.toggle_available_compression()
self.main_window.archiveTab.toggle_compact_button_visibility()
self.scheduler.reload_all_timers() # Start timer after Borg version is set.
else:
self._alert_missing_borg()

def _alert_missing_borg(self):
msg = QMessageBox()
msg.setIcon(QMessageBox.Critical)
msg.setIcon(QMessageBox.Icon.Critical)
msg.setText(self.tr("No Borg Binary Found"))
msg.setInformativeText(self.tr("Vorta was unable to locate a usable Borg Backup binary."))
msg.setStandardButtons(QMessageBox.Ok)
msg.setStandardButtons(QMessageBox.StandardButton.Ok)
msg.exec()

def check_darwin_permissions(self):
@@ -194,11 +197,15 @@ def check_darwin_permissions(self):
This function tries reading a file that is known to be restricted and warn the user about
incomplete backups.
"""

if not SettingsModel.get(key="check_full_disk_access").value:
return

test_path = Path('~/Library/Cookies').expanduser()
if test_path.exists() and not os.access(test_path, os.R_OK):
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse)
msg.setIcon(QMessageBox.Icon.Warning)
msg.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.LinksAccessibleByMouse)
msg.setText(self.tr("Vorta needs Full Disk Access for complete Backups"))
msg.setInformativeText(
self.tr(
@@ -208,7 +215,7 @@ def check_darwin_permissions(self):
"System Preferences > Security & Privacy</a>."
)
)
msg.setStandardButtons(QMessageBox.Ok)
msg.setStandardButtons(QMessageBox.StandardButton.Ok)
msg.exec()

def react_to_log(self, mgs, context):
@@ -221,9 +228,9 @@ def react_to_log(self, mgs, context):
repo_url = context.get('repo_url')
msg = QMessageBox()
msg.setWindowTitle(self.tr("Repository In Use"))
msg.setIcon(QMessageBox.Critical)
abortButton = msg.addButton(self.tr("Abort"), QMessageBox.RejectRole)
msg.addButton(self.tr("Continue"), QMessageBox.AcceptRole)
msg.setIcon(QMessageBox.Icon.Critical)
abortButton = msg.addButton(self.tr("Abort"), QMessageBox.ButtonRole.RejectRole)
msg.addButton(self.tr("Continue"), QMessageBox.ButtonRole.AcceptRole)
msg.setDefaultButton(abortButton)
msg.setText(self.tr(f"The repository at {repo_url} might be in use elsewhere."))
msg.setInformativeText(
@@ -250,12 +257,16 @@ def react_to_log(self, mgs, context):
def break_lock(self, profile):
params = BorgBreakJob.prepare(profile)
if not params['ok']:
self.backup_progress_event.emit(params['message'])
self.backup_progress_event.emit(f"[{profile.name}] {params['message']}")
return
job = BorgBreakJob(params['cmd'], params)
self.jobs_manager.add_job(job)

def bootstrap_profile(self, bootstrap_file=PROFILE_BOOTSTRAP_FILE):
def bootstrap_profile(self, bootstrap_file=None):
# Necessary to dynamically load the variable from config during runtime
# Check out pull request for #1682 for context
bootstrap_file = bootstrap_file or config.PROFILE_BOOTSTRAP_FILE

"""
Make sure there is at least one profile when first starting Vorta.
Will either import a profile placed in ~/.vorta-init.json
@@ -297,11 +308,6 @@ def check_failed_response(self, result: Dict[str, Any]):
Displays a `QMessageBox` with an error message depending on the
return code of the `BorgJob`.
Parameters
----------
repo_url : str
The url of the repo of concern
"""
# extract data from the params for the borg job
repo_url = result['params']['repo_url']
@@ -314,24 +320,26 @@ def check_failed_response(self, result: Dict[str, Any]):
# No fail
logger.warning('VortaApp.check_failed_response was called with returncode 0')
elif returncode == 130:
# Keyboard interupt
# Keyboard interrupt
pass
else: # Real error
# Create QMessageBox
msg = QMessageBox()
msg.setIcon(QMessageBox.Icon.Critical) # changed for warning
msg.setStandardButtons(QMessageBox.Ok)
msg.setStandardButtons(QMessageBox.StandardButton.Ok)
msg.setWindowTitle(self.tr('Repo Check Failed'))

if returncode == 1:
# warning
msg.setIcon(QMessageBox.Icon.Warning)
text = self.tr('Borg exited with a warning message. See logs for details.')
text = translate(
'VortaApp', 'Borg exited with warning status (rc 1). See the <a href="{0}">logs</a> for details.'
).format(config.LOG_DIR.as_uri())
infotext = error_message
elif returncode > 128:
# 128+N - killed by signal N (e.g. 137 == kill -9)
signal = returncode - 128
text = self.tr('Repository data check for repo was killed by signal %s.') % (signal)
text = self.tr('Repository data check for repo was killed by signal %s.') % signal
infotext = self.tr('The process running the check job got a kill signal. Try again.')
else:
# Real error
315 changes: 315 additions & 0 deletions src/vorta/assets/UI/abouttab.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>791</width>
<height>497</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="alignment">
<set>Qt::AlignHCenter</set>
</property>
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Vorta Version:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="versionLabel">
<property name="text">
<string>0.0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="alignment">
<set>Qt::AlignHCenter</set>
</property>
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Borg Version:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="borgVersion">
<property name="text">
<string>1.1.8</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="borgPath">
<property name="text">
<string>/usr/bin/borg</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="seperator">
<property name="frameShape">
<enum>QFrame::HLine</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="alignment">
<set>Qt::AlignHCenter</set>
</property>
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/borgbase/vorta/issues/new/choose&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0984e3;&quot;&gt;Click here&lt;/span&gt;&lt;/a&gt; to report a bug.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="alignment">
<set>Qt::AlignHCenter</set>
</property>
<property name="topMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="logLink">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;file:///&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0984e3;&quot;&gt;View the logs&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="indent">
<number>0</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="alignment">
<set>Qt::AlignHCenter</set>
</property>
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://borgbackup.readthedocs.io/en/master/index.html&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0984e3;&quot;&gt; Click here&lt;/span&gt;&lt;/a&gt; to view the docs.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="alignment">
<set>Qt::AlignHCenter</set>
</property>
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/borgbase/vorta&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0984e3;&quot;&gt;Click here&lt;/span&gt;&lt;/a&gt; to view Git repo.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="seperator">
<property name="frameShape">
<enum>QFrame::HLine</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="alignment">
<set>Qt::AlignHCenter</set>
</property>
<property name="spacing">
<number>20</number>
</property>
<item>
<widget class="QLabel" name="copyrightLabel">
<property name="text">
<string>
Vorta is a cross-platform, open-source client designed to simplify the management of Borg backups.

Copyright (C) 2018-2020 Manuel Riel and Vorta contributors (see CONTRIBUTORS.md)
</string>
</property>
<property name="indent">
<number>0</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<property name="spacing">
<number>20</number>
</property>
<property name="alignment">
<set>Qt::AlignHCenter</set>
</property>
<item>
<widget class="QLabel" name="gpl_logo"/>
</item>
<item>
<widget class="QLabel" name="python_logo"/>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
120 changes: 61 additions & 59 deletions src/vorta/assets/UI/archivetab.ui
Original file line number Diff line number Diff line change
@@ -145,9 +145,6 @@
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
@@ -176,6 +173,11 @@
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Trigger</string>
</property>
</column>
</widget>
</item>
<item row="0" column="1">
@@ -210,10 +212,29 @@
</sizepolicy>
</property>
<property name="toolTip">
<string>Refresh selected archive</string>
<string>Recalculate selected archive's size(s)</string>
</property>
<property name="text">
<string>Recalculate</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="bDiff">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Compare two archives</string>
</property>
<property name="text">
<string>Refresh</string>
<string>Diff</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -261,7 +282,7 @@
</property>
</widget>
</item>
<item>
<item>
<widget class="QToolButton" name="bRename">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
@@ -280,60 +301,41 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="bDelete">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Delete selected archive(s)</string>
</property>
<property name="text">
<string>Delete</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="bDiff">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Compare two archives</string>
</property>
<property name="text">
<string>Diff</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="bDelete">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Delete selected archive(s)</string>
</property>
<property name="text">
<string>Delete</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@@ -624,7 +626,7 @@
<item row="0" column="1">
<widget class="QLineEdit" name="prunePrefixTemplate">
<property name="toolTip">
<string>Available variables: hostname, profile_id, profile_slug, now, utc_now, user</string>
<string>Available variables: hostname, fqdn, profile_id, profile_slug, now, utc_now, user</string>
</property>
<property name="placeholderText">
<string>{hostname}-{profile_slug}-</string>
@@ -681,7 +683,7 @@
<item row="0" column="1">
<widget class="QLineEdit" name="archiveNameTemplate">
<property name="toolTip">
<string>Available variables: hostname, profile_id, profile_slug, now, utc_now, user</string>
<string>Available variables: hostname, fqdn, profile_id, profile_slug, now, utc_now, user</string>
</property>
<property name="placeholderText">
<string>{hostname}-{profile_slug}-{now:%Y-%m-%d-%H%M%S}</string>
153 changes: 153 additions & 0 deletions src/vorta/assets/UI/excludedialog.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>504</width>
<height>426</height>
</rect>
</property>
<property name="windowTitle">
<string>Add patterns to exclude</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="topMargin">
<number>10</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Custom</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="customPresetsHelpText">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="customExclusionsList"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="bAddPattern"/>
</item>
<item>
<widget class="QToolButton" name="bRemovePattern"/>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Presets</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="exclusionPresetsHelpText">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="exclusionPresetsList"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Raw</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="rawExclusionsHelpText">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="rawExclusionsText"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Preview</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="exclusionsPreviewHelpText">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="exclusionsPreviewText"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="bPreviewCopy">
<property name="text">
<string>Copy to Clipboard</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
404 changes: 243 additions & 161 deletions src/vorta/assets/UI/mainwindow.ui

Large diffs are not rendered by default.

107 changes: 0 additions & 107 deletions src/vorta/assets/UI/misctab.ui
Original file line number Diff line number Diff line change
@@ -43,113 +43,6 @@
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Vorta Version:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="versionLabel">
<property name="text">
<string>0.0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;| &lt;a href=&quot;https://github.com/borgbase/vorta/issues/new/choose&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0984e3;&quot;&gt;Report&lt;/span&gt;&lt;/a&gt; a Bug |&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="logLink">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;file:///&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0984e3;&quot;&gt;Log&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="indent">
<number>0</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Borg Version:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="borgVersion">
<property name="text">
<string>1.1.8</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="borgPath">
<property name="text">
<string>/usr/bin/borg</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
496 changes: 227 additions & 269 deletions src/vorta/assets/UI/repoadd.ui

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions src/vorta/assets/UI/scheduletab.ui
Original file line number Diff line number Diff line change
@@ -626,6 +626,19 @@
</column>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="logLink">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;file:///&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0984e3;&quot;&gt;View the logs&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="indent">
<number>0</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
71 changes: 11 additions & 60 deletions src/vorta/assets/UI/sourcetab.ui
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="2,1">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="2">
<property name="spacing">
<number>12</number>
</property>
@@ -112,6 +112,16 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="bExclude">
<property name="text">
<string>Manage Excluded Items…</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -147,65 +157,6 @@
</layout>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,1">
<property name="topMargin">
<number>12</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exclude Patterns (&lt;a href=&quot;https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-help-patterns&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0984e3;&quot;&gt;more&lt;/span&gt;&lt;/a&gt;):&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Exclude If Present (exclude folders with these files):</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPlainTextEdit" name="excludePatternsField">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContentsOnFirstShow</enum>
</property>
<property name="plainText">
<string/>
</property>
<property name="placeholderText">
<string>E.g. */.cache</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPlainTextEdit" name="excludeIfPresentField">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContentsOnFirstShow</enum>
</property>
<property name="placeholderText">
<string>E.g. .nobackup</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
71 changes: 71 additions & 0 deletions src/vorta/assets/exclusion_presets/browsers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
[
{
"name": "Chromium cache and config files",
"slug": "chromium-cache",
"patterns":
[
"fm:*/.config/chromium/*/Local Storage",
"fm:*/.config/chromium/*/Session Storage",
"fm:*/.config/chromium/*/Service Worker/CacheStorage",
"fm:*/.config/chromium/*/Application Cache",
"fm:*/.config/chromium/*/History Index *",
"fm:*/snap/chromium/common/.cache",
"fm:*/snap/chromium/*/.config/chromium/*/Service Worker/CacheStorage",
"fm:*/snap/chromium/*/.local/share/"
],
"tags":["application:chromium", "type:browser", "os:linux"],
"author": "Divi"
},
{
"name": "Google Chrome cache and config files",
"slug": "google-chrome-cache",
"patterns":
[
"fm:*/.config/google-chrome/ShaderCache",
"fm:*/.config/google-chrome/*/Local Storage",
"fm:*/.config/google-chrome/*/Session Storage",
"fm:*/.config/google-chrome/*/Application Cache",
"fm:*/.config/google-chrome/*/History Index *",
"fm:*/.config/google-chrome/*/Service Worker/CacheStorage"
],
"tags": ["application:chrome", "type:browser", "os:linux"],
"author": "Divi"
},
{
"name": "Brave cache and config files",
"slug": "brave-cache",
"patterns":[
"fm:*/.config/BraveSoftware/Brave-Browser/*/Feature Engagement Tracker/",
"fm:*/.config/BraveSoftware/Brave-Browser/*/Local Storage/",
"fm:*/.config/BraveSoftware/Brave-Browser/*/Service Worker/CacheStorage/",
"fm:*/.config/BraveSoftware/Brave-Browser/*/Session Storage/",
"fm:*/.config/BraveSoftware/Brave-Browser/Safe Browsing/",
"fm:*/.config/BraveSoftware/Brave-Browser/ShaderCache/"
],
"tags": ["application:brave", "type:browser", "os:linux"],
"author": "Divi"
},
{
"name": "Mozilla Firefox cache and config files",
"slug": "firefox-cache",
"patterns":[
"fm:*/.mozilla/firefox/*/Cache",
"fm:*/.mozilla/firefox/*/minidumps",
"fm:*/.mozilla/firefox/*/.parentlock",
"fm:*/.mozilla/firefox/*/urlclassifier3.sqlite",
"fm:*/.mozilla/firefox/*/blocklist.xml",
"fm:*/.mozilla/firefox/*/extensions.sqlite",
"fm:*/.mozilla/firefox/*/extensions.sqlite-journal",
"fm:*/.mozilla/firefox/*/extensions.rdf",
"fm:*/.mozilla/firefox/*/extensions.ini",
"fm:*/.mozilla/firefox/*/extensions.cache",
"fm:*/.mozilla/firefox/*/XUL.mfasl",
"fm:*/.mozilla/firefox/*/XPC.mfasl",
"fm:*/.mozilla/firefox/*/xpti.dat",
"fm:*/.mozilla/firefox/*/compreg.dat",
"fm:*/.mozilla/firefox/*/pluginreg.dat"
],
"tags": ["application:firefox", "type:browser", "os:linux"],
"author": "Divi"
}
]
37 changes: 37 additions & 0 deletions src/vorta/assets/exclusion_presets/dev.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[
{
"name": "Node Modules and package manager cache",
"slug": "node-cache",
"patterns":
[
"fm:*/node_modules",
"fm:*/.npm"
],
"tags": ["type:dev", "lang:javascript", "os:linux", "os:darwin"],
"author": "Divi"
},
{
"name": "Python cache and virtualenv",
"slug": "python-cache",
"patterns":
[
"fm:*/__pycache__",
"fm:*.pyc",
"fm:*.pyo",
"fm:*/.virtualenvs"
],
"tags": ["type:dev", "lang:python", "os:linux", "os:darwin"],
"author": "Divi"
},
{
"name": "Rust artefacts",
"slug": "rust-artefacts",
"patterns":
[
"fm:*/.cargo",
"fm:*/.rustup"
],
"tags": ["type:dev", "lang:rust", "os:linux", "os:darwin"],
"author": "Divi"
}
]
204 changes: 204 additions & 0 deletions src/vorta/assets/icons/APACHE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/!\ The Apache version 2 license applies to all SVG icon files in this directory that
have a copyright header referring to "Material Design icons by Google".

Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.

"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.

"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.

"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.

"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.

"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.

"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).

"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.

"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."

"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:

(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and

(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and

(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and

(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.

You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
99 changes: 99 additions & 0 deletions src/vorta/assets/icons/OFL.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/!\ The SIL OPEN FONT LICENSE applies to all SVG icon files in this directory that
don't have any other copyright information.


Copyright (c) 2018, Fork Awesome (https://forkawesome.github.io),
with Reserved Font Name Fork Awesome.


This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
8 changes: 2 additions & 6 deletions src/vorta/assets/icons/angle-down-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 2 additions & 5 deletions src/vorta/assets/icons/angle-up-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/vorta/assets/icons/broom-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/vorta/assets/icons/copy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 13 additions & 7 deletions src/vorta/assets/icons/eye-slash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 10 additions & 1 deletion src/vorta/assets/icons/eye.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
315 changes: 315 additions & 0 deletions src/vorta/assets/icons/gpl_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 1 addition & 6 deletions src/vorta/assets/icons/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
265 changes: 265 additions & 0 deletions src/vorta/assets/icons/python_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/vorta/assets/icons/settings_wheel.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit ac624ed

Please sign in to comment.