mirror of https://github.com/qarmin/czkawka
Compare commits
143 Commits
Author | SHA1 | Date |
---|---|---|
Rafał Mikrut | 2a32a52aa8 | 3 months ago |
Rafał Mikrut | e5a0219bc9 | 3 months ago |
Rafał Mikrut | 4dbc26e18c | 3 months ago |
Rafał Mikrut | c58569eaa0 | 3 months ago |
Rafał Mikrut | 8109a826b9 | 3 months ago |
Rafał Mikrut | 51b802205b | 3 months ago |
Rafał Mikrut | 0446ff366c | 3 months ago |
Thomas Andreas Jung | 9599ed5377 | 3 months ago |
Rafał Mikrut | 378fa1fd6e | 4 months ago |
Thomas Andreas Jung | b63c631e14 | 4 months ago |
codingnewcode | 0cc115c96e | 4 months ago |
Tom Praschan | a5f89fbaad | 4 months ago |
Rafał Mikrut | 6cde5ab7a0 | 5 months ago |
Rafał Mikrut | 0defcbd253 | 5 months ago |
Rafał Mikrut | bf78fc8b57 | 6 months ago |
Rafał Mikrut | 219f9f058b | 6 months ago |
Rafał Mikrut | 739e2a9860 | 6 months ago |
Rafał Mikrut | 51198c2043 | 6 months ago |
rugk | 306648a37d | 6 months ago |
Rafał Mikrut | 9228f45f7a | 6 months ago |
Rafał Mikrut | c6b1eaeeb4 | 6 months ago |
Aarni Koskela | 8df5e991a6 | 7 months ago |
Rafał Mikrut | 99277b9ea5 | 8 months ago |
Rafał Mikrut | 59ff9f3e3c | 8 months ago |
Rafał Mikrut | 44400e08af | 8 months ago |
Rafał Mikrut | 0f7aa95a64 | 8 months ago |
Rafał Mikrut | e92a8a65de | 8 months ago |
Rafał Mikrut | 9072b0cc98 | 8 months ago |
Rafał Mikrut | 8b20f78573 | 8 months ago |
Rafał Mikrut | e50d930683 | 8 months ago |
Rafał Mikrut | 0462324607 | 8 months ago |
Rafał Mikrut | 9b57382e39 | 8 months ago |
Rafał Mikrut | 4a1f6227db | 8 months ago |
Rafał Mikrut | bb2806fa05 | 8 months ago |
Rafał Mikrut | e976d40eee | 8 months ago |
Rafał Mikrut | edfc8e7b5f | 8 months ago |
undefined-landmark | 30068b58d3 | 8 months ago |
Nick Gallimore | 14bd35a73b | 8 months ago |
Rafał Mikrut | a77cb27f3b | 11 months ago |
Jocelyn Le Sage | 2dabb788e6 | 11 months ago |
Jocelyn Le Sage | 9e6cc35783 | 11 months ago |
Rafał Mikrut | c36c841d9f | 12 months ago |
Rafał Mikrut | 7cb355a359 | 12 months ago |
Rafał Mikrut | 55b2744bf4 | 12 months ago |
Rafał Mikrut | 04a91aeca7 | 1 year ago |
Rafał Mikrut | 582e5417ac | 1 year ago |
Rafał Mikrut | 78d00eeb99 | 1 year ago |
Liru Wilkowski | 14ccb49e45 | 1 year ago |
Rafał Mikrut | 72df211ca2 | 1 year ago |
santiago fn | 67e648a5ab | 1 year ago |
Tom Paine | 0d4ae0a31b | 1 year ago |
Rafał Mikrut | 5272309341 | 1 year ago |
Alexis Lefebvre | de4edba380 | 1 year ago |
Alexis Lefebvre | e524f23e8c | 1 year ago |
Alexis Lefebvre | 336bbd3057 | 1 year ago |
Rafał Mikrut | 329fc8f93d | 1 year ago |
Rafał Mikrut | de9f70310a | 1 year ago |
Rafał Mikrut | 1c76d3426c | 1 year ago |
Fr_Dae | 699da09a54 | 1 year ago |
Rafał Mikrut | c6c4230699 | 1 year ago |
Rafał Mikrut | 27410bcd45 | 1 year ago |
Rafał Mikrut | f1c6e6da17 | 1 year ago |
Rafał Mikrut | 8ea9b4b800 | 1 year ago |
Rodrigo Torres | d39354a51f | 1 year ago |
Rafał Mikrut | 8ab4c19eea | 1 year ago |
Rafał Mikrut | 8e24492416 | 1 year ago |
Rafał Mikrut | c9e9a65cc9 | 1 year ago |
Alex | e6b19270a6 | 1 year ago |
Rafał Mikrut | b27a95e547 | 2 years ago |
Rafał Mikrut | a66a2849d1 | 2 years ago |
Rafał Mikrut | b1fde3becc | 2 years ago |
Rafał Mikrut | 53492395c5 | 2 years ago |
Kian-Meng Ang | ddc4def99e | 2 years ago |
OMEGA_RAZER | 42ecc94deb | 2 years ago |
Dominik Piątkowski | c549057cc8 | 2 years ago |
Rafał Mikrut | e731f5ed75 | 2 years ago |
Rafał Mikrut | f16818dc8e | 2 years ago |
Rafał Mikrut | d29935d208 | 2 years ago |
Rafał Mikrut | 24b64a32c6 | 2 years ago |
Rafał Mikrut | d3e7c2d777 | 2 years ago |
0x4A6F | e20f30c66f | 2 years ago |
Alexis Lefebvre | 95d1d73a29 | 2 years ago |
Rafał Mikrut | ae87489f3b | 2 years ago |
Rafał Mikrut | 7d654a7899 | 2 years ago |
alexdraconian | 624be66b4d | 2 years ago |
Rafał Mikrut | 44fb75ada5 | 2 years ago |
Rafał Mikrut | 67db713a05 | 2 years ago |
Rafał Mikrut | 97563a7b2a | 2 years ago |
Rafał Mikrut | 5d79dc7ccf | 2 years ago |
Rafał Mikrut | 390f4751e8 | 2 years ago |
Rafał Mikrut | bf9dd352dd | 2 years ago |
Rafał Mikrut | d5b08787a0 | 2 years ago |
Rafał Mikrut | 2f932e20ff | 2 years ago |
Rafał Mikrut | 8f0527cd33 | 2 years ago |
Rafał Mikrut | 07cfc7884f | 2 years ago |
Rafał Mikrut | e3cea67634 | 2 years ago |
Rafał Mikrut | d1c66fda1b | 2 years ago |
Rafał Mikrut | 4765bee87f | 2 years ago |
Rafał Mikrut | d42e17c15f | 2 years ago |
Rafał Mikrut | 486bec15ad | 2 years ago |
Rafał Mikrut | db09dc9363 | 2 years ago |
Rafał Mikrut | 56fc29fa4f | 2 years ago |
Rafał Mikrut | ec13f86aee | 2 years ago |
Rafał Mikrut | cf94ab918e | 2 years ago |
Rafał Mikrut | 5119a377c7 | 2 years ago |
Rafał Mikrut | 3748411ebd | 2 years ago |
Rafał Mikrut | 19afce5d2e | 2 years ago |
Rafał Mikrut | 6d8b33d8cf | 2 years ago |
Dominik Piątkowski | 849eb5a637 | 2 years ago |
Joey Babcock | da061e8037 | 2 years ago |
ChihWei Wang | 96def07bc9 | 2 years ago |
Rafał Mikrut | a54224fbd0 | 2 years ago |
Rafał Mikrut | 073ae6f72f | 2 years ago |
Alexis Lefebvre | 637e97e66d | 2 years ago |
Rafał Mikrut | dd103b9520 | 2 years ago |
Rafał Mikrut | cb7e9573ef | 2 years ago |
Rafał Mikrut | 58b3d3e556 | 2 years ago |
Rafał Mikrut | b00420d8c0 | 2 years ago |
Rafał Mikrut | 642a6369f3 | 2 years ago |
Kerfuffle | c48b355bf0 | 2 years ago |
ChihWei Wang | c64ab05648 | 2 years ago |
Gitoffthelawn | 0a35e542a3 | 2 years ago |
Rafał Mikrut | 8e4e1f58cb | 2 years ago |
Rafał Mikrut | c88d347e00 | 2 years ago |
Rafał Mikrut | aa07d73bca | 2 years ago |
Rafał Mikrut | 12a873ff66 | 2 years ago |
Rafał Mikrut | 574cc78b12 | 2 years ago |
Rafał Mikrut | 39b2f4bc36 | 2 years ago |
Rafał Mikrut | f843673c7e | 2 years ago |
Rafał Mikrut | c13f9255e2 | 2 years ago |
Rafał Mikrut | 2d8a930ae5 | 2 years ago |
bakeromso | ebbbec414c | 2 years ago |
Rafał Mikrut | 6ed2e92702 | 2 years ago |
Rafał Mikrut | 91a9e56114 | 2 years ago |
Rafał Mikrut | 3ce5d4a967 | 2 years ago |
Rafał Mikrut | ff71e2b57a | 2 years ago |
Kerfuffle | 2b86e9079e | 2 years ago |
TheEvilSkeleton | 7d32f1c778 | 2 years ago |
Rafał Mikrut | 4427ec06c0 | 2 years ago |
Alexis Lefebvre | c7ff65c11a | 2 years ago |
Ivan Habernal | 37b61b0c4c | 2 years ago |
cyqsimon | 8fe7a10f74 | 2 years ago |
TheEvilSkeleton | 01101123e6 | 2 years ago |
@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve app
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Bug Description**
|
||||
|
||||
|
||||
**Steps to reproduce:**
|
||||
<!-- Please describe what you expected to see and what you saw instead. Also include screenshots or screencasts if needed. -->
|
||||
|
||||
|
||||
**Terminal output** (optional):
|
||||
```
|
||||
<!--
|
||||
Add terminal output only if needed - if there are some errors or warnings or you have performance/freeze issues.
|
||||
Very helpful in this situation will be logs from czkawka run with RUST_LOG environment variable set e.g.
|
||||
`RUST_LOG=debug ./czkawka` or `flatpak run --env=RUST_LOG=debug com.github.qarmin.czkawka` if you use flatpak, which will print more detailed info about executed function.
|
||||
-->
|
||||
|
||||
<details>
|
||||
<summary>Debug log</summary>
|
||||
|
||||
# UNCOMMENT DETAILS AND PUT LOGS HERE
|
||||
|
||||
</details>
|
||||
```
|
||||
|
||||
|
||||
**System**
|
||||
|
||||
- Czkawka/Krokiet version: <!-- e.g. 7.0.0 cli/gui -->
|
||||
- OS version: <!-- e.g Ubuntu 22.04, Windows 11, Mac 15.1 ARM -->
|
||||
- Installation method: <!-- e.g. github binaries, snap, flatpak, msys2 -->
|
||||
|
||||
<!-- If you use flatpak, please include the result of `flatpak info com.github.qarmin.czkawka`. -->
|
@ -0,0 +1,11 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Feature Description**
|
||||
...
|
@ -1,239 +0,0 @@
|
||||
name: 🐧 Linux
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 * * 2'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
linux-cli:
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [ stable ]
|
||||
type: [ release ]
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
override: true
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
target
|
||||
key: linux-cli-${{github.ref}}-${{github.sha}}
|
||||
restore-keys: |
|
||||
linux-cli-${{github.ref}}-${{github.sha}}
|
||||
|
||||
- name: Install basic libraries
|
||||
run: sudo apt-get update; sudo apt install libgtk-3-dev libasound2-dev -y
|
||||
|
||||
- name: Build CLI Debug
|
||||
run: cargo build --bin czkawka_cli
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0 -D warnings"
|
||||
if: ${{ matrix.type == 'debug'}}
|
||||
|
||||
- name: Build CLI Release
|
||||
run: cargo build --release --bin czkawka_cli
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0 -D warnings"
|
||||
if: ${{ matrix.type == 'release'}}
|
||||
|
||||
- name: Store Linux CLI
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: czkawka_cli-${{ runner.os }}-${{ matrix.toolchain }}
|
||||
path: target/release/czkawka_cli
|
||||
if: ${{ matrix.type == 'release' }}
|
||||
|
||||
# Duplicate finder checks included and excluded directories
|
||||
# Others are just check delete files number
|
||||
- name: Linux Regression Test
|
||||
run: |
|
||||
wget https://github.com/qarmin/czkawka/releases/download/1.1.0/TestSuite.zip
|
||||
unzip TestSuite.zip -d TestSuite
|
||||
python3 misc/check_results.py TestSuite 15 8
|
||||
|
||||
|
||||
target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -D aen -m 1024
|
||||
python3 misc/check_results.py TestSuite 7 8
|
||||
|
||||
rm -rf TestSuite
|
||||
unzip TestSuite.zip -d TestSuite
|
||||
|
||||
target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -D aen -m 1024
|
||||
python3 misc/check_results.py TestSuite 7 8
|
||||
|
||||
rm -rf TestSuite
|
||||
unzip TestSuite.zip -d TestSuite
|
||||
|
||||
target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -x TEXT -D aeo -m 1024
|
||||
python3 misc/check_results.py TestSuite 14 8
|
||||
|
||||
rm -rf TestSuite
|
||||
unzip TestSuite.zip -d TestSuite
|
||||
|
||||
target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -e "$(pwd)/TestSuite/SubFolder" -D aeo -m 1024
|
||||
python3 misc/check_results.py TestSuite 13 8
|
||||
|
||||
rm -rf TestSuite
|
||||
unzip TestSuite.zip -d TestSuite
|
||||
|
||||
target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -m 1500 -D aeo
|
||||
python3 misc/check_results.py TestSuite 8 8
|
||||
|
||||
rm -rf TestSuite
|
||||
unzip TestSuite.zip -d TestSuite
|
||||
|
||||
target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -R -m 1024
|
||||
python3 misc/check_results.py TestSuite 15 8
|
||||
target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -R -D aeo -m 1024
|
||||
python3 misc/check_results.py TestSuite 13 8
|
||||
|
||||
|
||||
target/release/czkawka_cli big -d "$(pwd)/TestSuite"
|
||||
|
||||
rm -rf TestSuite
|
||||
unzip TestSuite.zip -d TestSuite
|
||||
|
||||
target/release/czkawka_cli empty-files -d "$(pwd)/TestSuite"
|
||||
python3 misc/check_results.py TestSuite 15 8
|
||||
target/release/czkawka_cli empty-files -d "$(pwd)/TestSuite" -D
|
||||
python3 misc/check_results.py TestSuite 13 8
|
||||
|
||||
rm -rf TestSuite
|
||||
unzip TestSuite.zip -d TestSuite
|
||||
|
||||
target/release/czkawka_cli empty-folders -d "$(pwd)/TestSuite"
|
||||
python3 misc/check_results.py TestSuite 15 8
|
||||
target/release/czkawka_cli empty-folders -d "$(pwd)/TestSuite" -D
|
||||
python3 misc/check_results.py TestSuite 15 2
|
||||
|
||||
rm -rf TestSuite
|
||||
unzip TestSuite.zip -d TestSuite
|
||||
|
||||
target/release/czkawka_cli temp -d "$(pwd)/TestSuite"
|
||||
python3 misc/check_results.py TestSuite 15 8
|
||||
target/release/czkawka_cli temp -d "$(pwd)/TestSuite" -D
|
||||
python3 misc/check_results.py TestSuite 14 8
|
||||
if: ${{ matrix.type == 'release' }}
|
||||
|
||||
linux-gui:
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [ stable, 1.53.0 ]
|
||||
type: [ release ]
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
override: true
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
target
|
||||
key: linux-gui-${{github.ref}}-${{github.sha}}
|
||||
restore-keys: |
|
||||
linux-gui-${{github.ref}}-${{github.sha}}
|
||||
|
||||
- name: Install Gtk, Mingw, unzip, zip and wget
|
||||
run: sudo apt-get update; sudo apt install libgtk-3-dev libasound2-dev -y
|
||||
|
||||
- name: Build GUI Debug
|
||||
run: cargo build --bin czkawka_gui
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0 -D warnings"
|
||||
if: ${{ matrix.type == 'debug'}}
|
||||
|
||||
- name: Build GUI Release
|
||||
run: cargo build --release --bin czkawka_gui
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0 -D warnings"
|
||||
if: ${{ matrix.type == 'release'}}
|
||||
|
||||
- name: Store Linux GUI
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: czkawka_gui-${{ runner.os }}-${{ matrix.toolchain }}
|
||||
path: target/release/czkawka_gui
|
||||
if: ${{ matrix.type == 'release' }}
|
||||
|
||||
- name: Minimal AppImage
|
||||
run: |
|
||||
pwd
|
||||
rm -rf czkawka_gui
|
||||
cp target/release/czkawka_gui .
|
||||
strip czkawka_gui
|
||||
wget https://github.com/AppImage/pkg2appimage/releases/download/continuous/pkg2appimage-1807-x86_64.AppImage
|
||||
chmod +x pkg2appimage-1807-x86_64.AppImage
|
||||
./pkg2appimage-1807-x86_64.AppImage misc/czkawka-appimage-recipe.yml
|
||||
mv out/Czkawka*.AppImage out/czkawka_gui-minimal.AppImage
|
||||
|
||||
- name: Minimal Appimage Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: czkawka_gui-${{ matrix.toolchain }}_minimal_AppImage
|
||||
path: out/*.AppImage
|
||||
|
||||
|
||||
linux-appimage-gui:
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [ stable ]
|
||||
type: [ release ]
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
override: true
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
target
|
||||
key: linux-appimage-gui-${{github.ref}}-${{github.sha}}
|
||||
restore-keys: |
|
||||
linux-appimage-gui-${{github.ref}}-${{github.sha}}
|
||||
|
||||
- name: Install Gtk,
|
||||
run: sudo apt-get update; sudo apt install libgtk-3-dev libasound2-dev librsvg2-dev wget -y
|
||||
|
||||
- name: Build GUI Release
|
||||
run: cargo build --release --bin czkawka_gui
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0 -D warnings"
|
||||
|
||||
- name: Download appimage dependiences
|
||||
run: |
|
||||
wget -c "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh"
|
||||
wget -c "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
|
||||
chmod +x linuxdeploy-plugin-gtk.sh
|
||||
chmod +x linuxdeploy-x86_64.AppImage
|
||||
mkdir -p AppDir/usr/bin
|
||||
cp target/release/czkawka_gui AppDir/usr/bin
|
||||
./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin gtk --output appimage --icon-file data/icons/com.github.qarmin.czkawka.svg --desktop-file data/com.github.qarmin.czkawka.desktop
|
||||
|
||||
- name: Store Linux Appimage GUI
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: czkawka_gui-appimage-${{ runner.os }}-${{ matrix.toolchain }}
|
||||
path: Czkawka*.AppImage
|
@ -0,0 +1,50 @@
|
||||
name: 🐧 Linux CLI
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 * * 2'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
linux-cli:
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [ stable, 1.75.0 ]
|
||||
type: [ release ]
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install basic libraries
|
||||
run: sudo apt update || true; sudo apt install libheif-dev ffmpeg -y
|
||||
|
||||
- name: Setup rust version
|
||||
run: rustup default ${{ matrix.toolchain }}
|
||||
|
||||
- name: Enable LTO
|
||||
run: sed -i 's/#lto = "thin"/lto = "thin"/g' Cargo.toml
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Build Release
|
||||
run: cargo build --release --bin czkawka_cli
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Store Linux CLI
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: czkawka_cli-${{ runner.os }}-${{ matrix.toolchain }}
|
||||
path: target/release/czkawka_cli
|
||||
if: ${{ matrix.type == 'release' }}
|
||||
|
||||
- name: Linux Regression Test
|
||||
run: |
|
||||
wget https://github.com/qarmin/czkawka/releases/download/6.0.0/TestFiles.zip
|
||||
cd ci_tester
|
||||
cargo build --release
|
||||
cd ..
|
||||
|
||||
ci_tester/target/release/ci_tester target/release/czkawka_cli
|
||||
if: ${{ matrix.type == 'release' }}
|
@ -0,0 +1,58 @@
|
||||
name: 🐧 Linux CLI Eyra
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 * * 2'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
linux-cli:
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [ nightly ]
|
||||
type: [ release ]
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install basic libraries
|
||||
run: sudo apt update || true; sudo apt install -y ffmpeg
|
||||
|
||||
# New versions of nightly rust may call new unimplemented in eyra functions, so use const version
|
||||
- name: Setup rust version
|
||||
run: rustup default nightly-2024-02-06
|
||||
|
||||
- name: Add eyra
|
||||
run: |
|
||||
cd czkawka_cli
|
||||
cargo add eyra --rename=std
|
||||
echo 'fn main() { println!("cargo:rustc-link-arg=-nostartfiles"); }' > build.rs
|
||||
cd ..
|
||||
|
||||
- name: Enable LTO
|
||||
run: sed -i 's/#lto = "thin"/lto = "thin"/g' Cargo.toml
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Build Release
|
||||
run: cargo build --release --bin czkawka_cli
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Store Linux CLI
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: czkawka_cli-${{ runner.os }}-${{ matrix.toolchain }}
|
||||
path: target/release/czkawka_cli
|
||||
if: ${{ matrix.type == 'release' }}
|
||||
|
||||
- name: Linux Regression Test
|
||||
run: |
|
||||
wget https://github.com/qarmin/czkawka/releases/download/6.0.0/TestFiles.zip
|
||||
cd ci_tester
|
||||
cargo build --release
|
||||
cd ..
|
||||
|
||||
ci_tester/target/release/ci_tester target/release/czkawka_cli
|
||||
if: ${{ matrix.type == 'release' }}
|
@ -0,0 +1,184 @@
|
||||
name: 🐧 Linux GUI
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 * * 2'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
linux-krokiet-gui:
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [ stable, 1.75.0 ]
|
||||
type: [ release ]
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup rust version
|
||||
run: rustup default ${{ matrix.toolchain }}
|
||||
|
||||
- name: Enable LTO
|
||||
run: sed -i 's/#lto = "thin"/lto = "thin"/g' Cargo.toml
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Build Release Krokiet
|
||||
run: cargo build --release --bin krokiet
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Store Linux GUI Krokiet
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: krokiet-${{ runner.os }}-${{ matrix.toolchain }}
|
||||
path: target/release/krokiet
|
||||
if: ${{ matrix.type == 'release' }}
|
||||
|
||||
linux-krokiet-gui-heif:
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [ stable, 1.75.0 ]
|
||||
type: [ release ]
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install basic libraries
|
||||
run: sudo apt update || true; sudo apt install libheif-dev libraw-dev -y
|
||||
|
||||
- name: Setup rust version
|
||||
run: rustup default ${{ matrix.toolchain }}
|
||||
|
||||
- name: Enable LTO
|
||||
run: sed -i 's/#lto = "thin"/lto = "thin"/g' Cargo.toml
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Build Release Krokiet heif
|
||||
run: cargo build --release --bin krokiet --features "heif,libraw"
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Store Linux GUI Krokiet heif libraw
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: krokiet-${{ runner.os }}-${{ matrix.toolchain }}-heif-libraw
|
||||
path: target/release/krokiet
|
||||
if: ${{ matrix.type == 'release' }}
|
||||
|
||||
linux-gui:
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [ stable, 1.75.0 ]
|
||||
type: [ release ]
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install basic libraries
|
||||
run: sudo apt update || true; sudo apt install libgtk-4-dev libheif-dev libraw-dev -y
|
||||
|
||||
- name: Setup rust version
|
||||
run: rustup default ${{ matrix.toolchain }}
|
||||
|
||||
- name: Enable LTO
|
||||
run: sed -i 's/#lto = "thin"/lto = "thin"/g' Cargo.toml
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Build Release Heif Libraw
|
||||
run: cargo build --release --bin czkawka_gui --features "heif,libraw"
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Store Linux GUI Heif Libraw
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: czkawka_gui-${{ runner.os }}-${{ matrix.toolchain }}-heif-libraw
|
||||
path: target/release/czkawka_gui
|
||||
if: ${{ (matrix.type == 'release') && (matrix.toolchain == 'stable') }}
|
||||
|
||||
- name: Build Release
|
||||
run: cargo build --release --bin czkawka_gui
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
# Only store stable toolchain
|
||||
- name: Store Linux GUI
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: czkawka_gui-${{ runner.os }}-${{ matrix.toolchain }}
|
||||
path: target/release/czkawka_gui
|
||||
if: ${{ (matrix.type == 'release') && (matrix.toolchain == 'stable') }}
|
||||
|
||||
linux-appimage-gui:
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [ stable ]
|
||||
type: [ release ]
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
run: sudo apt update || true; sudo apt install libgtk-4-dev libheif-dev librsvg2-dev wget fuse libfuse2 -y
|
||||
|
||||
- name: Setup rust version
|
||||
run: rustup default ${{ matrix.toolchain }}
|
||||
|
||||
- name: Enable LTO
|
||||
run: sed -i 's/#lto = "thin"/lto = "thin"/g' Cargo.toml
|
||||
if: ${{ (matrix.type == 'release') }}
|
||||
|
||||
- name: Build Release
|
||||
run: cargo build --release --bin czkawka_gui
|
||||
|
||||
- name: Download appimage dependencies
|
||||
run: |
|
||||
pwd
|
||||
wget -c "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh"
|
||||
wget -c "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
|
||||
chmod +x linuxdeploy-plugin-gtk.sh
|
||||
chmod +x linuxdeploy-x86_64.AppImage
|
||||
mkdir -p AppDir/usr/bin
|
||||
pwd
|
||||
cp target/release/czkawka_gui AppDir/usr/bin
|
||||
./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin gtk --output appimage --icon-file data/icons/com.github.qarmin.czkawka.svg --desktop-file data/com.github.qarmin.czkawka.desktop
|
||||
|
||||
- name: Store Linux Appimage GUI
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: czkawka_gui-appimage-${{ runner.os }}-${{ matrix.toolchain }}
|
||||
path: Czkawka*.AppImage
|
||||
|
||||
- name: Minimal AppImage
|
||||
run: |
|
||||
pwd
|
||||
rm -rf czkawka_gui
|
||||
cp target/release/czkawka_gui .
|
||||
strip czkawka_gui
|
||||
wget https://github.com/AppImageCommunity/pkg2appimage/releases/download/continuous/pkg2appimage--x86_64.AppImage -O pkg2.appimage
|
||||
chmod +x ./pkg2.appimage
|
||||
./pkg2.appimage misc/czkawka-appimage-recipe.yml
|
||||
mv out/Czkawka*.AppImage out/czkawka_gui-minimal.AppImage
|
||||
|
||||
- name: Minimal Appimage Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: czkawka_gui-${{ matrix.toolchain }}_minimal_AppImage
|
||||
path: out/*.AppImage
|
||||
|
||||
linux-tests:
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain: [ stable ]
|
||||
type: [ debug ]
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
run: sudo apt update || true; sudo apt install libgtk-4-dev libheif-dev librsvg2-dev wget fuse libfuse2 -y xvfb
|
||||
|
||||
- name: Setup rust version
|
||||
run: rustup default ${{ matrix.toolchain }}
|
||||
|
||||
- name: Test
|
||||
run: xvfb-run cargo test
|
@ -0,0 +1,2 @@
|
||||
TheEvilSkeleton <theevilskeleton@riseup.net> Proprietary Chrome-chan <theevilskeleton@riseup.net>
|
||||
Rafał Mikrut <mikrutrafal@protonmail.com> <mikrutrafal54@gmail.com> <41945903+qarmin@users.noreply.github.com>
|
@ -1,3 +1,6 @@
|
||||
newline_style = "Unix"
|
||||
max_width = 180
|
||||
remove_nested_parens = true
|
||||
|
||||
# Enable only with nightly channel via - cargo +nightly fmt
|
||||
imports_granularity = "Module"
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "ci_tester"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
state = "0.6.0"
|
||||
handsome_logger = "0.8.0"
|
||||
log = "0.4.20"
|
@ -0,0 +1,339 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
use std::process::Stdio;
|
||||
|
||||
use log::info;
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
struct CollectedFiles {
|
||||
files: BTreeSet<String>,
|
||||
folders: BTreeSet<String>,
|
||||
symlinks: BTreeSet<String>,
|
||||
}
|
||||
|
||||
static CZKAWKA_PATH: state::InitCell<String> = state::InitCell::new();
|
||||
static COLLECTED_FILES: state::InitCell<CollectedFiles> = state::InitCell::new();
|
||||
|
||||
const ATTEMPTS: u32 = 10;
|
||||
const PRINT_MESSAGES_CZKAWKA: bool = true;
|
||||
|
||||
// App runs - ./ci_tester PATH_TO_CZKAWKA
|
||||
fn main() {
|
||||
handsome_logger::init().unwrap();
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let path_to_czkawka = args[1].clone();
|
||||
CZKAWKA_PATH.set(path_to_czkawka);
|
||||
remove_test_dir();
|
||||
run_with_good_status(&["ls"], false);
|
||||
unzip_files();
|
||||
|
||||
let all_files = collect_all_files_and_dirs("TestFiles").unwrap();
|
||||
COLLECTED_FILES.set(all_files);
|
||||
remove_test_dir();
|
||||
|
||||
for _ in 0..ATTEMPTS {
|
||||
test_empty_files();
|
||||
test_smallest_files();
|
||||
test_biggest_files();
|
||||
test_empty_folders();
|
||||
test_temporary_files();
|
||||
test_symlinks_files();
|
||||
test_remove_duplicates_one_oldest();
|
||||
test_remove_duplicates_one_newest();
|
||||
test_remove_duplicates_all_expect_newest();
|
||||
test_remove_duplicates_all_expect_oldest();
|
||||
test_remove_same_music_tags_one_oldest();
|
||||
test_remove_same_music_tags_one_newest();
|
||||
test_remove_same_music_tags_all_expect_oldest();
|
||||
test_remove_same_music_tags_all_expect_newest();
|
||||
test_remove_same_music_content_one_oldest();
|
||||
test_remove_same_music_content_all_expect_oldest();
|
||||
test_remove_same_music_content_one_newest();
|
||||
test_remove_same_music_content_all_expect_newest();
|
||||
test_remove_videos_one_oldest();
|
||||
test_remove_videos_one_newest();
|
||||
test_remove_videos_all_expect_oldest();
|
||||
test_remove_videos_all_expect_newest();
|
||||
}
|
||||
|
||||
println!("Completed checking");
|
||||
}
|
||||
fn test_remove_videos_one_oldest() {
|
||||
info!("test_remove_videos_one_oldest");
|
||||
run_test(&["video", "-d", "TestFiles", "-D", "OO"], vec!["Videos/V3.webm"], vec![], vec![]);
|
||||
}
|
||||
fn test_remove_videos_one_newest() {
|
||||
info!("test_remove_videos_one_newest");
|
||||
run_test(&["video", "-d", "TestFiles", "-D", "ON"], vec!["Videos/V5.mp4"], vec![], vec![]);
|
||||
}
|
||||
fn test_remove_videos_all_expect_oldest() {
|
||||
info!("test_remove_videos_all_expect_oldest");
|
||||
run_test(
|
||||
&["video", "-d", "TestFiles", "-D", "AEO"],
|
||||
vec!["Videos/V1.mp4", "Videos/V2.mp4", "Videos/V5.mp4"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
fn test_remove_videos_all_expect_newest() {
|
||||
info!("test_remove_videos_all_expect_newest");
|
||||
run_test(
|
||||
&["video", "-d", "TestFiles", "-D", "AEN"],
|
||||
vec!["Videos/V1.mp4", "Videos/V2.mp4", "Videos/V3.webm"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
fn test_remove_same_music_content_one_newest() {
|
||||
info!("test_remove_same_music_content_one_newest");
|
||||
run_test(
|
||||
&["music", "-d", "TestFiles", "-s", "CONTENT", "-l", "2.0", "-D", "ON"],
|
||||
vec!["Music/M2.mp3"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
fn test_remove_same_music_content_all_expect_newest() {
|
||||
info!("test_remove_same_music_content_all_expect_newest");
|
||||
run_test(
|
||||
&["music", "-d", "TestFiles", "-s", "CONTENT", "-l", "2.0", "-D", "AEN"],
|
||||
vec!["Music/M1.mp3", "Music/M3.flac", "Music/M5.mp3"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
fn test_remove_same_music_content_all_expect_oldest() {
|
||||
info!("test_remove_same_music_content_all_expect_oldest");
|
||||
run_test(
|
||||
&["music", "-d", "TestFiles", "-s", "CONTENT", "-l", "2.0", "-D", "AEO"],
|
||||
vec!["Music/M1.mp3", "Music/M2.mp3", "Music/M3.flac"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
fn test_remove_same_music_content_one_oldest() {
|
||||
info!("test_remove_same_music_content_one_oldest");
|
||||
run_test(
|
||||
&["music", "-d", "TestFiles", "-s", "CONTENT", "-l", "2.0", "-D", "OO"],
|
||||
vec!["Music/M5.mp3"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
fn test_remove_same_music_tags_one_oldest() {
|
||||
info!("test_remove_same_music_one_oldest");
|
||||
run_test(&["music", "-d", "TestFiles", "-D", "OO"], vec!["Music/M5.mp3"], vec![], vec![]);
|
||||
}
|
||||
fn test_remove_same_music_tags_one_newest() {
|
||||
info!("test_remove_same_music_one_newest");
|
||||
run_test(&["music", "-d", "TestFiles", "-D", "ON"], vec!["Music/M2.mp3"], vec![], vec![]);
|
||||
}
|
||||
fn test_remove_same_music_tags_all_expect_oldest() {
|
||||
info!("test_remove_same_music_all_expect_oldest");
|
||||
run_test(
|
||||
&["music", "-d", "TestFiles", "-D", "AEO"],
|
||||
vec!["Music/M1.mp3", "Music/M2.mp3", "Music/M3.flac"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
fn test_remove_same_music_tags_all_expect_newest() {
|
||||
info!("test_remove_same_music_all_expect_newest");
|
||||
run_test(
|
||||
&["music", "-d", "TestFiles", "-D", "AEN"],
|
||||
vec!["Music/M1.mp3", "Music/M3.flac", "Music/M5.mp3"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
fn test_remove_duplicates_all_expect_oldest() {
|
||||
info!("test_remove_duplicates_all_expect_oldest");
|
||||
run_test(
|
||||
&["dup", "-d", "TestFiles", "-D", "AEO"],
|
||||
vec!["Images/A1.jpg", "Images/A5.jpg", "Music/M1.mp3", "Music/M2.mp3", "Videos/V1.mp4", "Videos/V5.mp4"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
fn test_remove_duplicates_all_expect_newest() {
|
||||
info!("test_remove_duplicates_all_expect_newest");
|
||||
run_test(
|
||||
&["dup", "-d", "TestFiles", "-D", "AEN"],
|
||||
vec!["Images/A2.jpg", "Images/A5.jpg", "Music/M1.mp3", "Music/M5.mp3", "Videos/V1.mp4", "Videos/V2.mp4"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
fn test_remove_duplicates_one_newest() {
|
||||
info!("test_remove_duplicates_one_newest");
|
||||
run_test(
|
||||
&["dup", "-d", "TestFiles", "-D", "ON"],
|
||||
vec!["Images/A1.jpg", "Music/M2.mp3", "Videos/V5.mp4"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
fn test_remove_duplicates_one_oldest() {
|
||||
info!("test_remove_duplicates_one_oldest");
|
||||
run_test(
|
||||
&["dup", "-d", "TestFiles", "-D", "OO"],
|
||||
vec!["Images/A2.jpg", "Music/M5.mp3", "Videos/V2.mp4"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
fn test_symlinks_files() {
|
||||
info!("test_symlinks_files");
|
||||
run_test(&["symlinks", "-d", "TestFiles", "-D"], vec![], vec![], vec!["Symlinks/EmptyFiles"]);
|
||||
}
|
||||
fn test_temporary_files() {
|
||||
info!("test_temporary_files");
|
||||
run_test(&["temp", "-d", "TestFiles", "-D"], vec!["Temporary/Boczze.cache"], vec![], vec![]);
|
||||
}
|
||||
fn test_empty_folders() {
|
||||
info!("test_empty_folders");
|
||||
run_test(
|
||||
&["empty-folders", "-d", "TestFiles", "-D"],
|
||||
vec![],
|
||||
vec!["EmptyFolders/One", "EmptyFolders/Two", "EmptyFolders/Two/TwoInside"],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
fn test_biggest_files() {
|
||||
info!("test_biggest_files");
|
||||
run_test(
|
||||
&["big", "-d", "TestFiles", "-n", "6", "-D"],
|
||||
vec!["Music/M3.flac", "Music/M4.mp3", "Videos/V2.mp4", "Videos/V3.webm", "Videos/V1.mp4", "Videos/V5.mp4"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
fn test_smallest_files() {
|
||||
info!("test_smallest_files");
|
||||
run_test(
|
||||
&["big", "-d", "TestFiles", "-J", "-n", "5", "-D"],
|
||||
vec!["Broken/Br.jpg", "Broken/Br.mp3", "Broken/Br.pdf", "Broken/Br.zip", "EmptyFolders/ThreeButNot/KEKEKE"],
|
||||
vec![],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
fn test_empty_files() {
|
||||
info!("test_empty_files");
|
||||
run_test(&["empty-files", "-d", "TestFiles", "-D"], vec!["EmptyFile"], vec![], vec![]);
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
////////////////////////////////////
|
||||
/////////HELPER FUNCTIONS///////////
|
||||
////////////////////////////////////
|
||||
////////////////////////////////////
|
||||
|
||||
fn run_test(arguments: &[&str], expected_files_differences: Vec<&'static str>, expected_folders_differences: Vec<&'static str>, expected_symlinks_differences: Vec<&'static str>) {
|
||||
unzip_files();
|
||||
// Add path_to_czkawka to arguments
|
||||
let mut all_arguments = vec![];
|
||||
all_arguments.push(CZKAWKA_PATH.get().as_str());
|
||||
all_arguments.extend_from_slice(arguments);
|
||||
run_with_good_status(&all_arguments, PRINT_MESSAGES_CZKAWKA);
|
||||
file_folder_diffs(
|
||||
COLLECTED_FILES.get(),
|
||||
expected_files_differences,
|
||||
expected_folders_differences,
|
||||
expected_symlinks_differences,
|
||||
);
|
||||
|
||||
remove_test_dir();
|
||||
}
|
||||
fn unzip_files() {
|
||||
run_with_good_status(&["unzip", "-X", "TestFiles.zip", "-d", "TestFiles"], false);
|
||||
}
|
||||
fn remove_test_dir() {
|
||||
let _ = fs::remove_dir_all("TestFiles");
|
||||
}
|
||||
|
||||
fn run_with_good_status(str_command: &[&str], print_messages: bool) {
|
||||
let mut command = Command::new(str_command[0]);
|
||||
let mut com = command.args(&str_command[1..]);
|
||||
if !print_messages {
|
||||
com = com.stderr(Stdio::piped()).stdout(Stdio::piped());
|
||||
}
|
||||
let status = com.spawn().expect("failed to execute process").wait().unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
fn file_folder_diffs(
|
||||
all_files: &CollectedFiles,
|
||||
mut expected_files_differences: Vec<&'static str>,
|
||||
mut expected_folders_differences: Vec<&'static str>,
|
||||
mut expected_symlinks_differences: Vec<&'static str>,
|
||||
) {
|
||||
let current_files = collect_all_files_and_dirs("TestFiles").unwrap();
|
||||
let mut diff_files = all_files
|
||||
.files
|
||||
.difference(¤t_files.files)
|
||||
.map(|e| e.strip_prefix("TestFiles/").unwrap().to_string())
|
||||
.collect::<Vec<_>>();
|
||||
let mut diff_folders = all_files
|
||||
.folders
|
||||
.difference(¤t_files.folders)
|
||||
.map(|e| e.strip_prefix("TestFiles/").unwrap().to_string())
|
||||
.collect::<Vec<_>>();
|
||||
let mut diff_symlinks = all_files
|
||||
.symlinks
|
||||
.difference(¤t_files.symlinks)
|
||||
.map(|e| e.strip_prefix("TestFiles/").unwrap().to_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
expected_symlinks_differences.sort();
|
||||
expected_folders_differences.sort();
|
||||
expected_files_differences.sort();
|
||||
|
||||
diff_files.sort();
|
||||
diff_folders.sort();
|
||||
diff_symlinks.sort();
|
||||
|
||||
assert_eq!(diff_files, expected_files_differences);
|
||||
assert_eq!(diff_folders, expected_folders_differences);
|
||||
assert_eq!(diff_symlinks, expected_symlinks_differences);
|
||||
}
|
||||
|
||||
fn collect_all_files_and_dirs(dir: &str) -> std::io::Result<CollectedFiles> {
|
||||
let mut files = BTreeSet::new();
|
||||
let mut folders = BTreeSet::new();
|
||||
let mut symlinks = BTreeSet::new();
|
||||
|
||||
let mut folders_to_check = vec![dir.to_string()];
|
||||
while !folders_to_check.is_empty() {
|
||||
let folder = folders_to_check.pop().unwrap();
|
||||
let rd = fs::read_dir(folder)?;
|
||||
for entry in rd {
|
||||
let entry = entry?;
|
||||
let file_type = entry.file_type()?;
|
||||
let path_str = entry.path().to_string_lossy().to_string();
|
||||
|
||||
if file_type.is_dir() {
|
||||
folders.insert(path_str.clone());
|
||||
folders_to_check.push(path_str);
|
||||
} else if file_type.is_symlink() {
|
||||
symlinks.insert(path_str);
|
||||
} else if file_type.is_file() {
|
||||
files.insert(path_str);
|
||||
} else {
|
||||
panic!("Unknown type of file {path_str:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
folders.remove(dir);
|
||||
// println!("Found {} files, {} folders and {} symlinks", files.len(), folders.len(), symlinks.len());
|
||||
Ok(CollectedFiles { files, folders, symlinks })
|
||||
}
|
@ -1,16 +1,29 @@
|
||||
[package]
|
||||
name = "czkawka_cli"
|
||||
version = "4.0.0"
|
||||
version = "7.0.0"
|
||||
authors = ["Rafał Mikrut <mikrutrafal@protonmail.com>"]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
rust-version = "1.75.0"
|
||||
description = "CLI frontend of Czkawka"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/qarmin/czkawka"
|
||||
repository = "https://github.com/qarmin/czkawka"
|
||||
|
||||
[dependencies]
|
||||
czkawka_core = { path = "../czkawka_core", version = "4.0.0" }
|
||||
structopt = "0.3.25"
|
||||
clap = { version = "4.5", features = ["derive"] }
|
||||
|
||||
# For enum types
|
||||
img_hash = "3.2.0"
|
||||
image_hasher = "1.2"
|
||||
|
||||
log = "0.4.20"
|
||||
handsome_logger = "0.8"
|
||||
fun_time = { version = "0.3", features = ["log"] }
|
||||
czkawka_core = { path = "../czkawka_core", version = "7.0.0", features = [] }
|
||||
indicatif = "0.17"
|
||||
crossbeam-channel = { version = "0.5", features = [] }
|
||||
ctrlc = { version = "3.4", features = ["termination"] }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
heif = ["czkawka_core/heif"]
|
||||
libraw = ["czkawka_core/libraw"]
|
||||
|
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2024 Rafał Mikrut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -0,0 +1,44 @@
|
||||
# Czkawka CLI
|
||||
|
||||
CLI frontend, allows to use Czkawka from terminal.
|
||||
|
||||
## Requirements
|
||||
Precompiled binaries should work without any additional dependencies with Linux(Ubuntu 20.04+), Windows(10+) and macOS(10.15+).
|
||||
|
||||
If you decide to compile the app, you probably will be able to run it on even older versions of OS, like Ubuntu 16.04 or Windows 7.
|
||||
|
||||
On linux it is even possible with eyra to avoid entirely libc and using fully static rust binary.
|
||||
|
||||
If you want to use similar videos tool, you need to install ffmpeg(runtime dependency) or use heif/libraw(build/runtime dependency) you need to install required packages.
|
||||
- mac - `brew install ffmpeg libraw libheif` - https://formulae.brew.sh/formula/ffmpeg
|
||||
- linux - `sudo apt install ffmpeg libraw-dev libheif-dev`
|
||||
- windows - `choco install ffmpeg` - or if not working, download from https://ffmpeg.org/download.html#build-windows and unpack to location with `czkawka_cli.exe`, heif and libraw are not supported on windows
|
||||
|
||||
## Compilation
|
||||
For compilation, you need to have installed Rust via rustup - https://rustup.rs/ and compile it e.g. via
|
||||
```shell
|
||||
cargo run --release --bin czkawka_cli
|
||||
```
|
||||
you can enable additional features via
|
||||
```shell
|
||||
cargo run --release --bin czkawka_cli --features "heif,libraw"
|
||||
```
|
||||
on linux to build fully static binary with eyra you need to use (this is only for crazy people, so just use command above if you don't know what you are doing)
|
||||
```shell
|
||||
rustup default nightly-2024-02-06 # or any newer nightly that works fine with eyra
|
||||
cd czkawka_cli
|
||||
cargo add eyra --rename=std
|
||||
echo 'fn main() { println!("cargo:rustc-link-arg=-nostartfiles"); }' > build.rs
|
||||
cd ..
|
||||
cargo build --release --bin czkawka_cli
|
||||
```
|
||||
|
||||
## Limitations
|
||||
Not all available features in core are available in CLI.
|
||||
|
||||
List of not available features:
|
||||
- Ability to use/choose referenced directories
|
||||
- See progress of scanning
|
||||
|
||||
## LICENSE
|
||||
MIT
|
@ -0,0 +1 @@
|
||||
../data/
|
@ -1,393 +1,343 @@
|
||||
use std::process;
|
||||
#![allow(clippy::needless_late_init)]
|
||||
|
||||
use structopt::StructOpt;
|
||||
use std::thread;
|
||||
|
||||
use clap::Parser;
|
||||
use crossbeam_channel::{bounded, unbounded, Receiver, Sender};
|
||||
use log::error;
|
||||
|
||||
use commands::Commands;
|
||||
#[allow(unused_imports)] // It is used in release for print_results().
|
||||
use czkawka_core::bad_extensions::BadExtensions;
|
||||
use czkawka_core::big_file::{BigFile, SearchMode};
|
||||
use czkawka_core::broken_files::BrokenFiles;
|
||||
use czkawka_core::common::{print_version_mode, set_number_of_threads, setup_logger, DEFAULT_THREAD_SIZE};
|
||||
use czkawka_core::common_dir_traversal::ProgressData;
|
||||
use czkawka_core::common_tool::{CommonData, DeleteMethod};
|
||||
#[allow(unused_imports)] // It is used in release for print_results_to_output().
|
||||
use czkawka_core::common_traits::*;
|
||||
use czkawka_core::similar_images::test_image_conversion_speed;
|
||||
use czkawka_core::{
|
||||
big_file::{self, BigFile},
|
||||
broken_files::{self, BrokenFiles},
|
||||
duplicate::DuplicateFinder,
|
||||
empty_files::{self, EmptyFiles},
|
||||
empty_folder::EmptyFolder,
|
||||
invalid_symlinks,
|
||||
invalid_symlinks::InvalidSymlinks,
|
||||
same_music::SameMusic,
|
||||
similar_images::{return_similarity_from_similarity_preset, SimilarImages},
|
||||
similar_videos::SimilarVideos,
|
||||
temporary::{self, Temporary},
|
||||
use czkawka_core::duplicate::DuplicateFinder;
|
||||
use czkawka_core::empty_files::EmptyFiles;
|
||||
use czkawka_core::empty_folder::EmptyFolder;
|
||||
use czkawka_core::invalid_symlinks::InvalidSymlinks;
|
||||
use czkawka_core::same_music::SameMusic;
|
||||
use czkawka_core::similar_images::{return_similarity_from_similarity_preset, test_image_conversion_speed, SimilarImages};
|
||||
use czkawka_core::similar_videos::SimilarVideos;
|
||||
use czkawka_core::temporary::Temporary;
|
||||
|
||||
use crate::commands::{
|
||||
Args, BadExtensionsArgs, BiggestFilesArgs, BrokenFilesArgs, CommonCliItems, DuplicatesArgs, EmptyFilesArgs, EmptyFoldersArgs, InvalidSymlinksArgs, SameMusicArgs,
|
||||
SimilarImagesArgs, SimilarVideosArgs, TemporaryArgs,
|
||||
};
|
||||
use crate::progress::connect_progress;
|
||||
|
||||
mod commands;
|
||||
mod progress;
|
||||
|
||||
fn main() {
|
||||
let command = Commands::from_args();
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
println!("{:?}", command);
|
||||
|
||||
match command {
|
||||
Commands::Duplicates {
|
||||
directories,
|
||||
excluded_directories,
|
||||
excluded_items,
|
||||
minimal_file_size,
|
||||
maximal_file_size,
|
||||
minimal_cached_file_size,
|
||||
allowed_extensions,
|
||||
search_method,
|
||||
delete_method,
|
||||
hash_type,
|
||||
file_to_save,
|
||||
not_recursive,
|
||||
allow_hard_links,
|
||||
dryrun,
|
||||
} => {
|
||||
let mut df = DuplicateFinder::new();
|
||||
|
||||
df.set_included_directory(directories.directories);
|
||||
df.set_excluded_directory(excluded_directories.excluded_directories);
|
||||
df.set_excluded_items(excluded_items.excluded_items);
|
||||
df.set_minimal_file_size(minimal_file_size);
|
||||
df.set_maximal_file_size(maximal_file_size);
|
||||
df.set_minimal_cache_file_size(minimal_cached_file_size);
|
||||
df.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
|
||||
df.set_check_method(search_method);
|
||||
df.set_delete_method(delete_method);
|
||||
df.set_hash_type(hash_type);
|
||||
df.set_recursive_search(!not_recursive.not_recursive);
|
||||
df.set_ignore_hard_links(!allow_hard_links.allow_hard_links);
|
||||
df.set_dryrun(dryrun.dryrun);
|
||||
|
||||
df.find_duplicates(None, None);
|
||||
|
||||
if let Some(file_name) = file_to_save.file_name() {
|
||||
if !df.save_results_to_file(file_name) {
|
||||
df.get_text_messages().print_messages();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
|
||||
df.print_results();
|
||||
df.get_text_messages().print_messages();
|
||||
}
|
||||
Commands::EmptyFolders {
|
||||
directories,
|
||||
delete_folders,
|
||||
file_to_save,
|
||||
excluded_directories,
|
||||
excluded_items,
|
||||
} => {
|
||||
let mut ef = EmptyFolder::new();
|
||||
|
||||
ef.set_included_directory(directories.directories);
|
||||
ef.set_excluded_directory(excluded_directories.excluded_directories);
|
||||
ef.set_excluded_items(excluded_items.excluded_items);
|
||||
ef.set_delete_folder(delete_folders);
|
||||
|
||||
ef.find_empty_folders(None, None);
|
||||
|
||||
if let Some(file_name) = file_to_save.file_name() {
|
||||
if !ef.save_results_to_file(file_name) {
|
||||
ef.get_text_messages().print_messages();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
|
||||
ef.print_results();
|
||||
ef.get_text_messages().print_messages();
|
||||
}
|
||||
Commands::BiggestFiles {
|
||||
directories,
|
||||
excluded_directories,
|
||||
excluded_items,
|
||||
allowed_extensions,
|
||||
number_of_files,
|
||||
file_to_save,
|
||||
not_recursive,
|
||||
delete_files,
|
||||
} => {
|
||||
let mut bf = BigFile::new();
|
||||
|
||||
bf.set_included_directory(directories.directories);
|
||||
bf.set_excluded_directory(excluded_directories.excluded_directories);
|
||||
bf.set_excluded_items(excluded_items.excluded_items);
|
||||
bf.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
|
||||
bf.set_number_of_files_to_check(number_of_files);
|
||||
bf.set_recursive_search(!not_recursive.not_recursive);
|
||||
if delete_files {
|
||||
bf.set_delete_method(big_file::DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
bf.find_big_files(None, None);
|
||||
|
||||
if let Some(file_name) = file_to_save.file_name() {
|
||||
if !bf.save_results_to_file(file_name) {
|
||||
bf.get_text_messages().print_messages();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
|
||||
bf.print_results();
|
||||
bf.get_text_messages().print_messages();
|
||||
}
|
||||
Commands::EmptyFiles {
|
||||
directories,
|
||||
excluded_directories,
|
||||
excluded_items,
|
||||
allowed_extensions,
|
||||
delete_files,
|
||||
file_to_save,
|
||||
not_recursive,
|
||||
} => {
|
||||
let mut ef = EmptyFiles::new();
|
||||
|
||||
ef.set_included_directory(directories.directories);
|
||||
ef.set_excluded_directory(excluded_directories.excluded_directories);
|
||||
ef.set_excluded_items(excluded_items.excluded_items);
|
||||
ef.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
|
||||
ef.set_recursive_search(!not_recursive.not_recursive);
|
||||
|
||||
if delete_files {
|
||||
ef.set_delete_method(empty_files::DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
ef.find_empty_files(None, None);
|
||||
|
||||
if let Some(file_name) = file_to_save.file_name() {
|
||||
if !ef.save_results_to_file(file_name) {
|
||||
ef.get_text_messages().print_messages();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
|
||||
ef.print_results();
|
||||
ef.get_text_messages().print_messages();
|
||||
}
|
||||
Commands::Temporary {
|
||||
directories,
|
||||
excluded_directories,
|
||||
excluded_items,
|
||||
delete_files,
|
||||
file_to_save,
|
||||
not_recursive,
|
||||
} => {
|
||||
let mut tf = Temporary::new();
|
||||
|
||||
tf.set_included_directory(directories.directories);
|
||||
tf.set_excluded_directory(excluded_directories.excluded_directories);
|
||||
tf.set_excluded_items(excluded_items.excluded_items);
|
||||
tf.set_recursive_search(!not_recursive.not_recursive);
|
||||
|
||||
if delete_files {
|
||||
tf.set_delete_method(temporary::DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
tf.find_temporary_files(None, None);
|
||||
|
||||
if let Some(file_name) = file_to_save.file_name() {
|
||||
if !tf.save_results_to_file(file_name) {
|
||||
tf.get_text_messages().print_messages();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
|
||||
tf.print_results();
|
||||
tf.get_text_messages().print_messages();
|
||||
}
|
||||
Commands::SimilarImages {
|
||||
directories,
|
||||
excluded_directories,
|
||||
excluded_items,
|
||||
file_to_save,
|
||||
minimal_file_size,
|
||||
maximal_file_size,
|
||||
similarity_preset,
|
||||
not_recursive,
|
||||
hash_alg,
|
||||
image_filter,
|
||||
hash_size,
|
||||
} => {
|
||||
let mut sf = SimilarImages::new();
|
||||
|
||||
sf.set_included_directory(directories.directories);
|
||||
sf.set_excluded_directory(excluded_directories.excluded_directories);
|
||||
sf.set_excluded_items(excluded_items.excluded_items);
|
||||
sf.set_minimal_file_size(minimal_file_size);
|
||||
sf.set_maximal_file_size(maximal_file_size);
|
||||
sf.set_recursive_search(!not_recursive.not_recursive);
|
||||
sf.set_image_filter(image_filter);
|
||||
sf.set_hash_alg(hash_alg);
|
||||
sf.set_hash_size(hash_size);
|
||||
|
||||
sf.set_similarity(return_similarity_from_similarity_preset(&similarity_preset, hash_size));
|
||||
|
||||
sf.find_similar_images(None, None);
|
||||
|
||||
if let Some(file_name) = file_to_save.file_name() {
|
||||
if !sf.save_results_to_file(file_name) {
|
||||
sf.get_text_messages().print_messages();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
|
||||
sf.print_results();
|
||||
sf.get_text_messages().print_messages();
|
||||
}
|
||||
Commands::SameMusic {
|
||||
directories,
|
||||
excluded_directories,
|
||||
excluded_items,
|
||||
// delete_files,
|
||||
file_to_save,
|
||||
not_recursive,
|
||||
minimal_file_size,
|
||||
maximal_file_size,
|
||||
music_similarity,
|
||||
} => {
|
||||
let mut mf = SameMusic::new();
|
||||
|
||||
mf.set_included_directory(directories.directories);
|
||||
mf.set_excluded_directory(excluded_directories.excluded_directories);
|
||||
mf.set_excluded_items(excluded_items.excluded_items);
|
||||
mf.set_minimal_file_size(minimal_file_size);
|
||||
mf.set_maximal_file_size(maximal_file_size);
|
||||
mf.set_recursive_search(!not_recursive.not_recursive);
|
||||
mf.set_music_similarity(music_similarity);
|
||||
|
||||
// if delete_files {
|
||||
// // TODO mf.set_delete_method(same_music::DeleteMethod::Delete);
|
||||
// }
|
||||
|
||||
mf.find_same_music(None, None);
|
||||
|
||||
if let Some(file_name) = file_to_save.file_name() {
|
||||
if !mf.save_results_to_file(file_name) {
|
||||
mf.get_text_messages().print_messages();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
|
||||
mf.print_results();
|
||||
mf.get_text_messages().print_messages();
|
||||
}
|
||||
Commands::InvalidSymlinks {
|
||||
directories,
|
||||
excluded_directories,
|
||||
excluded_items,
|
||||
allowed_extensions,
|
||||
file_to_save,
|
||||
not_recursive,
|
||||
delete_files,
|
||||
} => {
|
||||
let mut ifs = InvalidSymlinks::new();
|
||||
|
||||
ifs.set_included_directory(directories.directories);
|
||||
ifs.set_excluded_directory(excluded_directories.excluded_directories);
|
||||
ifs.set_excluded_items(excluded_items.excluded_items);
|
||||
ifs.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
|
||||
ifs.set_recursive_search(!not_recursive.not_recursive);
|
||||
if delete_files {
|
||||
ifs.set_delete_method(invalid_symlinks::DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
ifs.find_invalid_links(None, None);
|
||||
|
||||
if let Some(file_name) = file_to_save.file_name() {
|
||||
if !ifs.save_results_to_file(file_name) {
|
||||
ifs.get_text_messages().print_messages();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
|
||||
ifs.print_results();
|
||||
ifs.get_text_messages().print_messages();
|
||||
let command = Args::parse().command;
|
||||
|
||||
setup_logger(true);
|
||||
print_version_mode();
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
println!("{command:?}");
|
||||
}
|
||||
|
||||
let (progress_sender, progress_receiver): (Sender<ProgressData>, Receiver<ProgressData>) = unbounded();
|
||||
let (stop_sender, stop_receiver): (Sender<()>, Receiver<()>) = bounded(1);
|
||||
|
||||
let calculate_thread = thread::Builder::new().stack_size(DEFAULT_THREAD_SIZE).spawn(move || match command {
|
||||
Commands::Duplicates(duplicates_args) => duplicates(duplicates_args, &stop_receiver, &progress_sender),
|
||||
Commands::EmptyFolders(empty_folders_args) => empty_folders(empty_folders_args, &stop_receiver, &progress_sender),
|
||||
Commands::BiggestFiles(biggest_files_args) => biggest_files(biggest_files_args, &stop_receiver, &progress_sender),
|
||||
Commands::EmptyFiles(empty_files_args) => empty_files(empty_files_args, &stop_receiver, &progress_sender),
|
||||
Commands::Temporary(temporary_args) => temporary(temporary_args, &stop_receiver, &progress_sender),
|
||||
Commands::SimilarImages(similar_images_args) => similar_images(similar_images_args, &stop_receiver, &progress_sender),
|
||||
Commands::SameMusic(same_music_args) => same_music(same_music_args, &stop_receiver, &progress_sender),
|
||||
Commands::InvalidSymlinks(invalid_symlinks_args) => invalid_symlinks(invalid_symlinks_args, &stop_receiver, &progress_sender),
|
||||
Commands::BrokenFiles(broken_files_args) => broken_files(broken_files_args, &stop_receiver, &progress_sender),
|
||||
Commands::SimilarVideos(similar_videos_args) => similar_videos(similar_videos_args, &stop_receiver, &progress_sender),
|
||||
Commands::BadExtensions(bad_extensions_args) => bad_extensions(bad_extensions_args, &stop_receiver, &progress_sender),
|
||||
Commands::Tester {} => {
|
||||
test_image_conversion_speed();
|
||||
}
|
||||
Commands::BrokenFiles {
|
||||
directories,
|
||||
excluded_directories,
|
||||
excluded_items,
|
||||
allowed_extensions,
|
||||
delete_files,
|
||||
file_to_save,
|
||||
not_recursive,
|
||||
} => {
|
||||
let mut br = BrokenFiles::new();
|
||||
|
||||
br.set_included_directory(directories.directories);
|
||||
br.set_excluded_directory(excluded_directories.excluded_directories);
|
||||
br.set_excluded_items(excluded_items.excluded_items);
|
||||
br.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
|
||||
br.set_recursive_search(!not_recursive.not_recursive);
|
||||
|
||||
if delete_files {
|
||||
br.set_delete_method(broken_files::DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
br.find_broken_files(None, None);
|
||||
|
||||
if let Some(file_name) = file_to_save.file_name() {
|
||||
if !br.save_results_to_file(file_name) {
|
||||
br.get_text_messages().print_messages();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
|
||||
br.print_results();
|
||||
br.get_text_messages().print_messages();
|
||||
});
|
||||
ctrlc::set_handler(move || {
|
||||
println!("Get Sender");
|
||||
stop_sender.send(()).expect("Could not send signal on channel.");
|
||||
})
|
||||
.expect("Error setting Ctrl-C handler");
|
||||
|
||||
connect_progress(&progress_receiver);
|
||||
|
||||
calculate_thread.unwrap().join().unwrap();
|
||||
}
|
||||
|
||||
fn duplicates(duplicates: DuplicatesArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let DuplicatesArgs {
|
||||
common_cli_items,
|
||||
minimal_file_size,
|
||||
maximal_file_size,
|
||||
minimal_cached_file_size,
|
||||
search_method,
|
||||
delete_method,
|
||||
hash_type,
|
||||
allow_hard_links,
|
||||
dry_run,
|
||||
case_sensitive_name_comparison,
|
||||
} = duplicates;
|
||||
|
||||
let mut item = DuplicateFinder::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
item.set_minimal_file_size(minimal_file_size);
|
||||
item.set_maximal_file_size(maximal_file_size);
|
||||
item.set_minimal_cache_file_size(minimal_cached_file_size);
|
||||
item.set_check_method(search_method);
|
||||
item.set_delete_method(delete_method.delete_method);
|
||||
item.set_hash_type(hash_type);
|
||||
item.set_ignore_hard_links(!allow_hard_links.allow_hard_links);
|
||||
item.set_dry_run(dry_run.dry_run);
|
||||
item.set_case_sensitive_name_comparison(case_sensitive_name_comparison.case_sensitive_name_comparison);
|
||||
|
||||
item.find_duplicates(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn empty_folders(empty_folders: EmptyFoldersArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let EmptyFoldersArgs { common_cli_items, delete_folders } = empty_folders;
|
||||
|
||||
let mut item = EmptyFolder::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
if delete_folders {
|
||||
item.set_delete_method(DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
item.find_empty_folders(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn biggest_files(biggest_files: BiggestFilesArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let BiggestFilesArgs {
|
||||
common_cli_items,
|
||||
number_of_files,
|
||||
delete_files,
|
||||
smallest_mode,
|
||||
} = biggest_files;
|
||||
|
||||
let mut item = BigFile::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
item.set_number_of_files_to_check(number_of_files);
|
||||
if delete_files {
|
||||
item.set_delete_method(DeleteMethod::Delete);
|
||||
}
|
||||
if smallest_mode {
|
||||
item.set_search_mode(SearchMode::SmallestFiles);
|
||||
}
|
||||
|
||||
item.find_big_files(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn empty_files(empty_files: EmptyFilesArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let EmptyFilesArgs { common_cli_items, delete_files } = empty_files;
|
||||
|
||||
let mut item = EmptyFiles::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
if delete_files {
|
||||
item.set_delete_method(DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
item.find_empty_files(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn temporary(temporary: TemporaryArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let TemporaryArgs { common_cli_items, delete_files } = temporary;
|
||||
|
||||
let mut item = Temporary::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
if delete_files {
|
||||
item.set_delete_method(DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
item.find_temporary_files(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn similar_images(similar_images: SimilarImagesArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let SimilarImagesArgs {
|
||||
common_cli_items,
|
||||
minimal_file_size,
|
||||
maximal_file_size,
|
||||
similarity_preset,
|
||||
hash_alg,
|
||||
image_filter,
|
||||
hash_size,
|
||||
delete_method,
|
||||
dry_run,
|
||||
allow_hard_links,
|
||||
} = similar_images;
|
||||
|
||||
let mut item = SimilarImages::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
item.set_minimal_file_size(minimal_file_size);
|
||||
item.set_maximal_file_size(maximal_file_size);
|
||||
item.set_image_filter(image_filter);
|
||||
item.set_hash_alg(hash_alg);
|
||||
item.set_hash_size(hash_size);
|
||||
item.set_delete_method(delete_method.delete_method);
|
||||
item.set_dry_run(dry_run.dry_run);
|
||||
item.set_similarity(return_similarity_from_similarity_preset(&similarity_preset, hash_size));
|
||||
item.set_ignore_hard_links(!allow_hard_links.allow_hard_links);
|
||||
|
||||
item.find_similar_images(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn same_music(same_music: SameMusicArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let SameMusicArgs {
|
||||
common_cli_items,
|
||||
delete_method,
|
||||
minimal_file_size,
|
||||
maximal_file_size,
|
||||
music_similarity,
|
||||
dry_run,
|
||||
minimum_segment_duration,
|
||||
maximum_difference,
|
||||
search_method,
|
||||
} = same_music;
|
||||
|
||||
let mut item = SameMusic::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
item.set_minimal_file_size(minimal_file_size);
|
||||
item.set_maximal_file_size(maximal_file_size);
|
||||
item.set_music_similarity(music_similarity);
|
||||
item.set_delete_method(delete_method.delete_method);
|
||||
item.set_dry_run(dry_run.dry_run);
|
||||
item.set_minimum_segment_duration(minimum_segment_duration);
|
||||
item.set_maximum_difference(maximum_difference);
|
||||
item.set_check_type(search_method);
|
||||
|
||||
item.find_same_music(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn invalid_symlinks(invalid_symlinks: InvalidSymlinksArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let InvalidSymlinksArgs { common_cli_items, delete_files } = invalid_symlinks;
|
||||
|
||||
let mut item = InvalidSymlinks::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
if delete_files {
|
||||
item.set_delete_method(DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
item.find_invalid_links(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn broken_files(broken_files: BrokenFilesArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let BrokenFilesArgs { common_cli_items, delete_files } = broken_files;
|
||||
|
||||
let mut item = BrokenFiles::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
if delete_files {
|
||||
item.set_delete_method(DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
item.find_broken_files(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn similar_videos(similar_videos: SimilarVideosArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let SimilarVideosArgs {
|
||||
common_cli_items,
|
||||
tolerance,
|
||||
minimal_file_size,
|
||||
maximal_file_size,
|
||||
delete_method,
|
||||
dry_run,
|
||||
allow_hard_links,
|
||||
} = similar_videos;
|
||||
|
||||
let mut item = SimilarVideos::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
item.set_minimal_file_size(minimal_file_size);
|
||||
item.set_maximal_file_size(maximal_file_size);
|
||||
item.set_tolerance(tolerance);
|
||||
item.set_delete_method(delete_method.delete_method);
|
||||
item.set_dry_run(dry_run.dry_run);
|
||||
item.set_ignore_hard_links(!allow_hard_links.allow_hard_links);
|
||||
|
||||
item.find_similar_videos(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn bad_extensions(bad_extensions: BadExtensionsArgs, stop_receiver: &Receiver<()>, progress_sender: &Sender<ProgressData>) {
|
||||
let BadExtensionsArgs { common_cli_items } = bad_extensions;
|
||||
|
||||
let mut item = BadExtensions::new();
|
||||
|
||||
set_common_settings(&mut item, &common_cli_items);
|
||||
|
||||
item.find_bad_extensions_files(Some(stop_receiver), Some(progress_sender));
|
||||
|
||||
save_and_print_results(&mut item, &common_cli_items);
|
||||
}
|
||||
|
||||
fn save_and_print_results<T: CommonData + PrintResults>(component: &mut T, common_cli_items: &CommonCliItems) {
|
||||
if let Some(file_name) = common_cli_items.file_to_save.file_name() {
|
||||
if let Err(e) = component.print_results_to_file(file_name) {
|
||||
error!("Failed to save results to file {e}");
|
||||
}
|
||||
Commands::SimilarVideos {
|
||||
directories,
|
||||
excluded_directories,
|
||||
excluded_items,
|
||||
file_to_save,
|
||||
not_recursive,
|
||||
tolerance,
|
||||
minimal_file_size,
|
||||
maximal_file_size,
|
||||
allowed_extensions,
|
||||
} => {
|
||||
let mut vr = SimilarVideos::new();
|
||||
|
||||
vr.set_included_directory(directories.directories);
|
||||
vr.set_excluded_directory(excluded_directories.excluded_directories);
|
||||
vr.set_excluded_items(excluded_items.excluded_items);
|
||||
vr.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
|
||||
vr.set_recursive_search(!not_recursive.not_recursive);
|
||||
vr.set_minimal_file_size(minimal_file_size);
|
||||
vr.set_maximal_file_size(maximal_file_size);
|
||||
vr.set_tolerance(tolerance);
|
||||
|
||||
vr.find_similar_videos(None, None);
|
||||
|
||||
if let Some(file_name) = file_to_save.file_name() {
|
||||
if !vr.save_results_to_file(file_name) {
|
||||
vr.get_text_messages().print_messages();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
|
||||
vr.print_results();
|
||||
vr.get_text_messages().print_messages();
|
||||
}
|
||||
if let Some(file_name) = common_cli_items.json_compact_file_to_save.file_name() {
|
||||
if let Err(e) = component.save_results_to_file_as_json(file_name, false) {
|
||||
error!("Failed to save compact json results to file {e}");
|
||||
}
|
||||
Commands::Tester { test_image } => {
|
||||
if test_image {
|
||||
test_image_conversion_speed();
|
||||
} else {
|
||||
println!("At least one test should be choosen!");
|
||||
}
|
||||
}
|
||||
if let Some(file_name) = common_cli_items.json_pretty_file_to_save.file_name() {
|
||||
if let Err(e) = component.save_results_to_file_as_json(file_name, true) {
|
||||
error!("Failed to save pretty json results to file {e}");
|
||||
}
|
||||
}
|
||||
|
||||
if !cfg!(debug_assertions) {
|
||||
component.print_results_to_output();
|
||||
}
|
||||
component.get_text_messages().print_messages();
|
||||
}
|
||||
|
||||
fn set_common_settings<T>(component: &mut T, common_cli_items: &CommonCliItems)
|
||||
where
|
||||
T: CommonData + PrintResults,
|
||||
{
|
||||
set_number_of_threads(common_cli_items.thread_number);
|
||||
|
||||
component.set_included_directory(common_cli_items.directories.clone());
|
||||
component.set_excluded_directory(common_cli_items.excluded_directories.clone());
|
||||
component.set_excluded_items(common_cli_items.excluded_items.clone());
|
||||
component.set_recursive_search(!common_cli_items.not_recursive);
|
||||
#[cfg(target_family = "unix")]
|
||||
component.set_exclude_other_filesystems(common_cli_items.exclude_other_filesystems);
|
||||
component.set_allowed_extensions(common_cli_items.allowed_extensions.clone().join(","));
|
||||
}
|
||||
|
@ -0,0 +1,93 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use crossbeam_channel::Receiver;
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
|
||||
use czkawka_core::common_dir_traversal::{CheckingMethod, ProgressData, ToolType};
|
||||
|
||||
pub fn connect_progress(progress_receiver: &Receiver<ProgressData>) {
|
||||
let mut pb = ProgressBar::new(1);
|
||||
let mut latest_id = None;
|
||||
while let Ok(progress_data) = progress_receiver.recv() {
|
||||
if latest_id != Some(progress_data.current_stage) {
|
||||
pb.finish_and_clear();
|
||||
if progress_data.current_stage == 0 {
|
||||
pb = get_progress_bar_for_collect_files();
|
||||
} else if check_if_saving_cache(&progress_data) || check_if_loading_cache(&progress_data) {
|
||||
pb = get_progress_loading_saving_cache(check_if_loading_cache(&progress_data));
|
||||
} else {
|
||||
pb = get_progress_known_values(progress_data.entries_to_check, &get_progress_message(&progress_data));
|
||||
}
|
||||
latest_id = Some(progress_data.current_stage);
|
||||
}
|
||||
|
||||
pb.set_position(progress_data.entries_checked as u64);
|
||||
if progress_data.current_stage == 0 && progress_data.tool_type != ToolType::EmptyFolders {
|
||||
pb.set_message(format!("Collecting files: {}", progress_data.entries_checked));
|
||||
} else if progress_data.current_stage == 0 {
|
||||
pb.set_message(format!("Collecting folders: {}", progress_data.entries_checked));
|
||||
}
|
||||
}
|
||||
pb.finish();
|
||||
}
|
||||
|
||||
pub fn get_progress_message(progress_data: &ProgressData) -> String {
|
||||
match (progress_data.tool_type, progress_data.current_stage, progress_data.checking_method) {
|
||||
(ToolType::SameMusic, 2, CheckingMethod::AudioTags) | (ToolType::SameMusic, 5, CheckingMethod::AudioContent) => "Reading tags",
|
||||
(ToolType::SameMusic, 2, CheckingMethod::AudioContent) => "Calculating fingerprint",
|
||||
(ToolType::SameMusic, 4, CheckingMethod::AudioTags) => "Comparing tags",
|
||||
(ToolType::SameMusic, 4, CheckingMethod::AudioContent) => "Comparing fingerprint",
|
||||
|
||||
(ToolType::Duplicate, 2, CheckingMethod::Hash) => "Reading prehashes",
|
||||
(ToolType::Duplicate, 5, CheckingMethod::Hash) => "Reading hashes",
|
||||
(ToolType::SimilarImages, 1, _) => "Reading images",
|
||||
(ToolType::SimilarImages, 2, _) => "Comparing image hashes",
|
||||
(ToolType::SimilarVideos, 1, _) => "Reading similar values",
|
||||
(ToolType::BrokenFiles, 1, _) => "Checking broken files",
|
||||
(ToolType::BadExtensions, 1, _) => "Checking extensions of files",
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn check_if_loading_cache(progress_data: &ProgressData) -> bool {
|
||||
matches!(
|
||||
(progress_data.tool_type, progress_data.current_stage),
|
||||
(ToolType::SameMusic, 1) | (ToolType::Duplicate, 1 | 4)
|
||||
)
|
||||
}
|
||||
pub fn check_if_saving_cache(progress_data: &ProgressData) -> bool {
|
||||
matches!(
|
||||
(progress_data.tool_type, progress_data.current_stage),
|
||||
(ToolType::SameMusic, 3) | (ToolType::Duplicate, 3 | 6)
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_progress_bar_for_collect_files() -> ProgressBar {
|
||||
let pb = ProgressBar::new_spinner();
|
||||
pb.enable_steady_tick(Duration::from_millis(120));
|
||||
pb.set_style(
|
||||
ProgressStyle::with_template("{msg} {spinner:.blue}")
|
||||
.unwrap()
|
||||
.tick_strings(&["▹▹▹▹▹", "▸▹▹▹▹", "▹▸▹▹▹", "▹▹▸▹▹", "▹▹▹▸▹", "▹▹▹▹▸", "▪▪▪▪▪"]),
|
||||
);
|
||||
pb
|
||||
}
|
||||
|
||||
pub fn get_progress_known_values(max_value: usize, msg: &str) -> ProgressBar {
|
||||
let pb = ProgressBar::new(max_value as u64);
|
||||
pb.set_style(ProgressStyle::with_template(&format!("{msg} [{{bar}}] {{pos}}/{{len}} ")).unwrap().progress_chars("=> "));
|
||||
pb
|
||||
}
|
||||
|
||||
pub fn get_progress_loading_saving_cache(loading: bool) -> ProgressBar {
|
||||
let msg = if loading { "Loading cache" } else { "Saving cache" };
|
||||
let pb = ProgressBar::new_spinner();
|
||||
pb.enable_steady_tick(Duration::from_millis(120));
|
||||
pb.set_style(
|
||||
ProgressStyle::with_template(&format!("{msg} {{spinner:.blue}}"))
|
||||
.unwrap()
|
||||
.tick_strings(&["▹▹▹▹▹", "▸▹▹▹▹", "▹▸▹▹▹", "▹▹▸▹▹", "▹▹▹▸▹", "▹▹▹▹▸", "▪▪▪▪▪"]),
|
||||
);
|
||||
pb
|
||||
}
|
@ -1,66 +1,91 @@
|
||||
[package]
|
||||
name = "czkawka_core"
|
||||
version = "4.0.0"
|
||||
version = "7.0.0"
|
||||
authors = ["Rafał Mikrut <mikrutrafal@protonmail.com>"]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
rust-version = "1.75.0"
|
||||
description = "Core of Czkawka app"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/qarmin/czkawka"
|
||||
repository = "https://github.com/qarmin/czkawka"
|
||||
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
humansize = "1.1.1"
|
||||
rayon = "1.5.1"
|
||||
crossbeam-channel = "0.5.1"
|
||||
humansize = "2.1"
|
||||
rayon = "1.8"
|
||||
crossbeam-channel = "0.5"
|
||||
|
||||
# For saving/loading config files to specific directories
|
||||
directories-next = "2.0.0"
|
||||
directories-next = "2.0"
|
||||
|
||||
# Needed by similar images
|
||||
img_hash = "3.2.0"
|
||||
bk-tree = "0.4.0"
|
||||
image = "0.23.14"
|
||||
hamming = "0.1.3"
|
||||
image_hasher = "1.2"
|
||||
bk-tree = "0.5"
|
||||
image = { version = "0.24", default-features = false, features = ["gif", "jpeg", "ico", "png", "pnm", "tga", "tiff", "webp", "bmp", "hdr", "dxt", "dds", "farbfeld", "openexr", "qoi"] }
|
||||
hamming = "0.1"
|
||||
|
||||
# Needed by same music
|
||||
bitflags = "1.3.2"
|
||||
audiotags = "0.2.7182"
|
||||
|
||||
# Futures - needed by async progress sender
|
||||
futures = "0.3.19"
|
||||
bitflags = "2.4"
|
||||
lofty = "0.18"
|
||||
|
||||
# Needed by broken files
|
||||
zip = "0.5.13"
|
||||
rodio = { version = "0.14.0", optional = true }
|
||||
zip = { version = "0.6", features = ["aes-crypto", "bzip2", "deflate", "time"], default-features = false }
|
||||
audio_checker = "0.1"
|
||||
pdf = "0.9"
|
||||
|
||||
# Needed by audio similarity feature
|
||||
rusty-chromaprint = "0.2"
|
||||
symphonia = { version = "0.5", features = ["all"] }
|
||||
|
||||
# Hashes for duplicate files
|
||||
blake3 = "1.2.0"
|
||||
crc32fast = "1.3.0"
|
||||
xxhash-rust = { version = "0.8.2", features = ["xxh3"] }
|
||||
blake3 = "1.5"
|
||||
crc32fast = "1.4"
|
||||
xxhash-rust = { version = "0.8", features = ["xxh3"] }
|
||||
|
||||
tempfile = "3.2.0"
|
||||
tempfile = "3.10"
|
||||
|
||||
# Video Duplactes
|
||||
vid_dup_finder_lib = "0.1.0"
|
||||
ffmpeg_cmdline_utils = "0.1.0"
|
||||
# Video Duplicates
|
||||
vid_dup_finder_lib = "0.1"
|
||||
ffmpeg_cmdline_utils = "0.1"
|
||||
|
||||
# Saving/Loading Cache
|
||||
serde = "1.0.133"
|
||||
bincode = "1.3.3"
|
||||
serde_json = "1.0.74"
|
||||
serde = "1.0"
|
||||
bincode = "1.3"
|
||||
serde_json = "1.0"
|
||||
|
||||
# Language
|
||||
i18n-embed = { version = "0.13", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.6.1"
|
||||
rust-embed = "6.3.0"
|
||||
once_cell = "1.9.0"
|
||||
i18n-embed = { version = "0.14", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.8"
|
||||
rust-embed = { version = "8.2", features = ["debug-embed"] }
|
||||
once_cell = "1.19"
|
||||
|
||||
# Raw image files
|
||||
rawloader = "0.37.0"
|
||||
imagepipe = "0.4.0"
|
||||
rawloader = "0.37"
|
||||
imagepipe = "0.5"
|
||||
libraw-rs = { version = "0.0.4", optional = true }
|
||||
|
||||
# Checking for invalid extensions
|
||||
mime_guess = "2.0"
|
||||
infer = "0.15"
|
||||
|
||||
# Heif/Heic
|
||||
libheif-rs = { version = "=0.18.0", optional = true } # Do not upgrade now, since Ubuntu 22.04 not works with newer version
|
||||
libheif-sys = { version = "=1.14.2", optional = true } # 1.14.3 brake compilation on Ubuntu 22.04, so pin it to this version
|
||||
anyhow = { version = "1.0" }
|
||||
|
||||
|
||||
state = "0.6"
|
||||
trash = "3.3"
|
||||
|
||||
os_info = { version = "3", default-features = false }
|
||||
log = "0.4.20"
|
||||
handsome_logger = "0.8"
|
||||
fun_time = { version = "0.3", features = ["log"] }
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.4"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
broken_audio = ["rodio"]
|
||||
heif = ["dep:libheif-rs", "dep:libheif-sys"]
|
||||
libraw = ["dep:libraw-rs"]
|
||||
|
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2024 Rafał Mikrut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -0,0 +1,3 @@
|
||||
# Czkawka Core
|
||||
|
||||
Core of Czkawka GUI/CLI and Krokiet projects.
|
@ -0,0 +1,18 @@
|
||||
fn main() {
|
||||
let rust_version = match rustc_version::version_meta() {
|
||||
Ok(meta) => {
|
||||
let rust_v = meta.semver.to_string();
|
||||
let rust_date = meta.commit_date.unwrap_or_default();
|
||||
format!("{rust_v} ({rust_date})")
|
||||
}
|
||||
Err(_) => "<unknown>".to_string(),
|
||||
};
|
||||
println!("cargo:rustc-env=RUST_VERSION_INTERNAL={rust_version}");
|
||||
|
||||
// Find if app is build with cranelift
|
||||
if let Ok(codegen) = std::env::var("CARGO_PROFILE_RELEASE_CODEGEN_UNITS") {
|
||||
if codegen == "1" {
|
||||
println!("cargo:rustc-env=USING_CRANELIFT=1");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
../data/
|
@ -0,0 +1,29 @@
|
||||
# Core
|
||||
core_similarity_original = الأصل
|
||||
core_similarity_very_high = عالية جدا
|
||||
core_similarity_high = مرتفع
|
||||
core_similarity_medium = متوسط
|
||||
core_similarity_small = صغير
|
||||
core_similarity_very_small = صغير جدا
|
||||
core_similarity_minimal = الحد الأدنى
|
||||
core_cannot_open_dir = لا يمكن فتح dir { $dir }، السبب { $reason }
|
||||
core_cannot_read_entry_dir = لا يمكن قراءة الإدخال في dir { $dir }، السبب { $reason }
|
||||
core_cannot_read_metadata_dir = لا يمكن قراءة البيانات الوصفية في dir { $dir }، السبب { $reason }
|
||||
core_file_not_utf8_name = الملف { $name } ليس لديه اسم UTF-8 صالح (قد لا تظهر بعض الأحرف)
|
||||
core_file_modified_before_epoch = يبدو أن الملف { $name } قد تم تعديله قبل يونكس Epoch
|
||||
core_folder_modified_before_epoch = يبدو أن المجلد { $name } قد تم تعديله قبل يونكس Epoch
|
||||
core_file_no_modification_date = غير قادر على الحصول على تاريخ التعديل من الملف { $name }، السبب { $reason }
|
||||
core_folder_no_modification_date = غير قادر على الحصول على تاريخ التعديل من المجلد { $name }، السبب { $reason }
|
||||
core_missing_no_chosen_included_directory = يجب توفير دليل واحد على الأقل
|
||||
core_directory_wildcard_no_supported = الأدلة: البطاقات البرية في المسار غير مدعومة، تجاهل { $path }
|
||||
core_directory_must_exists = الأدلة: يجب أن يكون مسار المجلد المتوفر موجودا، تجاهل { $path }
|
||||
core_directory_must_be_directory = الأدلة: المسار المقدم يجب أن يشير إلى الدليل، تجاهل { $path }
|
||||
core_included_directory_zero_valid_directories = خطأ في الدليل المضمن: لا يوجد حتى مسار واحد صحيح للإدراج المطلوب
|
||||
core_excluded_directory_pointless_slash = الأدلة: استبعاد / لا معنى له، لأنه يعني أنه لن يتم مسح أي ملفات
|
||||
core_directory_overlap = الأدلة: جميع الدلائل للبحث عن التداخل مع الدلائل المستبعدة
|
||||
core_directory_unable_to_get_device_id = الأدلة: غير قادر على الحصول على معرف الجهاز من المجلد { $path }
|
||||
core_ffmpeg_not_found = لا يمكن العثور على التثبيت الصحيح لFFmpeg
|
||||
core_ffmpeg_not_found_windows = تأكد من أن ffmpeg.exe و ffprobe.exe متاحان في PATH أو يتم وضعهما مباشرة لنفس المجلد حيث التطبيق قابل للتنفيذ
|
||||
core_ffmpeg_missing_in_snap = مقاطع فيديو مشابهة لا تعمل حاليا مع السعادة، إذا كنت تريد المساعدة في النظر - { $url }
|
||||
core_saving_to_cache = تم الحفظ في الملف { $number } إدخالات ذاكرة التخزين المؤقت
|
||||
core_loading_from_cache = تحميل من ذاكرة التخزين المؤقت { $number } إدخالات
|
@ -1,25 +1,29 @@
|
||||
# Core
|
||||
core_similarity_original = Originál
|
||||
core_similarity_very_high = Velmi vysoká
|
||||
core_similarity_high = Vysoká
|
||||
core_similarity_medium = Střední
|
||||
core_similarity_small = Malá
|
||||
core_similarity_very_small = Velmi malá
|
||||
core_similarity_minimal = Minimální
|
||||
core_cannot_open_dir = Nelze otevřít dir { $dir }, důvod { $reason }
|
||||
core_cannot_read_entry_dir = Nelze číst záznam v adresáři { $dir }, důvod { $reason }
|
||||
core_cannot_read_metadata_dir = Metadata nelze číst v adresáři { $dir }, důvod { $reason }
|
||||
core_cannot_open_dir = Nelze otevřít adresář { $dir }, důvod { $reason }
|
||||
core_cannot_read_entry_dir = Nelze načíst záznam v adresáři { $dir }, důvod { $reason }
|
||||
core_cannot_read_metadata_dir = Nelze načíst metadata v adresáři { $dir }, důvod { $reason }
|
||||
core_file_not_utf8_name = Soubor { $name } nemá platný název UTF-8 (některé znaky nemusí být zobrazeny)
|
||||
core_file_modified_before_epoch = Soubor { $name } se zdá být před Unix Epoch upraven
|
||||
core_folder_modified_before_epoch = Složka { $name } se zdá být upravena před Unixem Epoch
|
||||
core_file_modified_before_epoch = Soubor { $name } se zdá být upraven před unixovým Epochem (1.1.1970)
|
||||
core_folder_modified_before_epoch = Složka { $name } se zdá být upravena před unixovým Epochem (1.1.1970)
|
||||
core_file_no_modification_date = Nelze získat datum úpravy ze souboru { $name }, důvod { $reason }
|
||||
core_folder_no_modification_date = Nelze získat datum úpravy ze složky { $name }, důvod { $reason }
|
||||
core_missing_no_chosen_included_directory = Musí být uveden alespoň jeden adresář
|
||||
core_directory_wildcard_no_supported = Adresáře: Zástupné znaky v cestě nejsou podporovány, ignoruji { $path }
|
||||
core_directory_relative_path = Adresáře: Zástupné znaky v cestě nejsou podporovány, ignoruji { $path }
|
||||
core_directory_must_exists = Adresáře: Poskytnutá cesta ke složce musí skončit, ignoruji { $path }
|
||||
core_directory_must_be_directory = Adresáře: Poskytnutá cesta musí směřovat do adresáře, ignoruje { $path }
|
||||
core_directory_must_exists = Adresáře: Poskytnutá cesta ke složce musí existovat, ignoruji { $path }
|
||||
core_directory_must_be_directory = Adresáře: Poskytnutá cesta musí směřovat do adresáře, ignoruji { $path }
|
||||
core_included_directory_zero_valid_directories = CHYBA zahrnutí adresáře: Nenalezena ani jedna správná cesta k zahrnutí, která je vyžadována
|
||||
core_excluded_directory_pointless_slash = Adresáře: Vyloučení / je bezúčelné, protože to znamená, že žádné soubory nebudou naskenovány
|
||||
core_directory_overlap = Adresáře: Všechny adresáře pro vyhledávání se překrývají s vyloučením adresářů
|
||||
core_directory_unable_to_get_device_id = Adresáře: Nelze získat ID zařízení ze složky { $path }
|
||||
core_ffmpeg_not_found = Nelze najít správnou instalaci FFmpeg
|
||||
core_ffmpeg_not_found_windows = Ujistěte se, že ffmpeg.exe a ffprobe.exe jsou k dispozici v PATH nebo jsou umístěny přímo do stejné složky, kde lze spustit aplikaci
|
||||
core_ffmpeg_missing_in_snap = Podobná videa v současné době nefungují se snapem, pokud chcete nápovědu sledovat - { $url }
|
||||
core_saving_to_cache = Uloženo do souboru { $number } položek mezipaměti
|
||||
core_loading_from_cache = Načteno z { $number } položek keše
|
||||
|
@ -1,25 +1,29 @@
|
||||
# Core
|
||||
core_similarity_original = Original
|
||||
core_similarity_very_high = Sehr Hoch
|
||||
core_similarity_high = Hoch
|
||||
core_similarity_medium = Mittel
|
||||
core_similarity_small = Klein
|
||||
core_similarity_very_small = Sehr klein
|
||||
core_similarity_minimal = Minimale
|
||||
core_similarity_minimal = Minimal
|
||||
core_cannot_open_dir = Verzeichnis { $dir } kann nicht geöffnet werden, Grund { $reason }
|
||||
core_cannot_read_entry_dir = Kann Eintrag in Verzeichnis { $dir } nicht lesen, Grund { $reason }
|
||||
core_cannot_read_metadata_dir = Metadaten können in Verzeichnis { $dir } nicht gelesen werden, Grund { $reason }
|
||||
core_file_not_utf8_name = Datei { $name } hat keinen gültigen UTF-8-Namen (einige Zeichen dürfen nicht angezeigt werden)
|
||||
core_file_modified_before_epoch = Datei { $name } scheint vor der Unix-Epoche geändert zu werden
|
||||
core_folder_modified_before_epoch = Ordner { $name } scheint vor der Unix-Epoche geändert zu werden
|
||||
core_file_not_utf8_name = Datei { $name } hat keinen gültigen UTF-8-Namen (einige Zeichen könnten nicht angezeigt werden)
|
||||
core_file_modified_before_epoch = Datei { $name } scheint vor dieser Unix-Epoche geändert worden zu sein
|
||||
core_folder_modified_before_epoch = Ordner { $name } scheint vor dieser Unix-Epoche geändert worden zu sein
|
||||
core_file_no_modification_date = Konnte das Änderungsdatum von Datei { $name } nicht abrufen, Grund { $reason }
|
||||
core_folder_no_modification_date = Konnte das Änderungsdatum aus dem Ordner { $name } nicht abrufen, Grund { $reason }
|
||||
core_missing_no_chosen_included_directory = Mindestens ein Verzeichnis muss angegeben werden
|
||||
core_directory_wildcard_no_supported = Verzeichnisse: Wildcards im Pfad werden nicht unterstützt, { $path } wird ignoriert
|
||||
core_directory_relative_path = Verzeichnisse: Relativer Pfad wird nicht unterstützt, { $path } wird ignoriert
|
||||
core_directory_must_exists = Verzeichnisse: Der angegebene Ordnerpfad muss beendet werden, { $path } wird ignoriert
|
||||
core_directory_must_be_directory = Verzeichnisse: Der angegebene Pfad muss auf das Verzeichnis zeigen und { $path } ignorieren
|
||||
core_included_directory_zero_valid_directories = Inklusive Verzeichnis-FEHLER: Nicht einmal einen korrekten Pfad zu inkludiert, der erforderlich ist
|
||||
core_excluded_directory_pointless_slash = Verzeichnisse: Ausschließen / ist sinnlos, weil es bedeutet, dass keine Dateien gescannt werden
|
||||
core_directory_overlap = Verzeichnisse: Alle Verzeichnisse zum Suchen von Überlappungen mit ausgeschlossenen Verzeichnissen
|
||||
core_directory_must_exists = Verzeichnisse: Der angegebene Ordnerpfad muss existieren, { $path } wird ignoriert
|
||||
core_directory_must_be_directory = Verzeichnisse: Der angegebene Pfad muss auf das Verzeichnis zeigen, { $path } wird ignoriert
|
||||
core_included_directory_zero_valid_directories = Einbezogenes Verzeichnis-FEHLER: Kein korrekter Pfad gefunden, welcher einbezogen werden soll, was erforderlich ist
|
||||
core_excluded_directory_pointless_slash = Verzeichnisse: / auszuschließen ist sinnlos, weil somit keine Dateien gescannt werden
|
||||
core_directory_overlap = Verzeichnisse: Alle zu durchsuchende Verzeichnisse überlappen mit den ausgeschlossenen Verzeichnissen
|
||||
core_directory_unable_to_get_device_id = Verzeichnisse: Geräte-ID kann nicht aus dem Ordner { $path } geholt werden
|
||||
core_ffmpeg_not_found = Keine richtige Installation von FFmpeg gefunden
|
||||
core_ffmpeg_missing_in_snap = Ähnliche Videos funktionieren derzeit nicht mit Snap, wenn du Hilfe möchtest - { $url }
|
||||
core_ffmpeg_not_found_windows = Stellen Sie sicher, dass ffmpeg.exe und ffprobe.exe in PATH verfügbar sind oder direkt in den gleichen Ordner gelegt werden, in dem die App ausführbar ist
|
||||
core_ffmpeg_missing_in_snap = Ähnliche Videos funktionieren derzeit nicht mit Snap, wenn du Hilfe möchtest, besuche - { $url }
|
||||
core_saving_to_cache = { $number } Cache-Einträge in der Datei gespeichert
|
||||
core_loading_from_cache = { $number } Einträge aus dem Cache geladen
|
||||
|
@ -0,0 +1,29 @@
|
||||
# Core
|
||||
core_similarity_original = 원본
|
||||
core_similarity_very_high = 매우 높음
|
||||
core_similarity_high = 높음
|
||||
core_similarity_medium = 보통
|
||||
core_similarity_small = 낮음
|
||||
core_similarity_very_small = 매우 낮음
|
||||
core_similarity_minimal = 최소
|
||||
core_cannot_open_dir = { $dir } 디렉터리를 열 수 없습니다. 이유: { $reason }
|
||||
core_cannot_read_entry_dir = { $dir } 디렉터리를 열 수 없습니다. 이유: { $reason }
|
||||
core_cannot_read_metadata_dir = { $dir } 디렉터리의 메타데이터를 열 수 없습니다. 이유: { $reason }
|
||||
core_file_not_utf8_name = 파일 이름 "{ $name }"은 유효한 UTF-8 이름이 아닙니다. 일부 글자가 보이지 않을 수 있습니다.
|
||||
core_file_modified_before_epoch = { $name } 파일이 Unix 시간 이전에 수정된 것 같습니다.
|
||||
core_folder_modified_before_epoch = { $name } 폴더가 Unix 시간 이전에 수정된 것 같습니다.
|
||||
core_file_no_modification_date = { $name } 파일의 수정된 시각을 읽을 수 없습니다. 이유: { $reason }
|
||||
core_folder_no_modification_date = { $name } 폴더의 수정된 시각을 읽을 수 없습니다. 이유: { $reason }
|
||||
core_missing_no_chosen_included_directory = 적어도 1개 이상의 디렉터리가 주어져야 합니다.
|
||||
core_directory_wildcard_no_supported = 디렉터리: 경로에는 와일드 카드가 지원되지 않습니다. "{ $path }"는 무시됩니다.
|
||||
core_directory_must_exists = 디렉터리: 주어진 폴더 경로는 반드시 존재해야 합니다. "{ $path }"는 무시됩니다.
|
||||
core_directory_must_be_directory = 디렉터리: 주어진 경로는 디렉터리를 가리켜야 합니다. "{ $path }"는 무시됩니다.
|
||||
core_included_directory_zero_valid_directories = 검색 대상 디렉터리 오류: 적어도 1개 이상의 유효한 경로가 주어져야 합니다. 유효한 경로가 하나도 없습니다.
|
||||
core_excluded_directory_pointless_slash = 디렉터리: "/"를 제외하는 것은 아무런 파일도 스캔하지 않는다는 것이므로, 의미가 없습니다.
|
||||
core_directory_overlap = 디렉터리: 모든 주어진 경로가 검색 제외 경로와 겹칩니다.
|
||||
core_directory_unable_to_get_device_id = 디렉터리: { $path }의 장치 ID를 가져올 수 없습니다.
|
||||
core_ffmpeg_not_found = 유효한 FFmpeg 설치를 발견하지 못했습니다.
|
||||
core_ffmpeg_not_found_windows = ffmpeg.exe와 ffprobe.exe가 시스템 변수 PATH에서 사용 가능하거나, 이 프로그램의 경로와 같은 곳에 위치하는지 확인하세요.
|
||||
core_ffmpeg_missing_in_snap = 현재 ffmpeg snap에서는 유사한 영상 검색이 지원되지 않습니다. 더 많은 정보는 { $url }에서 확인하세요.
|
||||
core_saving_to_cache = { $number }개의 파일을 캐시에 저장했습니다.
|
||||
core_loading_from_cache = { $number }개의 파일을 캐시에서 불러왔습니다.
|
@ -0,0 +1,29 @@
|
||||
# Core
|
||||
core_similarity_original = Origineel
|
||||
core_similarity_very_high = Zeer hoog
|
||||
core_similarity_high = hoog
|
||||
core_similarity_medium = Middelgroot
|
||||
core_similarity_small = Klein
|
||||
core_similarity_very_small = Zeer Klein
|
||||
core_similarity_minimal = Minimaal
|
||||
core_cannot_open_dir = Kan dir { $dir }niet openen, reden { $reason }
|
||||
core_cannot_read_entry_dir = Kan invoer niet lezen in map { $dir }, reden { $reason }
|
||||
core_cannot_read_metadata_dir = Kan metadata niet lezen in map { $dir }, reden { $reason }
|
||||
core_file_not_utf8_name = Bestand { $name } heeft geen geldige UTF-8-naam (sommige tekens kunnen niet worden getoond)
|
||||
core_file_modified_before_epoch = Het bestand { $name } lijkt aangepast te zijn voor Unix Epoch
|
||||
core_folder_modified_before_epoch = Map { $name } lijkt aangepast te zijn voor Unix Epoch
|
||||
core_file_no_modification_date = Niet in staat om de datum van bestand { $name }te krijgen, reden { $reason }
|
||||
core_folder_no_modification_date = Niet in staat om wijzigingsdatum van map { $name }te krijgen, reden { $reason }
|
||||
core_missing_no_chosen_included_directory = Ten minste één map moet worden opgegeven
|
||||
core_directory_wildcard_no_supported = Maps: Wildcards op pad worden niet ondersteund, negeer { $path }
|
||||
core_directory_must_exists = Maps: Opgegeven mappad moet bestaan, afwijzend { $path }
|
||||
core_directory_must_be_directory = Directories: Het opgegeven pad moet naar de map wijzen, { $path } wordt genegeerd
|
||||
core_included_directory_zero_valid_directories = Inclusief map FOUT: Er is niet één juist pad gevonden naar de map die vereist is
|
||||
core_excluded_directory_pointless_slash = Maps: Uitsluiten/is zinloos, omdat er geen bestanden worden gescand
|
||||
core_directory_overlap = Maps: alle mappen om overlappingen te zoeken met uitgesloten mappen
|
||||
core_directory_unable_to_get_device_id = Maps: Kan apparaat-id niet ophalen uit map { $path }
|
||||
core_ffmpeg_not_found = Kan de juiste installatie van FFmpeg niet vinden
|
||||
core_ffmpeg_not_found_windows = Zorg ervoor dat ffmpeg.exe en ffprobe.exe beschikbaar zijn in PATH of direct in dezelfde map geplaatst zijn waar de app uitvoerbaar is
|
||||
core_ffmpeg_missing_in_snap = Vergelijkbare video's werken momenteel niet met snap, als je wilt helpen kijken naar - { $url }
|
||||
core_saving_to_cache = Opgeslagen in bestand { $number } cache items
|
||||
core_loading_from_cache = Geladen uit cache { $number } items
|
@ -0,0 +1,29 @@
|
||||
# Core
|
||||
core_similarity_original = Opprinnelig
|
||||
core_similarity_very_high = Veldig høy
|
||||
core_similarity_high = Høy
|
||||
core_similarity_medium = Middels
|
||||
core_similarity_small = Liten
|
||||
core_similarity_very_small = Veldig liten
|
||||
core_similarity_minimal = Minimal
|
||||
core_cannot_open_dir = Kan ikke åpne dir { $dir }, årsak { $reason }
|
||||
core_cannot_read_entry_dir = Kan ikke lese oppføringen i dir { $dir }, årsak { $reason }
|
||||
core_cannot_read_metadata_dir = Kan ikke lese metadata i dir { $dir }, årsak { $reason }
|
||||
core_file_not_utf8_name = Filen { $name } har ikke et gyldig UTF-8-navn (noen tegn kan ikke vises)
|
||||
core_file_modified_before_epoch = Filen { $name } ser ut til å bli endret før Unix Epoch
|
||||
core_folder_modified_before_epoch = Mappen { $name } ser ut til å bli endret før Unix Epoch
|
||||
core_file_no_modification_date = Klarte ikke å hente endringsdato fra filen { $name }. Årsak { $reason }
|
||||
core_folder_no_modification_date = Klarte ikke å hente endringsdato fra mappen { $name }. Årsak { $reason }
|
||||
core_missing_no_chosen_included_directory = Minst en katalog må angis
|
||||
core_directory_wildcard_no_supported = Kataloger: Jokertegn i stien støttes ikke, ignorerer { $path }
|
||||
core_directory_must_exists = Kataloger: Angitt sti for mappe må eksistere. Ignorerer { $path }
|
||||
core_directory_must_be_directory = Kataloger: Angitt sti må peke på mappen. Ignorerer { $path }
|
||||
core_included_directory_zero_valid_directories = Feil med inkludert katalog: Fant ikke én eneste sti til den inkluderte mappen, noe som er påkrevd
|
||||
core_excluded_directory_pointless_slash = Kataloger: Ekskludere / er poengløst, fordi det betyr at ingen filer vil bli skannet
|
||||
core_directory_overlap = Kataloger: Alle kataloger å søke overlapper med ekskluderte mapper
|
||||
core_directory_unable_to_get_device_id = Mapper: Kan ikke hente enhets id fra mappen { $path }
|
||||
core_ffmpeg_not_found = Klarte ikke å finne riktig installasjon av FFmpeg
|
||||
core_ffmpeg_not_found_windows = Pass på at ffmpeg.exe og ffprobe.exe er tilgjengelig i PATH eller plasseres direkte i samme mappe som appen kan kjøres
|
||||
core_ffmpeg_missing_in_snap = Lignende videoer fungerer ikke for øyeblikket med snap. Hvis du vil ha hjelp kan du se her - { $url }
|
||||
core_saving_to_cache = Lagret i filen { $number } cache-oppføringer
|
||||
core_loading_from_cache = Lastet fra hurtigbuffer { $number } oppføringer
|
@ -0,0 +1,29 @@
|
||||
# Core
|
||||
core_similarity_original = Originală
|
||||
core_similarity_very_high = Foarte Mare
|
||||
core_similarity_high = Ridicat
|
||||
core_similarity_medium = Medie
|
||||
core_similarity_small = Mică
|
||||
core_similarity_very_small = Foarte mic
|
||||
core_similarity_minimal = Minimă
|
||||
core_cannot_open_dir = Nu se poate deschide dir { $dir }, motiv { $reason }
|
||||
core_cannot_read_entry_dir = Nu se poate citi intrarea în dir { $dir }, motivul { $reason }
|
||||
core_cannot_read_metadata_dir = Metadatele nu pot fi citite în dir { $dir }, motivul { $reason }
|
||||
core_file_not_utf8_name = Fișierul { $name } nu are un nume valid UTF-8 (este posibil ca unele caractere să nu fie afișate)
|
||||
core_file_modified_before_epoch = Fișierul { $name } pare să fie modificat înainte de Epoch Unix
|
||||
core_folder_modified_before_epoch = Dosarul { $name } pare să fie modificat înainte de Epoc Unix
|
||||
core_file_no_modification_date = Imposibil de obținut data modificării din fișierul { $name }, motivul { $reason }
|
||||
core_folder_no_modification_date = Imposibil de obținut data modificării din dosarul { $name }, motivul { $reason }
|
||||
core_missing_no_chosen_included_directory = Trebuie furnizat cel puțin un director
|
||||
core_directory_wildcard_no_supported = Directoare: Wildcards pe cale nu sunt acceptate, ignorând { $path }
|
||||
core_directory_must_exists = Directoare: Calea dosarului furnizat trebuie să existe, ignorând { $path }
|
||||
core_directory_must_be_directory = Directoare: Calea specificată trebuie să indice în director, ignorând { $path }
|
||||
core_included_directory_zero_valid_directories = EROARE din Director inclusă: Nici măcar o cale corectă de inclus, care este necesară
|
||||
core_excluded_directory_pointless_slash = Directoare: Excludere / este inutilă, deoarece înseamnă că niciun fișier nu va fi scanat
|
||||
core_directory_overlap = Directoare: Toate directoarele pentru a căuta suprapuneri cu directoarele excluse
|
||||
core_directory_unable_to_get_device_id = Directoare: Imposibil de obținut ID-ul dispozitivului din folderul { $path }
|
||||
core_ffmpeg_not_found = Nu se poate găsi instalarea corectă a FFmpeg
|
||||
core_ffmpeg_not_found_windows = Asigurați-vă că ffmpeg.exe și ffprobe.exe sunt disponibile în PATH sau sunt puse direct în același folder unde este executabilă aplicația
|
||||
core_ffmpeg_missing_in_snap = Videoclipuri similare nu funcționează în prezent cu ancorare, dacă doriți să vă uitați - { $url }
|
||||
core_saving_to_cache = Intrări cache salvate în fişierul { $number }
|
||||
core_loading_from_cache = Încărcat din geocutia { $number }
|
@ -0,0 +1,29 @@
|
||||
# Core
|
||||
core_similarity_original = Ursprunglig
|
||||
core_similarity_very_high = Mycket Hög
|
||||
core_similarity_high = Hög
|
||||
core_similarity_medium = Mellan
|
||||
core_similarity_small = Litet
|
||||
core_similarity_very_small = Väldigt Liten
|
||||
core_similarity_minimal = Minimalt
|
||||
core_cannot_open_dir = Kan inte öppna dir { $dir }anledning { $reason }
|
||||
core_cannot_read_entry_dir = Kan inte läsa post i dir { $dir }, anledning { $reason }
|
||||
core_cannot_read_metadata_dir = Kan inte läsa metadata i dir { $dir }, anledning { $reason }
|
||||
core_file_not_utf8_name = Filen { $name } har inte ett giltigt UTF-8-namn (vissa tecken kan inte visas)
|
||||
core_file_modified_before_epoch = Filen { $name } verkar ändras innan Unix Epoch
|
||||
core_folder_modified_before_epoch = Mappen { $name } verkar ändras innan Unix Epoch
|
||||
core_file_no_modification_date = Det går inte att hämta ändringsdatum från filen { $name }, anledning { $reason }
|
||||
core_folder_no_modification_date = Det går inte att hämta ändringsdatum från mappen { $name }, anledning { $reason }
|
||||
core_missing_no_chosen_included_directory = Minst en katalog måste tillhandahållas
|
||||
core_directory_wildcard_no_supported = Kataloger: Wildcards i sökvägen stöds inte, ignorerar { $path }
|
||||
core_directory_must_exists = Kataloger: Tillhandahållen mappsökväg måste finnas, ignorerar { $path }
|
||||
core_directory_must_be_directory = Kataloger: Tillhandahållen sökväg måste peka på katalogen, ignorerar { $path }
|
||||
core_included_directory_zero_valid_directories = Inkluderad katalog FEL: Hittas inte ens en korrekt sökväg till inkluderad som krävs
|
||||
core_excluded_directory_pointless_slash = Kataloger: Exklusive / är meningslös, eftersom det innebär att inga filer kommer att skannas
|
||||
core_directory_overlap = Kataloger: Alla kataloger att söka överlappar med uteslutna kataloger
|
||||
core_directory_unable_to_get_device_id = Kataloger: Det går inte att hämta enhets-id från mappen { $path }
|
||||
core_ffmpeg_not_found = Kan inte hitta rätt installation av FFmpeg
|
||||
core_ffmpeg_not_found_windows = Se till att ffmpeg.exe och ffprobe.exe är tillgängliga i PATH eller sätts direkt till samma mapp där är app körbar
|
||||
core_ffmpeg_missing_in_snap = Liknande videor fungerar inte just nu med snap, om du vill ha hjälp att titta på - { $url }
|
||||
core_saving_to_cache = Sparad i filen { $number } cacheposter
|
||||
core_loading_from_cache = Laddad från cache { $number } poster
|
@ -0,0 +1,460 @@
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::io::prelude::*;
|
||||
use std::mem;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
use fun_time::fun_time;
|
||||
use log::debug;
|
||||
use mime_guess::get_mime_extensions;
|
||||
use rayon::prelude::*;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::common::{check_if_stop_received, prepare_thread_handler_common, send_info_and_wait_for_ending_all_threads};
|
||||
use crate::common_dir_traversal::{CheckingMethod, DirTraversalBuilder, DirTraversalResult, FileEntry, ProgressData, ToolType};
|
||||
use crate::common_tool::{CommonData, CommonToolData};
|
||||
use crate::common_traits::*;
|
||||
|
||||
static DISABLED_EXTENSIONS: &[&str] = &["file", "cache", "bak", "data"]; // Such files can have any type inside
|
||||
|
||||
// This adds several workarounds for bugs/invalid recognizing types by external libraries
|
||||
// ("real_content_extension", "current_file_extension")
|
||||
const WORKAROUNDS: &[(&str, &str)] = &[
|
||||
// Wine/Windows
|
||||
("der", "cat"),
|
||||
("exe", "acm"),
|
||||
("exe", "ax"),
|
||||
("exe", "bck"),
|
||||
("exe", "com"),
|
||||
("exe", "cpl"),
|
||||
("exe", "dll16"),
|
||||
("exe", "dll"),
|
||||
("exe", "drv16"),
|
||||
("exe", "drv"),
|
||||
("exe", "ds"),
|
||||
("exe", "efi"),
|
||||
("exe", "exe16"),
|
||||
("exe", "fon"), // Type of font or something else
|
||||
("exe", "mod16"),
|
||||
("exe", "msstyles"),
|
||||
("exe", "mui"),
|
||||
("exe", "mun"),
|
||||
("exe", "orig"),
|
||||
("exe", "ps1xml"),
|
||||
("exe", "rll"),
|
||||
("exe", "rs"),
|
||||
("exe", "scr"),
|
||||
("exe", "signed"),
|
||||
("exe", "sys"),
|
||||
("exe", "tlb"),
|
||||
("exe", "tsp"),
|
||||
("exe", "vdm"),
|
||||
("exe", "vxd"),
|
||||
("exe", "winmd"),
|
||||
("gz", "loggz"),
|
||||
("xml", "adml"),
|
||||
("xml", "admx"),
|
||||
("xml", "camp"),
|
||||
("xml", "cdmp"),
|
||||
("xml", "cdxml"),
|
||||
("xml", "dgml"),
|
||||
("xml", "diagpkg"),
|
||||
("xml", "gmmp"),
|
||||
("xml", "library-ms"),
|
||||
("xml", "man"),
|
||||
("xml", "manifest"),
|
||||
("xml", "msc"),
|
||||
("xml", "mum"),
|
||||
("xml", "resx"),
|
||||
("zip", "wmz"),
|
||||
// Games specific extensions - cannot be used here common extensions like zip
|
||||
("gz", "h3m"), // Heroes 3
|
||||
("zip", "hashdb"), // Gog
|
||||
("zip", "c2"), // King of the Dark Age
|
||||
("bmp", "c2"), // King of the Dark Age
|
||||
("avi", "c2"), // King of the Dark Age
|
||||
("exe", "c2"), // King of the Dark Age
|
||||
// Other
|
||||
("der", "keystore"), // Godot/Android keystore
|
||||
("exe", "pyd"), // Python/Mingw
|
||||
("gz", "blend"), // Blender
|
||||
("gz", "crate"), // Cargo
|
||||
("gz", "svgz"), // Archive svg
|
||||
("gz", "tgz"), // Archive
|
||||
("html", "dtd"), // Mingw
|
||||
("html", "ent"), // Mingw
|
||||
("html", "md"), // Markdown
|
||||
("html", "svelte"), // Svelte
|
||||
("jpg", "jfif"), // Photo format
|
||||
("m4v", "mp4"), // m4v and mp4 are interchangeable
|
||||
("mobi", "azw3"), // Ebook format
|
||||
("mpg", "vob"), // Weddings in parts have usually vob extension
|
||||
("obj", "bin"), // Multiple apps, Czkawka, Nvidia, Windows
|
||||
("obj", "o"), // Compilators
|
||||
("odp", "otp"), // LibreOffice
|
||||
("ods", "ots"), // Libreoffice
|
||||
("odt", "ott"), // Libreoffice
|
||||
("ogg", "ogv"), // Audio format
|
||||
("pem", "key"), // curl, openssl
|
||||
("png", "kpp"), // Krita presets
|
||||
("pptx", "ppsx"), // Powerpoint
|
||||
("sh", "bash"), // Linux
|
||||
("sh", "guess"), // GNU
|
||||
("sh", "pl"), // Gnome/Linux
|
||||
("sh", "pm"), // Gnome/Linux
|
||||
("sh", "py"), // Python
|
||||
("sh", "pyx"), // Python
|
||||
("sh", "rs"), // Rust
|
||||
("sh", "sample"), // Git
|
||||
("xml", "bsp"), // Quartus
|
||||
("xml", "cbp"), // CodeBlocks config
|
||||
("xml", "cfg"), // Multiple apps - Godot
|
||||
("xml", "cmb"), // Cambalache
|
||||
("xml", "conf"), // Multiple apps - Python
|
||||
("xml", "config"), // Multiple apps - QT Creator
|
||||
("xml", "dae"), // 3D models
|
||||
("xml", "docbook"), //
|
||||
("xml", "fb2"), //
|
||||
("xml", "filters"), // Visual studio
|
||||
("xml", "gir"), // GTK
|
||||
("xml", "glade"), // Glade
|
||||
("xml", "iml"), // Intelij Idea
|
||||
("xml", "kdenlive"), // KDenLive
|
||||
("xml", "lang"), // ?
|
||||
("xml", "nuspec"), // Nuget
|
||||
("xml", "policy"), // SystemD
|
||||
("xml", "qsys"), // Quartus
|
||||
("xml", "sopcinfo"), // Quartus
|
||||
("xml", "svg"), // SVG
|
||||
("xml", "ui"), // Cambalache, Glade
|
||||
("xml", "user"), // Qtcreator
|
||||
("xml", "vbox"), // VirtualBox
|
||||
("xml", "vbox-prev"), // VirtualBox
|
||||
("xml", "vcproj"), // VisualStudio
|
||||
("xml", "vcxproj"), // VisualStudio
|
||||
("xml", "xba"), // Libreoffice
|
||||
("xml", "xcd"), // Libreoffice files
|
||||
("zip", "apk"), // Android apk
|
||||
("zip", "cbr"), // Comics
|
||||
("zip", "dat"), // Multiple - python, brave
|
||||
("zip", "doc"), // Word
|
||||
("zip", "docx"), // Word
|
||||
("zip", "jar"), // Java
|
||||
("zip", "kra"), // Krita
|
||||
("zip", "kgm"), // Krita
|
||||
("zip", "nupkg"), // Nuget packages
|
||||
("zip", "odg"), // Libreoffice
|
||||
("zip", "pptx"), // Powerpoint
|
||||
("zip", "whl"), // Python packages
|
||||
("zip", "xlsx"), // Excel
|
||||
("zip", "xpi"), // Firefox extensions
|
||||
("zip", "zcos"), // Scilab
|
||||
// Probably invalid
|
||||
("html", "svg"),
|
||||
("xml", "html"),
|
||||
// Probably bug in external library
|
||||
("msi", "ppt"), // Not sure why ppt is not recognized
|
||||
("msi", "doc"), // Not sure why doc is not recognized
|
||||
("exe", "xls"), // Not sure why xls is not recognized
|
||||
];
|
||||
|
||||
#[derive(Clone, Serialize, Debug)]
|
||||
pub struct BadFileEntry {
|
||||
pub path: PathBuf,
|
||||
pub modified_date: u64,
|
||||
pub size: u64,
|
||||
pub current_extension: String,
|
||||
pub proper_extensions: String,
|
||||
}
|
||||
|
||||
impl ResultEntry for BadFileEntry {
|
||||
fn get_path(&self) -> &Path {
|
||||
&self.path
|
||||
}
|
||||
fn get_modified_date(&self) -> u64 {
|
||||
self.modified_date
|
||||
}
|
||||
fn get_size(&self) -> u64 {
|
||||
self.size
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Info {
|
||||
pub number_of_files_with_bad_extension: usize,
|
||||
}
|
||||
|
||||
pub struct BadExtensions {
|
||||
common_data: CommonToolData,
|
||||
information: Info,
|
||||
files_to_check: Vec<FileEntry>,
|
||||
bad_extensions_files: Vec<BadFileEntry>,
|
||||
include_files_without_extension: bool,
|
||||
}
|
||||
|
||||
impl BadExtensions {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
common_data: CommonToolData::new(ToolType::BadExtensions),
|
||||
information: Info::default(),
|
||||
files_to_check: Default::default(),
|
||||
bad_extensions_files: Default::default(),
|
||||
include_files_without_extension: true,
|
||||
}
|
||||
}
|
||||
|
||||
#[fun_time(message = "find_bad_extensions_files", level = "info")]
|
||||
pub fn find_bad_extensions_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
|
||||
self.prepare_items();
|
||||
if !self.check_files(stop_receiver, progress_sender) {
|
||||
self.common_data.stopped_search = true;
|
||||
return;
|
||||
}
|
||||
if !self.look_for_bad_extensions_files(stop_receiver, progress_sender) {
|
||||
self.common_data.stopped_search = true;
|
||||
return;
|
||||
}
|
||||
self.debug_print();
|
||||
}
|
||||
|
||||
#[fun_time(message = "check_files", level = "debug")]
|
||||
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
|
||||
let result = DirTraversalBuilder::new()
|
||||
.common_data(&self.common_data)
|
||||
.group_by(|_fe| ())
|
||||
.stop_receiver(stop_receiver)
|
||||
.progress_sender(progress_sender)
|
||||
.build()
|
||||
.run();
|
||||
|
||||
match result {
|
||||
DirTraversalResult::SuccessFiles { grouped_file_entries, warnings } => {
|
||||
self.files_to_check = grouped_file_entries.into_values().flatten().collect();
|
||||
self.common_data.text_messages.warnings.extend(warnings);
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
DirTraversalResult::Stopped => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[fun_time(message = "look_for_bad_extensions_files", level = "debug")]
|
||||
fn look_for_bad_extensions_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
|
||||
let (progress_thread_handle, progress_thread_run, atomic_counter, check_was_stopped) =
|
||||
prepare_thread_handler_common(progress_sender, 1, 1, self.files_to_check.len(), CheckingMethod::None, self.get_cd().tool_type);
|
||||
|
||||
let files_to_check = mem::take(&mut self.files_to_check);
|
||||
|
||||
let mut hashmap_workarounds: HashMap<&str, Vec<&str>> = Default::default();
|
||||
for (proper, found) in WORKAROUNDS {
|
||||
// This should be enabled when items will have only 1 possible workaround items, but looks that some have 2 or even more, so at least for now this is disabled
|
||||
// if hashmap_workarounds.contains_key(found) {
|
||||
// panic!("Already have {} key", found);
|
||||
// }
|
||||
hashmap_workarounds.entry(found).or_default().push(proper);
|
||||
}
|
||||
|
||||
self.bad_extensions_files = self.verify_extensions(files_to_check, &atomic_counter, stop_receiver, &check_was_stopped, &hashmap_workarounds);
|
||||
|
||||
send_info_and_wait_for_ending_all_threads(&progress_thread_run, progress_thread_handle);
|
||||
|
||||
// Break if stop was clicked
|
||||
if check_was_stopped.load(Ordering::Relaxed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.information.number_of_files_with_bad_extension = self.bad_extensions_files.len();
|
||||
|
||||
debug!("Found {} files with invalid extension.", self.information.number_of_files_with_bad_extension);
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
#[fun_time(message = "verify_extensions", level = "debug")]
|
||||
fn verify_extensions(
|
||||
&self,
|
||||
files_to_check: Vec<FileEntry>,
|
||||
atomic_counter: &Arc<AtomicUsize>,
|
||||
stop_receiver: Option<&Receiver<()>>,
|
||||
check_was_stopped: &AtomicBool,
|
||||
hashmap_workarounds: &HashMap<&str, Vec<&str>>,
|
||||
) -> Vec<BadFileEntry> {
|
||||
files_to_check
|
||||
.into_par_iter()
|
||||
.map(|file_entry| {
|
||||
atomic_counter.fetch_add(1, Ordering::Relaxed);
|
||||
if check_if_stop_received(stop_receiver) {
|
||||
check_was_stopped.store(true, Ordering::Relaxed);
|
||||
return None;
|
||||
}
|
||||
|
||||
// Check what exactly content file contains
|
||||
let kind = match infer::get_from_path(&file_entry.path) {
|
||||
Ok(k) => match k {
|
||||
Some(t) => t,
|
||||
None => return Some(None),
|
||||
},
|
||||
Err(_) => return Some(None),
|
||||
};
|
||||
let proper_extension = kind.extension();
|
||||
|
||||
let Some(current_extension) = self.get_and_validate_extension(&file_entry, proper_extension) else {
|
||||
return Some(None);
|
||||
};
|
||||
|
||||
// Check for all extensions that file can use(not sure if it is worth to do it)
|
||||
let (mut all_available_extensions, valid_extensions) = self.check_for_all_extensions_that_file_can_use(hashmap_workarounds, ¤t_extension, proper_extension);
|
||||
|
||||
if all_available_extensions.is_empty() {
|
||||
// Not found any extension
|
||||
return Some(None);
|
||||
} else if current_extension.is_empty() {
|
||||
if !self.include_files_without_extension {
|
||||
return Some(None);
|
||||
}
|
||||
} else if all_available_extensions.take(¤t_extension).is_some() {
|
||||
// Found proper extension
|
||||
return Some(None);
|
||||
}
|
||||
|
||||
Some(Some(BadFileEntry {
|
||||
path: file_entry.path,
|
||||
modified_date: file_entry.modified_date,
|
||||
size: file_entry.size,
|
||||
current_extension,
|
||||
proper_extensions: valid_extensions,
|
||||
}))
|
||||
})
|
||||
.while_some()
|
||||
.filter(Option::is_some)
|
||||
.map(Option::unwrap)
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn get_and_validate_extension(&self, file_entry: &FileEntry, proper_extension: &str) -> Option<String> {
|
||||
let current_extension;
|
||||
// Extract current extension from file
|
||||
if let Some(extension) = file_entry.path.extension() {
|
||||
let extension = extension.to_string_lossy().to_lowercase();
|
||||
if DISABLED_EXTENSIONS.contains(&extension.as_str()) {
|
||||
return None;
|
||||
}
|
||||
// Text longer than 10 characters is not considered as extension
|
||||
if extension.len() > 10 {
|
||||
current_extension = String::new();
|
||||
} else {
|
||||
current_extension = extension;
|
||||
}
|
||||
} else {
|
||||
current_extension = String::new();
|
||||
}
|
||||
|
||||
// Already have proper extension, no need to do more things
|
||||
if current_extension == proper_extension {
|
||||
return None;
|
||||
}
|
||||
Some(current_extension)
|
||||
}
|
||||
|
||||
fn check_for_all_extensions_that_file_can_use(
|
||||
&self,
|
||||
hashmap_workarounds: &HashMap<&str, Vec<&str>>,
|
||||
current_extension: &str,
|
||||
proper_extension: &str,
|
||||
) -> (BTreeSet<String>, String) {
|
||||
let mut all_available_extensions: BTreeSet<String> = Default::default();
|
||||
let valid_extensions = if current_extension.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
for mim in mime_guess::from_ext(proper_extension) {
|
||||
if let Some(all_ext) = get_mime_extensions(&mim) {
|
||||
for ext in all_ext {
|
||||
all_available_extensions.insert((*ext).to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Workarounds
|
||||
if let Some(vec_pre) = hashmap_workarounds.get(current_extension) {
|
||||
for pre in vec_pre {
|
||||
if all_available_extensions.contains(*pre) {
|
||||
all_available_extensions.insert(current_extension.to_string());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut guessed_multiple_extensions = format!("({proper_extension}) - ");
|
||||
for ext in &all_available_extensions {
|
||||
guessed_multiple_extensions.push_str(ext);
|
||||
guessed_multiple_extensions.push(',');
|
||||
}
|
||||
guessed_multiple_extensions.pop();
|
||||
|
||||
guessed_multiple_extensions
|
||||
};
|
||||
(all_available_extensions, valid_extensions)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BadExtensions {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugPrint for BadExtensions {
|
||||
fn debug_print(&self) {
|
||||
if !cfg!(debug_assertions) {
|
||||
return;
|
||||
}
|
||||
println!("---------------DEBUG PRINT---------------");
|
||||
self.debug_print_common();
|
||||
println!("-----------------------------------------");
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintResults for BadExtensions {
|
||||
fn write_results<T: Write>(&self, writer: &mut T) -> std::io::Result<()> {
|
||||
writeln!(
|
||||
writer,
|
||||
"Results of searching {:?} with excluded directories {:?} and excluded items {:?}",
|
||||
self.common_data.directories.included_directories,
|
||||
self.common_data.directories.excluded_directories,
|
||||
self.common_data.excluded_items.get_excluded_items()
|
||||
)?;
|
||||
writeln!(writer, "Found {} files with invalid extension.\n", self.information.number_of_files_with_bad_extension)?;
|
||||
|
||||
for file_entry in &self.bad_extensions_files {
|
||||
writeln!(writer, "{:?} ----- {}", file_entry.path, file_entry.proper_extensions)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn save_results_to_file_as_json(&self, file_name: &str, pretty_print: bool) -> std::io::Result<()> {
|
||||
self.save_results_to_file_as_json_internal(file_name, &self.bad_extensions_files, pretty_print)
|
||||
}
|
||||
}
|
||||
|
||||
impl BadExtensions {
|
||||
pub const fn get_bad_extensions_files(&self) -> &Vec<BadFileEntry> {
|
||||
&self.bad_extensions_files
|
||||
}
|
||||
|
||||
pub const fn get_information(&self) -> &Info {
|
||||
&self.information
|
||||
}
|
||||
}
|
||||
|
||||
impl CommonData for BadExtensions {
|
||||
fn get_cd(&self) -> &CommonToolData {
|
||||
&self.common_data
|
||||
}
|
||||
fn get_cd_mut(&mut self) -> &mut CommonToolData {
|
||||
&mut self.common_data
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,241 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::io::{BufReader, BufWriter};
|
||||
|
||||
use fun_time::fun_time;
|
||||
use image::imageops::FilterType;
|
||||
use image_hasher::HashAlg;
|
||||
use log::debug;
|
||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::common;
|
||||
use crate::common_messages::Messages;
|
||||
use crate::common_traits::ResultEntry;
|
||||
use crate::duplicate::HashType;
|
||||
use crate::similar_images::{convert_algorithm_to_string, convert_filters_to_string};
|
||||
|
||||
const CACHE_VERSION: &str = "70";
|
||||
|
||||
pub fn get_broken_files_cache_file() -> String {
|
||||
format!("cache_broken_files_{CACHE_VERSION}.bin")
|
||||
}
|
||||
|
||||
pub fn get_similar_images_cache_file(hash_size: &u8, hash_alg: &HashAlg, image_filter: &FilterType) -> String {
|
||||
format!(
|
||||
"cache_similar_images_{hash_size}_{}_{}_{CACHE_VERSION}.bin",
|
||||
convert_algorithm_to_string(hash_alg),
|
||||
convert_filters_to_string(image_filter),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_similar_videos_cache_file() -> String {
|
||||
format!("cache_similar_videos_{CACHE_VERSION}.bin")
|
||||
}
|
||||
pub fn get_similar_music_cache_file(checking_tags: bool) -> String {
|
||||
if checking_tags {
|
||||
format!("cache_same_music_tags_{CACHE_VERSION}.bin")
|
||||
} else {
|
||||
format!("cache_same_music_fingerprints_{CACHE_VERSION}.bin")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_duplicate_cache_file(type_of_hash: &HashType, is_prehash: bool) -> String {
|
||||
let prehash_str = if is_prehash { "_prehash" } else { "" };
|
||||
format!("cache_duplicates_{type_of_hash:?}{prehash_str}_{CACHE_VERSION}.bin")
|
||||
}
|
||||
|
||||
#[fun_time(message = "save_cache_to_file_generalized", level = "debug")]
|
||||
pub fn save_cache_to_file_generalized<T>(cache_file_name: &str, hashmap: &BTreeMap<String, T>, save_also_as_json: bool, minimum_file_size: u64) -> Messages
|
||||
where
|
||||
T: Serialize + ResultEntry + Sized + Send + Sync,
|
||||
{
|
||||
let mut text_messages = Messages::new();
|
||||
if let Some(((file_handler, cache_file), (file_handler_json, cache_file_json))) =
|
||||
common::open_cache_folder(cache_file_name, true, save_also_as_json, &mut text_messages.warnings)
|
||||
{
|
||||
let hashmap_to_save = hashmap.values().filter(|t| t.get_size() >= minimum_file_size).collect::<Vec<_>>();
|
||||
|
||||
{
|
||||
let writer = BufWriter::new(file_handler.unwrap()); // Unwrap because cannot fail here
|
||||
if let Err(e) = bincode::serialize_into(writer, &hashmap_to_save) {
|
||||
text_messages.warnings.push(format!("Cannot write data to cache file {cache_file:?}, reason {e}"));
|
||||
debug!("Failed to save cache to file {cache_file:?}");
|
||||
return text_messages;
|
||||
}
|
||||
debug!("Saved binary to file {cache_file:?}");
|
||||
}
|
||||
if save_also_as_json {
|
||||
if let Some(file_handler_json) = file_handler_json {
|
||||
let writer = BufWriter::new(file_handler_json);
|
||||
if let Err(e) = serde_json::to_writer(writer, &hashmap_to_save) {
|
||||
text_messages.warnings.push(format!("Cannot write data to cache file {cache_file_json:?}, reason {e}"));
|
||||
debug!("Failed to save cache to file {cache_file_json:?}");
|
||||
return text_messages;
|
||||
}
|
||||
debug!("Saved json to file {cache_file_json:?}");
|
||||
}
|
||||
}
|
||||
|
||||
text_messages.messages.push(format!("Properly saved to file {} cache entries.", hashmap.len()));
|
||||
debug!("Properly saved to file {} cache entries.", hashmap.len());
|
||||
} else {
|
||||
debug!("Failed to save cache to file {cache_file_name} because not exists");
|
||||
}
|
||||
text_messages
|
||||
}
|
||||
|
||||
#[fun_time(message = "load_cache_from_file_generalized_by_path", level = "debug")]
|
||||
pub fn load_cache_from_file_generalized_by_path<T>(cache_file_name: &str, delete_outdated_cache: bool, used_files: &BTreeMap<String, T>) -> (Messages, Option<BTreeMap<String, T>>)
|
||||
where
|
||||
for<'a> T: Deserialize<'a> + ResultEntry + Sized + Send + Sync + Clone,
|
||||
{
|
||||
let (text_messages, vec_loaded_cache) = load_cache_from_file_generalized(cache_file_name, delete_outdated_cache, used_files);
|
||||
let Some(vec_loaded_entries) = vec_loaded_cache else {
|
||||
return (text_messages, None);
|
||||
};
|
||||
|
||||
debug!("Converting cache Vec<T> into BTreeMap<String, T>");
|
||||
let map_loaded_entries: BTreeMap<String, T> = vec_loaded_entries
|
||||
.into_iter()
|
||||
.map(|file_entry| (file_entry.get_path().to_string_lossy().into_owned(), file_entry))
|
||||
.collect();
|
||||
debug!("Converted cache Vec<T> into BTreeMap<String, T>");
|
||||
|
||||
(text_messages, Some(map_loaded_entries))
|
||||
}
|
||||
|
||||
#[fun_time(message = "load_cache_from_file_generalized_by_size", level = "debug")]
|
||||
pub fn load_cache_from_file_generalized_by_size<T>(
|
||||
cache_file_name: &str,
|
||||
delete_outdated_cache: bool,
|
||||
cache_not_converted: &BTreeMap<u64, Vec<T>>,
|
||||
) -> (Messages, Option<BTreeMap<u64, Vec<T>>>)
|
||||
where
|
||||
for<'a> T: Deserialize<'a> + ResultEntry + Sized + Send + Sync + Clone,
|
||||
{
|
||||
debug!("Converting cache BtreeMap<u64, Vec<T>> into BTreeMap<String, T>");
|
||||
let mut used_files: BTreeMap<String, T> = Default::default();
|
||||
for file_entry in cache_not_converted.values().flatten() {
|
||||
used_files.insert(file_entry.get_path().to_string_lossy().into_owned(), file_entry.clone());
|
||||
}
|
||||
debug!("Converted cache BtreeMap<u64, Vec<T>> into BTreeMap<String, T>");
|
||||
|
||||
let (text_messages, vec_loaded_cache) = load_cache_from_file_generalized(cache_file_name, delete_outdated_cache, &used_files);
|
||||
let Some(vec_loaded_entries) = vec_loaded_cache else {
|
||||
return (text_messages, None);
|
||||
};
|
||||
|
||||
debug!("Converting cache Vec<T> into BTreeMap<u64, Vec<T>>");
|
||||
let mut map_loaded_entries: BTreeMap<u64, Vec<T>> = Default::default();
|
||||
for file_entry in vec_loaded_entries {
|
||||
map_loaded_entries.entry(file_entry.get_size()).or_default().push(file_entry);
|
||||
}
|
||||
debug!("Converted cache Vec<T> into BTreeMap<u64, Vec<T>>");
|
||||
|
||||
(text_messages, Some(map_loaded_entries))
|
||||
}
|
||||
|
||||
#[fun_time(message = "load_cache_from_file_generalized_by_path_from_size", level = "debug")]
|
||||
pub fn load_cache_from_file_generalized_by_path_from_size<T>(
|
||||
cache_file_name: &str,
|
||||
delete_outdated_cache: bool,
|
||||
cache_not_converted: &BTreeMap<u64, Vec<T>>,
|
||||
) -> (Messages, Option<BTreeMap<String, T>>)
|
||||
where
|
||||
for<'a> T: Deserialize<'a> + ResultEntry + Sized + Send + Sync + Clone,
|
||||
{
|
||||
debug!("Converting cache BtreeMap<u64, Vec<T>> into BTreeMap<String, T>");
|
||||
let mut used_files: BTreeMap<String, T> = Default::default();
|
||||
for file_entry in cache_not_converted.values().flatten() {
|
||||
used_files.insert(file_entry.get_path().to_string_lossy().into_owned(), file_entry.clone());
|
||||
}
|
||||
debug!("Converted cache BtreeMap<u64, Vec<T>> into BTreeMap<String, T>");
|
||||
|
||||
let (text_messages, vec_loaded_cache) = load_cache_from_file_generalized(cache_file_name, delete_outdated_cache, &used_files);
|
||||
let Some(vec_loaded_entries) = vec_loaded_cache else {
|
||||
return (text_messages, None);
|
||||
};
|
||||
|
||||
debug!("Converting cache Vec<T> into BTreeMap<String, T>");
|
||||
let map_loaded_entries: BTreeMap<String, T> = vec_loaded_entries
|
||||
.into_iter()
|
||||
.map(|file_entry| (file_entry.get_path().to_string_lossy().into_owned(), file_entry))
|
||||
.collect();
|
||||
debug!("Converted cache Vec<T> into BTreeMap<String, T>");
|
||||
|
||||
(text_messages, Some(map_loaded_entries))
|
||||
}
|
||||
|
||||
#[fun_time(message = "load_cache_from_file_generalized", level = "debug")]
|
||||
fn load_cache_from_file_generalized<T>(cache_file_name: &str, delete_outdated_cache: bool, used_files: &BTreeMap<String, T>) -> (Messages, Option<Vec<T>>)
|
||||
where
|
||||
for<'a> T: Deserialize<'a> + ResultEntry + Sized + Send + Sync + Clone,
|
||||
{
|
||||
let mut text_messages = Messages::new();
|
||||
|
||||
if let Some(((file_handler, cache_file), (file_handler_json, cache_file_json))) = common::open_cache_folder(cache_file_name, false, true, &mut text_messages.warnings) {
|
||||
let mut vec_loaded_entries: Vec<T>;
|
||||
if let Some(file_handler) = file_handler {
|
||||
let reader = BufReader::new(file_handler);
|
||||
|
||||
vec_loaded_entries = match bincode::deserialize_from(reader) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
text_messages.warnings.push(format!("Failed to load data from cache file {cache_file:?}, reason {e}"));
|
||||
debug!("Failed to load cache from file {cache_file:?}");
|
||||
return (text_messages, None);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
let reader = BufReader::new(file_handler_json.unwrap()); // Unwrap cannot fail, because at least one file must be valid
|
||||
vec_loaded_entries = match serde_json::from_reader(reader) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
text_messages.warnings.push(format!("Failed to load data from cache file {cache_file_json:?}, reason {e}"));
|
||||
debug!("Failed to load cache from file {cache_file:?}");
|
||||
return (text_messages, None);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
debug!(
|
||||
"Starting removing outdated cache entries (removing non existent files from cache - {})",
|
||||
delete_outdated_cache
|
||||
);
|
||||
let initial_number_of_entries = vec_loaded_entries.len();
|
||||
vec_loaded_entries = vec_loaded_entries
|
||||
.into_par_iter()
|
||||
.filter(|file_entry| {
|
||||
let path = file_entry.get_path();
|
||||
|
||||
let file_entry_path_str = path.to_string_lossy().to_string();
|
||||
if let Some(used_file) = used_files.get(&file_entry_path_str) {
|
||||
if file_entry.get_size() != used_file.get_size() {
|
||||
return false;
|
||||
}
|
||||
if file_entry.get_modified_date() != used_file.get_modified_date() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if delete_outdated_cache && !path.exists() {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
.collect();
|
||||
debug!(
|
||||
"Completed removing outdated cache entries, removed {} out of all {} entries",
|
||||
initial_number_of_entries - vec_loaded_entries.len(),
|
||||
initial_number_of_entries
|
||||
);
|
||||
|
||||
text_messages.messages.push(format!("Properly loaded {} cache entries.", vec_loaded_entries.len()));
|
||||
|
||||
debug!("Loaded cache from file {cache_file_name} (or json alternative) - {} results", vec_loaded_entries.len());
|
||||
return (text_messages, Some(vec_loaded_entries));
|
||||
}
|
||||
debug!("Failed to load cache from file {cache_file_name} because not exists");
|
||||
(text_messages, None)
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,80 +1,124 @@
|
||||
use std::time::SystemTime;
|
||||
use std::collections::HashSet;
|
||||
use std::fs::DirEntry;
|
||||
|
||||
use crate::common::Common;
|
||||
use crate::common_messages::Messages;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Extensions {
|
||||
file_extensions: Vec<String>,
|
||||
allowed_extensions_hashset: HashSet<String>,
|
||||
excluded_extensions_hashset: HashSet<String>,
|
||||
}
|
||||
|
||||
impl Extensions {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
/// List of allowed extensions, only files with this extensions will be checking if are duplicates
|
||||
/// After, extensions cannot contains any dot, commas etc.
|
||||
pub fn set_allowed_extensions(&mut self, mut allowed_extensions: String, text_messages: &mut Messages) {
|
||||
let start_time: SystemTime = SystemTime::now();
|
||||
if allowed_extensions.trim().is_empty() {
|
||||
return;
|
||||
|
||||
pub fn filter_extensions(mut file_extensions: String) -> (HashSet<String>, Messages) {
|
||||
let mut messages = Messages::new();
|
||||
let mut extensions_hashset = HashSet::new();
|
||||
|
||||
if file_extensions.trim().is_empty() {
|
||||
return (Default::default(), messages);
|
||||
}
|
||||
allowed_extensions = allowed_extensions.replace("IMAGE", "jpg,kra,gif,png,bmp,tiff,hdr,svg");
|
||||
allowed_extensions = allowed_extensions.replace("VIDEO", "mp4,flv,mkv,webm,vob,ogv,gifv,avi,mov,wmv,mpg,m4v,m4p,mpeg,3gp");
|
||||
allowed_extensions = allowed_extensions.replace("MUSIC", "mp3,flac,ogg,tta,wma,webm");
|
||||
allowed_extensions = allowed_extensions.replace("TEXT", "txt,doc,docx,odt,rtf");
|
||||
file_extensions = file_extensions.replace("IMAGE", "jpg,kra,gif,png,bmp,tiff,hdr,svg");
|
||||
file_extensions = file_extensions.replace("VIDEO", "mp4,flv,mkv,webm,vob,ogv,gifv,avi,mov,wmv,mpg,m4v,m4p,mpeg,3gp");
|
||||
file_extensions = file_extensions.replace("MUSIC", "mp3,flac,ogg,tta,wma,webm");
|
||||
file_extensions = file_extensions.replace("TEXT", "txt,doc,docx,odt,rtf");
|
||||
|
||||
let extensions: Vec<String> = allowed_extensions.split(',').map(|e| e.trim()).map(String::from).collect();
|
||||
let extensions: Vec<String> = file_extensions.split(',').map(str::trim).map(String::from).collect();
|
||||
for mut extension in extensions {
|
||||
if extension.is_empty() || extension.replace('.', "").replace(' ', "").trim().is_empty() {
|
||||
if extension.is_empty() || extension.replace(['.', ' '], "").trim().is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !extension.starts_with('.') {
|
||||
extension = format!(".{}", extension);
|
||||
if extension.starts_with('.') {
|
||||
extension = extension.chars().skip(1).collect::<String>();
|
||||
}
|
||||
|
||||
if extension[1..].contains('.') {
|
||||
text_messages.warnings.push(format!("{} is not valid extension because contains dot inside", extension));
|
||||
if extension.contains('.') {
|
||||
messages.warnings.push(format!("{extension} is not valid extension because contains dot inside"));
|
||||
continue;
|
||||
}
|
||||
|
||||
if extension[1..].contains(' ') {
|
||||
text_messages
|
||||
.warnings
|
||||
.push(format!("{} is not valid extension because contains empty space inside", extension));
|
||||
if extension.contains(' ') {
|
||||
messages.warnings.push(format!("{extension} is not valid extension because contains empty space inside"));
|
||||
continue;
|
||||
}
|
||||
|
||||
if !self.file_extensions.contains(&extension) {
|
||||
self.file_extensions.push(extension);
|
||||
}
|
||||
extensions_hashset.insert(extension);
|
||||
}
|
||||
(extensions_hashset, messages)
|
||||
}
|
||||
|
||||
if self.file_extensions.is_empty() {
|
||||
text_messages
|
||||
.messages
|
||||
.push("No valid extensions were provided, so allowing all extensions by default.".to_string());
|
||||
}
|
||||
Common::print_time(start_time, SystemTime::now(), "set_allowed_extensions".to_string());
|
||||
/// List of allowed extensions, only files with this extensions will be checking if are duplicates
|
||||
/// After, extensions cannot contain any dot, commas etc.
|
||||
pub fn set_allowed_extensions(&mut self, allowed_extensions: String) -> Messages {
|
||||
let (extensions, messages) = Self::filter_extensions(allowed_extensions);
|
||||
|
||||
self.allowed_extensions_hashset = extensions;
|
||||
messages
|
||||
}
|
||||
|
||||
pub fn set_excluded_extensions(&mut self, excluded_extensions: String) -> Messages {
|
||||
let (extensions, messages) = Self::filter_extensions(excluded_extensions);
|
||||
|
||||
self.excluded_extensions_hashset = extensions;
|
||||
messages
|
||||
}
|
||||
|
||||
pub fn matches_filename(&self, file_name: &str) -> bool {
|
||||
// assert_eq!(file_name, file_name.to_lowercase());
|
||||
if !self.file_extensions.is_empty() && !self.file_extensions.iter().any(|e| file_name.ends_with(e)) {
|
||||
return false;
|
||||
pub fn check_if_entry_have_valid_extension(&self, entry_data: &DirEntry) -> bool {
|
||||
if self.allowed_extensions_hashset.is_empty() && self.excluded_extensions_hashset.is_empty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Using entry_data.path().extension() is a lot of slower, even 5 times
|
||||
let file_name = entry_data.file_name();
|
||||
let Some(file_name_str) = file_name.to_str() else { return false };
|
||||
let Some(extension_idx) = file_name_str.rfind('.') else { return false };
|
||||
let extension = &file_name_str[extension_idx + 1..];
|
||||
|
||||
if !self.allowed_extensions_hashset.is_empty() {
|
||||
if extension.chars().all(|c| c.is_ascii_lowercase()) {
|
||||
self.allowed_extensions_hashset.contains(extension)
|
||||
} else {
|
||||
self.allowed_extensions_hashset.contains(&extension.to_lowercase())
|
||||
}
|
||||
} else {
|
||||
if extension.chars().all(|c| c.is_ascii_lowercase()) {
|
||||
!self.excluded_extensions_hashset.contains(extension)
|
||||
} else {
|
||||
!self.excluded_extensions_hashset.contains(&extension.to_lowercase())
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub fn using_custom_extensions(&self) -> bool {
|
||||
!self.file_extensions.is_empty()
|
||||
pub fn set_any_extensions(&self) -> bool {
|
||||
!self.allowed_extensions_hashset.is_empty()
|
||||
}
|
||||
|
||||
pub fn extend_allowed_extensions(&mut self, file_extensions: &[&str]) {
|
||||
fn extend_allowed_extensions(&mut self, file_extensions: &[&str]) {
|
||||
for extension in file_extensions {
|
||||
assert!(extension.starts_with('.'));
|
||||
self.file_extensions.push(extension.to_string());
|
||||
let extension_without_dot = extension.trim_start_matches('.');
|
||||
self.allowed_extensions_hashset.insert(extension_without_dot.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// E.g. when using similar videos, user can provide extensions like "mp4,flv", but if user provide "mp4,jpg" then
|
||||
// it will be only "mp4" because "jpg" is not valid extension for videos
|
||||
fn union_allowed_extensions(&mut self, file_extensions: &[&str]) {
|
||||
let mut new_extensions = HashSet::new();
|
||||
for extension in file_extensions {
|
||||
let extension_without_dot = extension.trim_start_matches('.');
|
||||
new_extensions.insert(extension_without_dot.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_and_validate_allowed_extensions(&mut self, file_extensions: &[&str]) {
|
||||
if self.allowed_extensions_hashset.is_empty() {
|
||||
self.extend_allowed_extensions(file_extensions);
|
||||
} else {
|
||||
self.union_allowed_extensions(file_extensions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,213 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::common_dir_traversal::ToolType;
|
||||
use crate::common_directory::Directories;
|
||||
use crate::common_extensions::Extensions;
|
||||
use crate::common_items::ExcludedItems;
|
||||
use crate::common_messages::Messages;
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct CommonToolData {
|
||||
pub(crate) tool_type: ToolType,
|
||||
pub(crate) text_messages: Messages,
|
||||
pub(crate) directories: Directories,
|
||||
pub(crate) extensions: Extensions,
|
||||
pub(crate) excluded_items: ExcludedItems,
|
||||
pub(crate) recursive_search: bool,
|
||||
pub(crate) delete_method: DeleteMethod,
|
||||
pub(crate) maximal_file_size: u64,
|
||||
pub(crate) minimal_file_size: u64,
|
||||
pub(crate) stopped_search: bool,
|
||||
pub(crate) use_cache: bool,
|
||||
pub(crate) delete_outdated_cache: bool,
|
||||
pub(crate) save_also_as_json: bool,
|
||||
pub(crate) use_reference_folders: bool,
|
||||
pub(crate) dry_run: bool,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Debug, Copy, Default)]
|
||||
pub enum DeleteMethod {
|
||||
#[default]
|
||||
None,
|
||||
Delete, // Just delete items
|
||||
AllExceptNewest,
|
||||
AllExceptOldest,
|
||||
OneOldest,
|
||||
OneNewest,
|
||||
HardLink,
|
||||
}
|
||||
|
||||
impl CommonToolData {
|
||||
pub fn new(tool_type: ToolType) -> Self {
|
||||
Self {
|
||||
tool_type,
|
||||
text_messages: Messages::new(),
|
||||
directories: Directories::new(),
|
||||
extensions: Extensions::new(),
|
||||
excluded_items: ExcludedItems::new(),
|
||||
recursive_search: true,
|
||||
delete_method: DeleteMethod::None,
|
||||
maximal_file_size: u64::MAX,
|
||||
minimal_file_size: 8192,
|
||||
stopped_search: false,
|
||||
use_cache: true,
|
||||
delete_outdated_cache: true,
|
||||
save_also_as_json: false,
|
||||
use_reference_folders: false,
|
||||
dry_run: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CommonData {
|
||||
fn get_cd(&self) -> &CommonToolData;
|
||||
fn get_cd_mut(&mut self) -> &mut CommonToolData;
|
||||
|
||||
fn set_dry_run(&mut self, dry_run: bool) {
|
||||
self.get_cd_mut().dry_run = dry_run;
|
||||
}
|
||||
fn get_dry_run(&self) -> bool {
|
||||
self.get_cd().dry_run
|
||||
}
|
||||
|
||||
fn set_use_cache(&mut self, use_cache: bool) {
|
||||
self.get_cd_mut().use_cache = use_cache;
|
||||
}
|
||||
fn get_use_cache(&self) -> bool {
|
||||
self.get_cd().use_cache
|
||||
}
|
||||
|
||||
fn set_delete_outdated_cache(&mut self, delete_outdated_cache: bool) {
|
||||
self.get_cd_mut().delete_outdated_cache = delete_outdated_cache;
|
||||
}
|
||||
fn get_delete_outdated_cache(&self) -> bool {
|
||||
self.get_cd().delete_outdated_cache
|
||||
}
|
||||
|
||||
fn get_stopped_search(&self) -> bool {
|
||||
self.get_cd().stopped_search
|
||||
}
|
||||
fn set_stopped_search(&mut self, stopped_search: bool) {
|
||||
self.get_cd_mut().stopped_search = stopped_search;
|
||||
}
|
||||
|
||||
fn set_maximal_file_size(&mut self, maximal_file_size: u64) {
|
||||
self.get_cd_mut().maximal_file_size = match maximal_file_size {
|
||||
0 => 1,
|
||||
t => t,
|
||||
};
|
||||
}
|
||||
fn get_maximal_file_size(&self) -> u64 {
|
||||
self.get_cd().maximal_file_size
|
||||
}
|
||||
|
||||
fn set_minimal_file_size(&mut self, minimal_file_size: u64) {
|
||||
self.get_cd_mut().minimal_file_size = match minimal_file_size {
|
||||
0 => 1,
|
||||
t => t,
|
||||
};
|
||||
}
|
||||
fn get_minimal_file_size(&self) -> u64 {
|
||||
self.get_cd().minimal_file_size
|
||||
}
|
||||
|
||||
fn set_reference_directory(&mut self, reference_directory: Vec<PathBuf>) {
|
||||
let messages = self.get_cd_mut().directories.set_reference_directory(&reference_directory);
|
||||
self.get_cd_mut().text_messages.extend_with_another_messages(messages);
|
||||
}
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
|
||||
self.get_cd_mut().directories.set_exclude_other_filesystems(exclude_other_filesystems);
|
||||
}
|
||||
#[cfg(not(target_family = "unix"))]
|
||||
fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
|
||||
|
||||
fn get_text_messages(&self) -> &Messages {
|
||||
&self.get_cd().text_messages
|
||||
}
|
||||
fn get_text_messages_mut(&mut self) -> &mut Messages {
|
||||
&mut self.get_cd_mut().text_messages
|
||||
}
|
||||
|
||||
fn set_save_also_as_json(&mut self, save_also_as_json: bool) {
|
||||
self.get_cd_mut().save_also_as_json = save_also_as_json;
|
||||
}
|
||||
fn get_save_also_as_json(&self) -> bool {
|
||||
self.get_cd().save_also_as_json
|
||||
}
|
||||
|
||||
fn set_recursive_search(&mut self, recursive_search: bool) {
|
||||
self.get_cd_mut().recursive_search = recursive_search;
|
||||
}
|
||||
fn get_recursive_search(&self) -> bool {
|
||||
self.get_cd().recursive_search
|
||||
}
|
||||
|
||||
fn set_use_reference_folders(&mut self, use_reference_folders: bool) {
|
||||
self.get_cd_mut().use_reference_folders = use_reference_folders;
|
||||
}
|
||||
fn get_use_reference_folders(&self) -> bool {
|
||||
self.get_cd().use_reference_folders
|
||||
}
|
||||
|
||||
fn set_delete_method(&mut self, delete_method: DeleteMethod) {
|
||||
self.get_cd_mut().delete_method = delete_method;
|
||||
}
|
||||
fn get_delete_method(&self) -> DeleteMethod {
|
||||
self.get_cd().delete_method
|
||||
}
|
||||
|
||||
fn set_included_directory(&mut self, included_directory: Vec<PathBuf>) {
|
||||
let messages = self.get_cd_mut().directories.set_included_directory(included_directory);
|
||||
self.get_cd_mut().text_messages.extend_with_another_messages(messages);
|
||||
}
|
||||
|
||||
fn set_excluded_directory(&mut self, excluded_directory: Vec<PathBuf>) {
|
||||
let messages = self.get_cd_mut().directories.set_excluded_directory(excluded_directory);
|
||||
self.get_cd_mut().text_messages.extend_with_another_messages(messages);
|
||||
}
|
||||
fn set_allowed_extensions(&mut self, allowed_extensions: String) {
|
||||
let messages = self.get_cd_mut().extensions.set_allowed_extensions(allowed_extensions);
|
||||
self.get_cd_mut().text_messages.extend_with_another_messages(messages);
|
||||
}
|
||||
fn set_excluded_extensions(&mut self, excluded_extensions: String) {
|
||||
let messages = self.get_cd_mut().extensions.set_excluded_extensions(excluded_extensions);
|
||||
self.get_cd_mut().text_messages.extend_with_another_messages(messages);
|
||||
}
|
||||
|
||||
fn set_excluded_items(&mut self, excluded_items: Vec<String>) {
|
||||
let messages = self.get_cd_mut().excluded_items.set_excluded_items(excluded_items);
|
||||
self.get_cd_mut().text_messages.extend_with_another_messages(messages);
|
||||
}
|
||||
|
||||
fn prepare_items(&mut self) {
|
||||
let recursive_search = self.get_cd().recursive_search;
|
||||
// Optimizes directories and removes recursive calls
|
||||
let messages = self.get_cd_mut().directories.optimize_directories(recursive_search);
|
||||
self.get_cd_mut().text_messages.extend_with_another_messages(messages);
|
||||
}
|
||||
|
||||
fn debug_print_common(&self) {
|
||||
println!("---------------DEBUG PRINT COMMON---------------");
|
||||
println!("Tool type: {:?}", self.get_cd().tool_type);
|
||||
println!("Directories: {:?}", self.get_cd().directories);
|
||||
println!("Extensions: {:?}", self.get_cd().extensions);
|
||||
println!("Excluded items: {:?}", self.get_cd().excluded_items);
|
||||
println!("Recursive search: {:?}", self.get_cd().recursive_search);
|
||||
println!("Maximal file size: {:?}", self.get_cd().maximal_file_size);
|
||||
println!("Minimal file size: {:?}", self.get_cd().minimal_file_size);
|
||||
println!("Stopped search: {:?}", self.get_cd().stopped_search);
|
||||
println!("Use cache: {:?}", self.get_cd().use_cache);
|
||||
println!("Delete outdated cache: {:?}", self.get_cd().delete_outdated_cache);
|
||||
println!("Save also as json: {:?}", self.get_cd().save_also_as_json);
|
||||
println!("Delete method: {:?}", self.get_cd().delete_method);
|
||||
println!("Use reference folders: {:?}", self.get_cd().use_reference_folders);
|
||||
println!("Dry run: {:?}", self.get_cd().dry_run);
|
||||
|
||||
println!("---------------DEBUG PRINT MESSAGES---------------");
|
||||
println!("Errors size - {}", self.get_cd().text_messages.errors.len());
|
||||
println!("Warnings size - {}", self.get_cd().text_messages.warnings.len());
|
||||
println!("Messages size - {}", self.get_cd().text_messages.messages.len());
|
||||
}
|
||||
}
|
@ -1,11 +1,75 @@
|
||||
use std::fs::File;
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::path::Path;
|
||||
|
||||
use fun_time::fun_time;
|
||||
use serde::Serialize;
|
||||
|
||||
pub trait DebugPrint {
|
||||
fn debug_print(&self);
|
||||
}
|
||||
|
||||
pub trait SaveResults {
|
||||
fn save_results_to_file(&mut self, file_name: &str) -> bool;
|
||||
pub trait PrintResults {
|
||||
fn write_results<T: Write>(&self, writer: &mut T) -> std::io::Result<()>;
|
||||
|
||||
#[fun_time(message = "print_results_to_output", level = "debug")]
|
||||
fn print_results_to_output(&self) {
|
||||
let stdout = std::io::stdout();
|
||||
let mut handle = stdout.lock();
|
||||
self.write_results(&mut handle).unwrap();
|
||||
handle.flush().unwrap();
|
||||
}
|
||||
|
||||
#[fun_time(message = "print_results_to_file", level = "debug")]
|
||||
fn print_results_to_file(&self, file_name: &str) -> std::io::Result<()> {
|
||||
let file_name: String = match file_name {
|
||||
"" => "results.txt".to_string(),
|
||||
k => k.to_string(),
|
||||
};
|
||||
|
||||
let file_handler = File::create(file_name)?;
|
||||
let mut writer = BufWriter::new(file_handler);
|
||||
self.write_results(&mut writer)?;
|
||||
writer.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn save_results_to_file_as_json(&self, file_name: &str, pretty_print: bool) -> std::io::Result<()>;
|
||||
|
||||
fn save_results_to_file_as_json_internal<T: Serialize + std::fmt::Debug>(&self, file_name: &str, item_to_serialize: &T, pretty_print: bool) -> std::io::Result<()> {
|
||||
if pretty_print {
|
||||
self.save_results_to_file_as_json_pretty(file_name, item_to_serialize)
|
||||
} else {
|
||||
self.save_results_to_file_as_json_compact(file_name, item_to_serialize)
|
||||
}
|
||||
}
|
||||
|
||||
#[fun_time(message = "save_results_to_file_as_json_pretty", level = "debug")]
|
||||
fn save_results_to_file_as_json_pretty<T: Serialize + std::fmt::Debug>(&self, file_name: &str, item_to_serialize: &T) -> std::io::Result<()> {
|
||||
let file_handler = File::create(file_name)?;
|
||||
let mut writer = BufWriter::new(file_handler);
|
||||
serde_json::to_writer_pretty(&mut writer, item_to_serialize)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[fun_time(message = "save_results_to_file_as_json_compact", level = "debug")]
|
||||
fn save_results_to_file_as_json_compact<T: Serialize + std::fmt::Debug>(&self, file_name: &str, item_to_serialize: &T) -> std::io::Result<()> {
|
||||
let file_handler = File::create(file_name)?;
|
||||
let mut writer = BufWriter::new(file_handler);
|
||||
serde_json::to_writer(&mut writer, item_to_serialize)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn save_all_in_one(&self, file_name: &str) -> std::io::Result<()> {
|
||||
self.save_results_to_file_as_json(&format!("{file_name}_pretty.json"), true)?;
|
||||
self.save_results_to_file_as_json(&format!("{file_name}_compact.json"), false)?;
|
||||
self.print_results_to_file(&format!("{file_name}.txt"))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PrintResults {
|
||||
fn print_results(&self);
|
||||
pub trait ResultEntry {
|
||||
fn get_path(&self) -> &Path;
|
||||
fn get_modified_date(&self) -> u64;
|
||||
fn get_size(&self) -> u64;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,59 +1,63 @@
|
||||
[package]
|
||||
name = "czkawka_gui"
|
||||
version = "4.0.0"
|
||||
version = "7.0.0"
|
||||
authors = ["Rafał Mikrut <mikrutrafal@protonmail.com>"]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
rust-version = "1.75.0"
|
||||
description = "GTK frontend of Czkawka"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/qarmin/czkawka"
|
||||
repository = "https://github.com/qarmin/czkawka"
|
||||
|
||||
[dependencies]
|
||||
czkawka_core = { path = "../czkawka_core", version = "4.0.0"}
|
||||
gdk = "0.14.3"
|
||||
glib = "0.14.8"
|
||||
gdk4 = "0.8"
|
||||
glib = "0.19"
|
||||
gtk4 = { version = "0.8", default-features = false, features = ["v4_6"] }
|
||||
|
||||
humansize = "1.1.1"
|
||||
chrono = "0.4.19"
|
||||
humansize = "2.1"
|
||||
chrono = "0.4.34"
|
||||
|
||||
# Used for sending stop signal across threads
|
||||
crossbeam-channel = "0.5.1"
|
||||
|
||||
# To get informations about progress
|
||||
futures = "0.3.19"
|
||||
crossbeam-channel = "0.5"
|
||||
|
||||
# For saving/loading config files to specific directories
|
||||
directories-next = "2.0.0"
|
||||
directories-next = "2.0"
|
||||
|
||||
# For opening files
|
||||
open = "2.0.2"
|
||||
open = "5.0"
|
||||
|
||||
# To get image preview
|
||||
image = "0.23.14"
|
||||
image = "0.24"
|
||||
|
||||
# To be able to use custom select
|
||||
regex = "1.5.4"
|
||||
regex = "1.10"
|
||||
|
||||
# To get image_hash types
|
||||
img_hash = "3.2.0"
|
||||
# To get image_hasher types
|
||||
image_hasher = "1.2"
|
||||
|
||||
# Move files to trash
|
||||
trash = "1.3.0"
|
||||
trash = "3.3"
|
||||
|
||||
# For moving files(why std::fs doesn't have such features)
|
||||
fs_extra = "1.2.0"
|
||||
# For moving files(why std::fs doesn't have such features?)
|
||||
fs_extra = "1.3"
|
||||
|
||||
# Language
|
||||
i18n-embed = { version = "0.13", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.6.1"
|
||||
rust-embed = "6.3.0"
|
||||
once_cell = "1.9.0"
|
||||
i18n-embed = { version = "0.14", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.8"
|
||||
rust-embed = { version = "8.2", features = ["debug-embed"] }
|
||||
once_cell = "1.19"
|
||||
|
||||
log = "0.4.20"
|
||||
handsome_logger = "0.8"
|
||||
fun_time = { version = "0.3", features = ["log"] }
|
||||
rayon = "1.8"
|
||||
|
||||
czkawka_core = { path = "../czkawka_core", version = "7.0.0", features = [] }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3.9", features = ["combaseapi", "objbase", "shobjidl_core", "windef", "winerror", "wtypesbase", "winuser"] }
|
||||
|
||||
[dependencies.gtk]
|
||||
version = "0.14.3"
|
||||
default-features = false # just in case
|
||||
features = ["v3_24_9"]
|
||||
|
||||
[features]
|
||||
default = []
|
||||
heif = ["czkawka_core/heif"]
|
||||
libraw = ["czkawka_core/libraw"]
|
||||
|
@ -0,0 +1,132 @@
|
||||
# Czkawka GUI
|
||||
|
||||
Czkawka GUI is a graphical user interface for Czkawka Core written with GTK 4.
|
||||
|
||||
![Screenshot from 2023-11-26 12-43-32](https://github.com/qarmin/czkawka/assets/41945903/722ed490-0be1-4dac-bcfc-182a4d0787dc)
|
||||
|
||||
## Requirements
|
||||
|
||||
Requirements depend on your platform.
|
||||
|
||||
Prebuilt binaries are available here - https://github.com/qarmin/czkawka/releases/
|
||||
|
||||
### Linux
|
||||
|
||||
#### Prebuild binaries
|
||||
|
||||
Ubuntu - `sudo apt install libgtk-4 libheif libraw ffmpeg -y`
|
||||
|
||||
#### Snap -
|
||||
|
||||
none - all needed libraries are bundled in
|
||||
snap [except ffmpeg](https://github.com/snapcrafters/ffmpeg/issues/73) - https://snapcraft.io/czkawka
|
||||
|
||||
#### Flatpak
|
||||
|
||||
none - all needed libraries are bundled - https://flathub.org/apps/com.github.qarmin.czkawka
|
||||
|
||||
### Mac
|
||||
|
||||
```
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
brew install gtk4 adwaita-icon-theme ffmpeg librsvg libheif libraw
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
All needed libraries should be bundled in zip (except ffmpeg which you need download and unpack to location
|
||||
with `czkawka_gui.exe` - https://ffmpeg.org/download.html#build-windows)
|
||||
|
||||
You can also install the app via msys2 (webp and heif should work here) - https://www.msys2.org/#installation (czkawka
|
||||
package - https://packages.msys2.org/base/mingw-w64-czkawka)
|
||||
|
||||
```
|
||||
pacman -S mingw-w64-x86_64-czkawka-gui
|
||||
```
|
||||
|
||||
and you can create a shortcut to `C:\msys64\mingw64\bin\czkawka_gui.exe`
|
||||
|
||||
## Compilation
|
||||
|
||||
Compiling the gui is harder than compiling cli or core, because it uses gtk4 which is written in C and also requires a
|
||||
lot build and runtime dependencies.
|
||||
|
||||
### Requirements
|
||||
|
||||
| Program | Minimal version |
|
||||
|:-------:|:---------------:|
|
||||
| Rust | 1.75.0 |
|
||||
| GTK | 4.6 |
|
||||
|
||||
### Linux (Ubuntu, but on other OS should work similar)
|
||||
|
||||
```shell
|
||||
sudo apt install libgtk-4-dev libheif-dev libraw-dev -y
|
||||
cargo run --release --bin czkawka_gui
|
||||
# Or with support for heif and libraw
|
||||
cargo run --release --bin czkawka_gui --features "heif,libraw"
|
||||
```
|
||||
|
||||
### Mac
|
||||
|
||||
```shell
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
brew install rustup gtk4 adwaita-icon-theme ffmpeg librsvg libheif libraw pkg-config
|
||||
rustup-init
|
||||
cargo run --release --bin czkawka_gui
|
||||
# Or with support for heif and libraw
|
||||
cargo run --release --bin czkawka_gui --features "heif,libraw"
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
Currently, there is are no instructions on how to compile the app on Windows natively.</br>
|
||||
You can check for CI for instructions how to cross-compile the app from linux to windows (uses prebuilt docker
|
||||
image) - [CI Instructions](../.github/workflows/windows.yml)</br>
|
||||
There exists a mingw recipe which you can try to convert for your
|
||||
purposes - https://github.com/msys2/MINGW-packages/blob/master/mingw-w64-czkawka/PKGBUILD
|
||||
|
||||
## Limitations
|
||||
|
||||
Not all available features and/or components implemented here, this is the list of limitations:
|
||||
|
||||
- Snap versions does not allow to use the similar videos feature
|
||||
- Windows version does not support heif and webp files with prebuilt binaries
|
||||
- Prebuilt binaries for mac arm do not exist
|
||||
- On Windows, text may appear very small on high resolution displays, a solution is to manually change DPI scaling for
|
||||
this app, see :
|
||||
- recommended
|
||||
fix: [#787#issuecomment-1292253437](https://github.com/qarmin/czkawka/issues/787#issuecomment-1292253437) (modify
|
||||
gtk.css),
|
||||
- or this
|
||||
workaround: [#867#issuecomment-1416761308](https://github.com/qarmin/czkawka/issues/863#issuecomment-1416761308) (
|
||||
modify windows DPI settings for this app (this works too but the text is a bit blurry)).
|
||||
|
||||
## License
|
||||
|
||||
Code is distributed under MIT license.
|
||||
|
||||
Icon was created by [jannuary](https://github.com/jannuary) and licensed CC-BY-4.0.
|
||||
|
||||
Windows dark theme is used from project [WhiteSur](https://github.com/slypy/whitesur-gtk4-theme) with MIT license.
|
||||
|
||||
Some icons were taken from [ReShot](https://www.reshot.com) site and are licensed under Reshot Free License.
|
||||
|
||||
The program is completely free to use.
|
||||
|
||||
"Gratis to uczciwa cena" - "Free is a fair price"
|
||||
|
||||
## Name
|
||||
|
||||
Czkawka is a Polish word which means _hiccup_.
|
||||
|
||||
I chose this name because I wanted to hear people speaking other languages pronounce it, so feel free to spell it the
|
||||
way you want.
|
||||
|
||||
This name is not as bad as it seems, because I was also thinking about using words like _żółć_, _gżegżółka_ or _żołądź_,
|
||||
but I gave up on these ideas because they contained Polish characters, which would cause difficulty in searching for the
|
||||
project.
|
||||
|
||||
At the beginning of the program creation, if the response concerning the name was unanimously negative, I prepared
|
||||
myself
|
||||
for a possible change of the name of the program, and the opinions were extremely mixed.
|
@ -0,0 +1 @@
|
||||
../data/
|
@ -0,0 +1,500 @@
|
||||
# Window titles
|
||||
window_settings_title = 설정
|
||||
window_main_title = Czkawka (Hiccup)
|
||||
window_progress_title = 스캔중
|
||||
window_compare_images = 이미지 비교
|
||||
# General
|
||||
general_ok_button = 확인
|
||||
general_close_button = 닫기
|
||||
# Main window
|
||||
music_title_checkbox = 제목
|
||||
music_artist_checkbox = 아티스트
|
||||
music_year_checkbox = 연도
|
||||
music_bitrate_checkbox = 비트레이트
|
||||
music_genre_checkbox = 장르
|
||||
music_length_checkbox = 길이
|
||||
music_comparison_checkbox = 근사값 비교
|
||||
music_checking_by_tags = Tags
|
||||
music_checking_by_content = Content
|
||||
same_music_seconds_label = Minimal fragment second duration
|
||||
same_music_similarity_label = Maximum difference
|
||||
same_music_tooltip =
|
||||
Searching for similar music files by its content can be configured by setting:
|
||||
|
||||
- The minimum fragment time after which music files can be identified as similar
|
||||
- The maximum difference difference between two tested fragments
|
||||
|
||||
The key to good results is to find sensible combinations of these parameters, for provided.
|
||||
|
||||
Setting the minimum time to 5s and the maximum difference to 1.0, will look for almost identical fragments in the files.
|
||||
A time of 20s and a maximum difference of 6.0, on the other hand, works well for finding remixes/live versions etc.
|
||||
|
||||
By default, each music file is compared to each other and this can take a lot of time when testing many files, so it is usually better to use reference folders and specifying which files are to be compared with each other(with same amount of files, comparing fingerprints will be faster at least 4x than without reference folders).
|
||||
music_comparison_checkbox_tooltip =
|
||||
기계학습을 통해 각 항목의 괄호를 제거합니다. 예를 들어, 다음 두 파일은 같은 파일로 인식될 것입니다.
|
||||
|
||||
Świędziżłób --- Świędziżłób (Remix Lato 2021)
|
||||
duplicate_case_sensitive_name = 대소문자 구분
|
||||
duplicate_case_sensitive_name_tooltip =
|
||||
대소문자 구분이 켜져 있으면, 완전히 같은 이름만이 중복 파일로 검색됩니다. 예시: Żołd <-> Żołd
|
||||
|
||||
대소문자 구분이 꺼져 있으면, 대문자와 소문자 구별을 하지 않고 중복 파일을 검색합니다. 예시: żoŁD <-> Żołd
|
||||
duplicate_mode_size_name_combo_box = Size and Name
|
||||
duplicate_mode_name_combo_box = 파일명
|
||||
duplicate_mode_size_combo_box = 파일 크기
|
||||
duplicate_mode_hash_combo_box = 해시
|
||||
duplicate_hash_type_tooltip =
|
||||
Czkawka는 3가지 유형의 해시 함수를 지원합니다.
|
||||
|
||||
Blake3 - 암호화에 사용되는 해시입니다. 매우 빠르게 작동하므로, 기본값으로 설정되어 있습니다.
|
||||
|
||||
CRC32 - 간단한 해시 함수입니다. Blake3보다는 빠르지만, 매우 드물게 충돌이 발생합니다.
|
||||
|
||||
XXH3 - Black3와 해시 품질 및 성능 면에서 매우 유사하지만, 암호화에 쓰이지는 않습니다. 때문에 Black3와 실질적으로 같습니다.
|
||||
duplicate_check_method_tooltip =
|
||||
현재 Czkawka는 중복 파일을 찾는데 3가지 방법을 지원합니다.
|
||||
|
||||
파일명 - 같은 이름을 가진 파일들을 찾습니다.
|
||||
|
||||
파일 크기 - 같은 크기를 가진 파일들을 찾습니다.
|
||||
|
||||
해시 - 같은 내용을 가진 파일들을 찾습니다. 이 모드에서는 먼저 파일을 해시한 다음, 각 해시값들을 비교하여 중복 파일인지 식별합니다. 때문에 중복 파일을 찾는 데 있어 가장 확실한 방법입니다. Czkawka는 캐시에 매우 의존하므로, 같은 데이터를 두 번째 이후로 스캔하는 경우 첫 번째 스캔보다 더욱 빠르게 스캔이 이루어집니다.
|
||||
image_hash_size_tooltip =
|
||||
Each checked image produces a special hash which can be compared with each other, and a small difference between them means that these images are similar.
|
||||
|
||||
8 hash size is quite good to find images that are only a little similar to original. With a bigger set of images (>1000), this will produce a big amount of false positives, so I recommend to use a bigger hash size in this case.
|
||||
|
||||
16 is the default hash size which is quite a good compromise between finding even a little similar images and having only a small amount of hash collisions.
|
||||
|
||||
32 and 64 hashes find only very similar images, but should have almost no false positives (maybe except some images with alpha channel).
|
||||
image_resize_filter_tooltip =
|
||||
To compute hash of image, the library must first resize it.
|
||||
|
||||
Depend on chosen algorithm, the resulting image used to calculate hash will looks a little different.
|
||||
|
||||
The fastest algorithm to use, but also the one which gives the worst results, is Nearest. It is enabled by default, because with 16x16 hash size lower quality it is not really visible.
|
||||
|
||||
With 8x8 hash size it is recommended to use a different algorithm than Nearest, to have better groups of images.
|
||||
image_hash_alg_tooltip =
|
||||
해시를 계산하는 데 사용되는 알고리즘을 선택할 수 있습니다.
|
||||
|
||||
각각의 알고리즘은 장단점이 있으므로, 경우마다 더 낫거나 더 나쁜 결과를 보여줄 수 있습니다.
|
||||
|
||||
따라서 가장 좋은 알고리즘을 찾으려면 수동으로 테스트해 보는 것이 좋습니다.
|
||||
big_files_mode_combobox_tooltip = 가장 큰 파일 또는 가장 작은 파일을 찾을 수 있습니다.
|
||||
big_files_mode_label = 찾을 파일
|
||||
big_files_mode_smallest_combo_box = 작은 파일
|
||||
big_files_mode_biggest_combo_box = 큰 파일
|
||||
main_notebook_duplicates = 중복 파일
|
||||
main_notebook_empty_directories = 빈 디렉터리
|
||||
main_notebook_big_files = 큰 파일
|
||||
main_notebook_empty_files = 빈 파일
|
||||
main_notebook_temporary = 임시 파일
|
||||
main_notebook_similar_images = 비슷한 이미지
|
||||
main_notebook_similar_videos = 비슷한 영상
|
||||
main_notebook_same_music = 중복 음악
|
||||
main_notebook_symlinks = 잘못된 심볼릭 링크
|
||||
main_notebook_broken_files = 손상된 파일
|
||||
main_notebook_bad_extensions = 잘못된 확장자
|
||||
main_tree_view_column_file_name = 파일명
|
||||
main_tree_view_column_folder_name = 폴더명
|
||||
main_tree_view_column_path = 경로
|
||||
main_tree_view_column_modification = 수정한 날짜
|
||||
main_tree_view_column_size = 파일 크기
|
||||
main_tree_view_column_similarity = 유사도
|
||||
main_tree_view_column_dimensions = 크기
|
||||
main_tree_view_column_title = 제목
|
||||
main_tree_view_column_artist = 아티스트
|
||||
main_tree_view_column_year = 연도
|
||||
main_tree_view_column_bitrate = 비트레이트
|
||||
main_tree_view_column_length = 길이
|
||||
main_tree_view_column_genre = 장르
|
||||
main_tree_view_column_symlink_file_name = 심볼릭 링크 파일명
|
||||
main_tree_view_column_symlink_folder = 심볼릭 링크 폴더
|
||||
main_tree_view_column_destination_path = 심볼릭 링크 대상 경로
|
||||
main_tree_view_column_type_of_error = 손상 유형
|
||||
main_tree_view_column_current_extension = 현재 확장자
|
||||
main_tree_view_column_proper_extensions = 올바른 확장자
|
||||
main_label_check_method = 확인 방법
|
||||
main_label_hash_type = 해시 유형
|
||||
main_label_hash_size = 해시 크기
|
||||
main_label_size_bytes = 파일 크기 (바이트)
|
||||
main_label_min_size = 최소
|
||||
main_label_max_size = 최대
|
||||
main_label_shown_files = 찾을 파일의 개수
|
||||
main_label_resize_algorithm = 크기 변경 알고리즘
|
||||
main_label_similarity = 유사도{ " " }
|
||||
main_check_box_broken_files_audio = 음악 파일
|
||||
main_check_box_broken_files_pdf = PDF
|
||||
main_check_box_broken_files_archive = 압축 파일
|
||||
main_check_box_broken_files_image = 이미지
|
||||
check_button_general_same_size = 같은 파일크기 무시
|
||||
check_button_general_same_size_tooltip = Ignore files with identical size in results - usually these are 1:1 duplicates
|
||||
main_label_size_bytes_tooltip = 스캔할 파일의 크기입니다.
|
||||
# Upper window
|
||||
upper_tree_view_included_folder_column_title = 검색할 폴더
|
||||
upper_tree_view_included_reference_column_title = 기준 폴더
|
||||
upper_recursive_button = 재귀
|
||||
upper_recursive_button_tooltip = 켜져 있으면, 하위 폴더 내부의 파일까지 검색합니다.
|
||||
upper_manual_add_included_button = 수동 추가
|
||||
upper_add_included_button = 추가
|
||||
upper_remove_included_button = 제거
|
||||
upper_manual_add_excluded_button = 수동 추가
|
||||
upper_add_excluded_button = 추가
|
||||
upper_remove_excluded_button = 제거
|
||||
upper_manual_add_included_button_tooltip =
|
||||
직접 검색할 경로를 입력합니다.
|
||||
|
||||
여러 경로를 입력하고자 한다면, ';'로 구분하세요.
|
||||
|
||||
'/home/roman;/home/rozkaz' 를 입력하면, '/home/roman'와 '/home/rozkaz'가 추가됩니다.
|
||||
upper_add_included_button_tooltip = 검색할 디렉터리를 추가합니다.
|
||||
upper_remove_included_button_tooltip = 검색할 디렉터리에서 제거합니다.
|
||||
upper_manual_add_excluded_button_tooltip =
|
||||
직접 제외할 경로를 입력합니다.
|
||||
|
||||
여러 경로를 입력하고자 한다면, ';'로 구분하세요.
|
||||
|
||||
'/home/roman;/home/krokiet' 를 입력하면, '/home/roman'와 '/home/krokiet'가 추가됩니다.
|
||||
upper_add_excluded_button_tooltip = 제외할 디렉터리를 추가합니다.
|
||||
upper_remove_excluded_button_tooltip = 제외할 디렉터리에서 제거합니다.
|
||||
upper_notebook_items_configuration = 항목 설정
|
||||
upper_notebook_excluded_directories = 제외할 디렉터리
|
||||
upper_notebook_included_directories = 검색할 디렉터리
|
||||
upper_allowed_extensions_tooltip =
|
||||
허용할 확장자는 콤마(',')를 통해 구분해야 합니다. (기본값인 경우 모든 확장자를 허용합니다.)
|
||||
|
||||
IMAGE, VIDEO, MUSIC, TEXT를 입력할 경우 해당하는 파일을 모두 지칭할 수 있습니다.
|
||||
|
||||
예시: ".exe, IMAGE, VIDEO, .rar, 7z" - 이와 같이 입력하면, 이미지 파일(예. jpg, png), 영상 파일(예. avi, mp4), exe, rar, 그리고 7z 파일을 검색합니다.
|
||||
upper_excluded_extensions_tooltip =
|
||||
List of disabled files which will be ignored in scan.
|
||||
|
||||
When using both allowed and disabled extensions, this one has higher priority, so file will not be checked.
|
||||
upper_excluded_items_tooltip =
|
||||
제외할 항목은 반드시 '*' 와일드카드 문자를 사용해서 추가해야 하며, 콤마(',')로 구분되어야 합니다.
|
||||
디렉터리를 직접 제외하는 것보다 느립니다. 주의해서 사용하세요.
|
||||
upper_excluded_items = 제외할 항목:
|
||||
upper_allowed_extensions = 허용할 확장자:
|
||||
upper_excluded_extensions = Disabled Extensions:
|
||||
# Popovers
|
||||
popover_select_all = 모두 선택
|
||||
popover_unselect_all = 모두 선택 해제
|
||||
popover_reverse = 선택 반전
|
||||
popover_select_all_except_oldest = 가장 오래된 파일 제외하고 모두 선택
|
||||
popover_select_all_except_newest = 가장 최신인 파일 제외하고 모두 선택
|
||||
popover_select_one_oldest = 가장 오래된 파일 선택
|
||||
popover_select_one_newest = 가장 최신인 파일 선택
|
||||
popover_select_custom = 사용자 지정 선택
|
||||
popover_unselect_custom = 사용자 지정 선택 해제
|
||||
popover_select_all_images_except_biggest = 가장 큰 파일 제외하고 모두 선택
|
||||
popover_select_all_images_except_smallest = 가장 작은 파일 제외하고 모두 선택
|
||||
popover_custom_path_check_button_entry_tooltip =
|
||||
경로를 기준으로 선택합니다.
|
||||
|
||||
사용 예시:
|
||||
'/home/pimpek/rzecz.txt' 파일을 선택하려면 '/home/pim*'와 같이 입력하세요.
|
||||
popover_custom_name_check_button_entry_tooltip =
|
||||
파일 이름을 기준으로 선택합니다.
|
||||
|
||||
사용 예시:
|
||||
'/usr/ping/pong.txt' 파일을 선택하려면 '*ong*'와 같이 입력하세요.
|
||||
popover_custom_regex_check_button_entry_tooltip =
|
||||
정규표현식을 이용해 선택합니다.
|
||||
|
||||
이 모드에서는 경로와 이름 모두가 정규표현식에 의해 검색됩니다.
|
||||
|
||||
사용 예시:
|
||||
'/usr/bin/ziemniak.txt' 파일을 선택하려면 '/ziem[a-z]+'와 같이 입력하세요.
|
||||
|
||||
정규 표현식은 Rust 언어에 내장된 구현체를 사용합니다. 더 알고 싶다면 https://docs.rs/regex를 방문하세요.
|
||||
popover_custom_case_sensitive_check_button_tooltip =
|
||||
대소문자를 구분할 지 여부를 선택합니다.
|
||||
|
||||
만일 꺼져 있으면, '/home/*'은 '/HoMe/roman'과 '/home/roman'를 모두 선택합니다.
|
||||
popover_custom_not_all_check_button_tooltip =
|
||||
한 그룹에 있는 모든 항목이 선택되는 것을 방지합니다.
|
||||
|
||||
이 옵션은 기본적으로 켜져 있습니다. 대부분의 경우, 원본과 중복 파일을 전부 선택하여 삭제하는 것은 원하지 않는 동작일 것입니다. 즉 각 그룹에서 최소한 하나의 항목은 삭제하지 않고 남겨놓게 됩니다.
|
||||
|
||||
경고! 이 설정은 수동으로 그룹의 모든 파일을 이미 선택해 놓았다면 작동하지 않습니다!
|
||||
popover_custom_regex_path_label = 경로
|
||||
popover_custom_regex_name_label = 파일명
|
||||
popover_custom_regex_regex_label = 경로 및 파일 정규표현식
|
||||
popover_custom_case_sensitive_check_button = 대소문자 구별
|
||||
popover_custom_all_in_group_label = 그룹의 모든 항목을 선택하지 않음
|
||||
popover_custom_mode_unselect = 사용자 지정 선택 해제
|
||||
popover_custom_mode_select = 사용자 지정 선택
|
||||
popover_sort_file_name = 파일 이름
|
||||
popover_sort_folder_name = 폴더 이름
|
||||
popover_sort_full_name = 본인 이름
|
||||
popover_sort_size = 파일 크기
|
||||
popover_sort_selection = 선택
|
||||
popover_invalid_regex = 정규표현식이 유효하지 않습니다.
|
||||
popover_valid_regex = 정규표현식이 유효합니다.
|
||||
# Bottom buttons
|
||||
bottom_search_button = 검색
|
||||
bottom_select_button = 선택
|
||||
bottom_delete_button = 삭제
|
||||
bottom_save_button = 저장
|
||||
bottom_symlink_button = 심볼릭 링크
|
||||
bottom_hardlink_button = 하드 링크
|
||||
bottom_move_button = 이동
|
||||
bottom_sort_button = 종류
|
||||
bottom_search_button_tooltip = 검색을 시작합니다.
|
||||
bottom_select_button_tooltip = 항목을 선택합니다. 오직 선택된 것만이 처리됩니다.
|
||||
bottom_delete_button_tooltip = 선택된 파일 또는 폴더를 삭제합니다.
|
||||
bottom_save_button_tooltip = 검색 결과를 파일로 저장합니다.
|
||||
bottom_symlink_button_tooltip =
|
||||
심볼릭 링크를 생성합니다.
|
||||
그룹 내에서 최소한 2개의 파일이 선택되어 있어야 합니다.
|
||||
첫 번째 파일은 그대로 남으며, 두 번째 이후 파일은 첫 번째 파일로 향하는 심볼릭 링크가 됩니다.
|
||||
bottom_hardlink_button_tooltip =
|
||||
하드 링크를 생성합니다.
|
||||
그룹 내에서 최소한 2개의 파일이 선택되어 있어야 합니다.
|
||||
첫 번째 파일은 그대로 남으며, 두 번째 이후 파일은 첫 번째 파일로 향하는 하드 링크가 됩니다.
|
||||
bottom_hardlink_button_not_available_tooltip =
|
||||
하드 링크를 생성합니다.
|
||||
현재 하드 링크를 만들 수 없어 버튼이 비활성화되었습니다.
|
||||
Windows에서 하드 링크는 관리자 권한으로만 만들 수 있습니다. 프로그램이 관리자 권한으로 실행되었는지 확인하세요.
|
||||
만일 프로그램이 이미 관리자 권한으로 실행되었다면, Github에서 비슷한 이슈가 있는지 확인해보세요.
|
||||
bottom_move_button_tooltip =
|
||||
선택된 디렉터리로 파일을 이동합니다.
|
||||
이 동작은 원본이 위치한 경로를 전부 무시하고, 선택한 경로로 파일을 전부 복사합니다.
|
||||
만일 2개 이상의 파일이 같은 이름을 가지고 있다면, 첫 번째 이후의 파일은 복사에 실패하고 오류 메시지를 보여줄 것입니다.
|
||||
bottom_sort_button_tooltip = 파일/폴더를 선택한 방법으로 정렬합니다.
|
||||
bottom_show_errors_tooltip = 하단 텍스트 패널을 보이거나 숨깁니다.
|
||||
bottom_show_upper_notebook_tooltip = 상단 패널을 보이거나 숨깁니다.
|
||||
# Progress Window
|
||||
progress_stop_button = 정지
|
||||
progress_stop_additional_message = 정지 요청됨
|
||||
# About Window
|
||||
about_repository_button_tooltip = 소스 코드가 있는 리포지토리 페이지 링크입니다.
|
||||
about_donation_button_tooltip = 기부 페이지 링크입니다.
|
||||
about_instruction_button_tooltip = 사용방법 페이지 링크입니다.
|
||||
about_translation_button_tooltip = 번역을 위한 Crowdin 페이지 링크입니다. 공식적으로 지원되는 언어는 폴란드어와 영어입니다.
|
||||
about_repository_button = 리포지토리
|
||||
about_donation_button = 기부
|
||||
about_instruction_button = 사용방법
|
||||
about_translation_button = 번역
|
||||
# Header
|
||||
header_setting_button_tooltip = 설정창을 엽니다.
|
||||
header_about_button_tooltip = 이 앱에 대한 정보창을 엽니다.
|
||||
|
||||
# Settings
|
||||
|
||||
|
||||
## General
|
||||
|
||||
settings_number_of_threads = 스레드 수
|
||||
settings_number_of_threads_tooltip = 사용할 스레드 수입니다. 0이면 가능한 최대 스레드를 사용합니다.
|
||||
settings_label_restart = 이 설정을 적용하려면 프로그램을 재시작해야 합니다!
|
||||
settings_ignore_other_filesystems = 다른 파일시스템 무시(Linux에서만)
|
||||
settings_ignore_other_filesystems_tooltip =
|
||||
검색할 디렉터리와 파일시스템이 다른 디렉터리를 무시합니다.
|
||||
|
||||
Linux의 find 명령에서 -xdev 옵션을 준 것과 동일하게 동작합니다.
|
||||
settings_save_at_exit_button_tooltip = 프로그램 종료 시에 설정을 저장합니다.
|
||||
settings_load_at_start_button_tooltip =
|
||||
프로그램을 열 때 저장된 설정을 불러옵니다.
|
||||
|
||||
꺼져 있다면, 기본 설정으로 프로그램을 시작합니다.
|
||||
settings_confirm_deletion_button_tooltip = 삭제 버튼을 누를 때 확인창을 띄웁니다.
|
||||
settings_confirm_link_button_tooltip = 하드 링크/심볼릭 링크 버튼을 누를 때 확인창을 띄웁니다.
|
||||
settings_confirm_group_deletion_button_tooltip = 그룹의 모든 항목을 삭제할 경우 경고창을 보여줍니다.
|
||||
settings_show_text_view_button_tooltip = UI 하단에 텍스트 패널을 보여줍니다.
|
||||
settings_use_cache_button_tooltip = 파일 캐시를 사용합니다.
|
||||
settings_save_also_as_json_button_tooltip = 캐시를 (사람이 읽을 수 있는) JSON 포맷으로 저장합니다. 캐시 내용을 수정할 수 있습니다. 만일 bin 확장자를 가진 바이너리 캐시 파일이 없으면, JSON 캐시가 프로그램 시작 시에 대신 로드됩니다.
|
||||
settings_use_trash_button_tooltip = 파일을 영구 삭제하는 대신 휴지통으로 이동합니다.
|
||||
settings_language_label_tooltip = UI에 표시될 언어를 설정합니다.
|
||||
settings_save_at_exit_button = 프로그램을 닫을 때 설정을 저장
|
||||
settings_load_at_start_button = 프로그램을 열 때 설정을 불러오기
|
||||
settings_confirm_deletion_button = 항목 삭제 시에 확인창 띄우기
|
||||
settings_confirm_link_button = 항목 심볼릭 링크/하드 링크 설정시에 확인창 띄우기
|
||||
settings_confirm_group_deletion_button = 그룹 내의 모든 항목 삭제 시 경고창 띄우기
|
||||
settings_show_text_view_button = 하단 텍스트 패널 표시하기
|
||||
settings_use_cache_button = 캐시 사용
|
||||
settings_save_also_as_json_button = 캐시를 JSON 포맷으로도 저장
|
||||
settings_use_trash_button = 삭제된 파일을 휴지통으로 이동
|
||||
settings_language_label = 언어
|
||||
settings_multiple_delete_outdated_cache_checkbutton = 만료된 파일을 캐시에서 자동으로 삭제
|
||||
settings_multiple_delete_outdated_cache_checkbutton_tooltip =
|
||||
더 이상 존재하지 않는 파일에 대한 정보를 캐시에서 삭제합니다.
|
||||
|
||||
이 옵션이 켜져 있으면, 프로그램은 존재하는 파일만이 캐시에 남도록 할 것입니다(망가진 파일은 무시됩니다).
|
||||
|
||||
이 옵션을 끄는 것은 외장 저장장치에 존재하는 파일을 스캔했을 때, 외장 저장장치에 있는 파일에 대한 캐시를 보존하는 데 도움이 됩니다.
|
||||
|
||||
만일 수백~수천 개의 파일에 해당하는 정보가 캐시에 있다면 이 옵션을 켜는 것을 추천합니다. 이 경우 캐시를 저장하거나 불러오는 시간이 빨라집니다.
|
||||
settings_notebook_general = 일반
|
||||
settings_notebook_duplicates = 중복 파일
|
||||
settings_notebook_images = 유사한 이미지
|
||||
settings_notebook_videos = 유사한 영상
|
||||
|
||||
## Multiple - settings used in multiple tabs
|
||||
|
||||
settings_multiple_image_preview_checkbutton_tooltip = 이미지 파일을 선택하면 우측에 미리보기를 보여줍니다.
|
||||
settings_multiple_image_preview_checkbutton = 이미지 미리보기 표시
|
||||
settings_multiple_clear_cache_button_tooltip =
|
||||
더 이상 존재하지 않는 파일을 캐시에서 제거합니다.
|
||||
캐시를 자동으로 정리하는 옵션이 꺼져 있을 때만 사용하세요.
|
||||
settings_multiple_clear_cache_button = Remove outdated results from cache.
|
||||
|
||||
## Duplicates
|
||||
|
||||
settings_duplicates_hide_hard_link_button_tooltip =
|
||||
하나의 파일에 대한 여러 개의 하드 링크가 존재할 경우, 그 중 하나만을 표시합니다.
|
||||
|
||||
예: 만일 특정한 파일에 대한 7개의 하드 링크가 디스크에 존재하고, 그 중 하나가 다른 inode를 갖는다면, 결과창에는 1개의 파일과 1개의 하드 링크만이 표시됩니다.
|
||||
settings_duplicates_minimal_size_entry_tooltip =
|
||||
캐시에 추가되기 위한 최소 파일 사이즈를 설정합니다.
|
||||
|
||||
이 값이 작을 수록 더 많은 파일이 캐시에 저장됩니다. 이 경우 검색은 더 빨라지지만, 캐시 저장 및 불러오기는 느려집니다.
|
||||
settings_duplicates_prehash_checkbutton_tooltip =
|
||||
사전 해시(파일 일부만으로 계산되는 해시)에 대한 캐싱을 허용하여, 중복이 아닌 파일을 더 빠르게 결과에서 제거합니다.
|
||||
|
||||
이 옵션은 일부 상황에서 검색을 느리게 하기 때문에, 기본적으로 꺼져 있습니다.
|
||||
|
||||
만일 수백~수천 개 이상의 파일처럼 매우 많은 파일을 여러 번 검색하는 경우, 이 기능을 반드시 켜는 것을 추천합니다.
|
||||
settings_duplicates_prehash_minimal_entry_tooltip = 캐싱을 위한 최소 파일크기입니다.
|
||||
settings_duplicates_hide_hard_link_button = 하드 링크 숨기기 (Linux 및 macOS)
|
||||
settings_duplicates_prehash_checkbutton = 사전 해시 캐싱하기
|
||||
settings_duplicates_minimal_size_cache_label = 캐싱하기 위한 최소 파일 크기 (바이트)
|
||||
settings_duplicates_minimal_size_cache_prehash_label = 사전 해시를 캐싱하기 위한 최소 파일 크기 (바이트)
|
||||
|
||||
## Saving/Loading settings
|
||||
|
||||
settings_saving_button_tooltip = 현재 설정을 파일에 저장합니다.
|
||||
settings_loading_button_tooltip = 저장된 설정을 불러와 현재 설정을 덮어씁니다.
|
||||
settings_reset_button_tooltip = 설정을 기본값으로 되돌립니다.
|
||||
settings_saving_button = 설정 저장
|
||||
settings_loading_button = 설정 불러오기
|
||||
settings_reset_button = 설정 초기화
|
||||
|
||||
## Opening cache/config folders
|
||||
|
||||
settings_folder_cache_open_tooltip =
|
||||
캐시 파일이 저장되는 폴더를 엽니다.
|
||||
|
||||
캐시 파일을 편집하는 경우 유효하지 않은 결과가 표시될 수 있습니다. 다만, 많은 양의 파일이 다른 곳으로 이동되었다면 캐시 내의 경로를 수정하는 것이 도움이 됩니다.
|
||||
|
||||
만일 비슷한 디렉터리 구조를 가지는 경우, 캐시 파일을 복사하여 다른 컴퓨터에서도 같은 캐시를 재활용할 수 있습니다.
|
||||
|
||||
만일 캐시에 문제가 발생한다면 이 폴더의 파일들을 지우십시오. 그렇게 하면 프로그램이 다시 캐시 파일을 생성합니다.
|
||||
settings_folder_settings_open_tooltip =
|
||||
Czkawka의 설정 파일이 있는 폴더를 엽니다.
|
||||
|
||||
경고! 설정 파일을 수동으로 편집하는 경우 원치 않는 동작이 일어날 수 있습니다.
|
||||
settings_folder_cache_open = 캐시 폴더 열기
|
||||
settings_folder_settings_open = 설정 폴더 열기
|
||||
# Compute results
|
||||
compute_stopped_by_user = 사용자에 의해 검색이 중단됨.
|
||||
compute_found_duplicates_hash_size = 총 { $number_groups }개의 그룹, { $number_files }개의 중복 파일을 찾음. 총 크기 { $size }
|
||||
compute_found_duplicates_name = 총 { $number_groups }개의 그룹, { $number_files }개의 중복 파일을 찾음.
|
||||
compute_found_empty_folders = 총 { $number_files }개의 빈 폴더를 찾음.
|
||||
compute_found_empty_files = 총 { $number_files }개의 빈 파일을 찾음.
|
||||
compute_found_big_files = 총 { $number_files }개의 큰 파일을 찾음.
|
||||
compute_found_temporary_files = 총 { $number_files }개의 임시 파일을 찾음.
|
||||
compute_found_images = 총 { $number_groups }개의 그룹, { $number_files }개의 유사한 이미지를 찾음.
|
||||
compute_found_videos = 총 { $number_groups }개의 그룹, { $number_files }개의 유사한 영상을 찾음.
|
||||
compute_found_music = 총 { $number_groups }개의 그룹, { $number_files }개의 유사한 음악 파일을 찾음.
|
||||
compute_found_invalid_symlinks = 총 { $number_files } 개의 유효하지 않은 심볼릭 링크를 찾음.
|
||||
compute_found_broken_files = { $number_files }개의 손상된 파일을 찾음.
|
||||
compute_found_bad_extensions = 총 { $number_files }개의 잘못된 확장자를 가진 파일을 찾음.
|
||||
# Progress window
|
||||
progress_scanning_general_file = { $file_number }개의 파일 스캔 중
|
||||
progress_scanning_extension_of_files = { $file_checked }/{ $all_files }개 파일의 확장자 점검 중
|
||||
progress_scanning_broken_files = { $file_checked }/{ $all_files }개 파일 점검 중
|
||||
progress_scanning_video = { $file_checked }/{ $all_files }개 영상 해시 계산 중
|
||||
progress_scanning_image = { $file_checked }/{ $all_files }개 이미지 해시 계산 중
|
||||
progress_comparing_image_hashes = { $file_checked }/{ $all_files }개 이미지 해시 비교 중
|
||||
progress_scanning_music_tags_end = { $file_checked }/{ $all_files }개 음악 파일 태그 검색 중
|
||||
progress_scanning_music_tags = { $file_checked }/{ $all_files }개 음악 파일 태그 읽는 중
|
||||
progress_scanning_music_content_end = Comparing fingerprint of { $file_checked }/{ $all_files } music file
|
||||
progress_scanning_music_content = Calculating fingerprint of { $file_checked }/{ $all_files } music file
|
||||
progress_scanning_empty_folders = { $folder_number }개 폴더 검색 중
|
||||
progress_scanning_size = { $file_number }개 파일의 크기 스캔 중
|
||||
progress_scanning_size_name = Scanning name and size of { $file_number } file
|
||||
progress_scanning_name = { $file_number }개 파일의 이름 스캔 중
|
||||
progress_analyzed_partial_hash = { $file_checked }/{ $all_files }개 파일의 부분 해시 계산 중
|
||||
progress_analyzed_full_hash = { $file_checked }/{ $all_files }개 파일의 전체 해시 계산 중
|
||||
progress_prehash_cache_loading = Loading prehash cache
|
||||
progress_prehash_cache_saving = Saving prehash cache
|
||||
progress_hash_cache_loading = Loading hash cache
|
||||
progress_hash_cache_saving = Saving hash cache
|
||||
progress_cache_loading = Loading cache
|
||||
progress_cache_saving = Saving cache
|
||||
progress_current_stage = 현재 단계:{ " " }
|
||||
progress_all_stages = 전체 단계:{ " " }
|
||||
# Saving loading
|
||||
saving_loading_saving_success = 파일 { $name }에 설정 저장함.
|
||||
saving_loading_saving_failure = 파일 { $name }에 설정 저장 실패.
|
||||
saving_loading_reset_configuration = 현재 설정이 초기화됨.
|
||||
saving_loading_loading_success = 앱 설정 불러오기 성공.
|
||||
saving_loading_invalid_string = 키 "{ $key }"의 값이 올바르지 않습니다. "{ $result }"는 string이 아닙니다.
|
||||
saving_loading_invalid_int = 키 "{ $key }"의 값이 올바르지 않습니다. "{ $result }"는 integer가 아닙니다.
|
||||
saving_loading_invalid_bool = 키 "{ $key }"의 값이 올바르지 않습니다. "{ $result }"은 bool이 아닙니다.
|
||||
saving_loading_decode_problem_bool = 키 "{ $key }"의 값을 bool로 해석할 수 없습니다. 허용된 값은 0, 1, true, false 중 하나이지만 실제 값이 "{ $result }"입니다.
|
||||
saving_loading_saving_same_keys = 키 "{ $key }"가 중복되어 있습니다.
|
||||
saving_loading_failed_to_get_home_directory = 설정 파일을 저장 또는 불러오기 위한 홈 디렉터리를 찾을 수 없습니다.saving_loading_folder_config_instead_file = "{ $path }"에 있는 설정 파일을 열거나 설정 파일을 생성할 수 없습니다. 파일과 같은 이름의 폴더가 존재합니다.
|
||||
saving_loading_folder_config_instead_file = "{ $path }"에 설정 파일을 만들거나 열 수 없습니다. 이미 같은 이름의 폴더가 존재합니다.
|
||||
saving_loading_failed_to_create_configuration_folder = 설정 폴더를 "{ $path }"에 생성할 수 없습니다. 이유: "{ $reason }".
|
||||
saving_loading_failed_to_create_config_file = "{ $path }" 파일에 설정을 저장할 수 없습니다. 이유: "{ $reason }".
|
||||
saving_loading_failed_to_read_config_file = "{ $path }" 파일에서 설정을 불러올 수 없습니다. 파일이 없거나, 파일이 아닙니다.
|
||||
saving_loading_failed_to_read_data_from_file = "{ $path }" 파일을 읽을 수 없습니다. 이유: "{ $reason }".
|
||||
saving_loading_orphan_data = { $line }번 행에 고아 데이터 "{ $data }"가 있습니다.
|
||||
saving_loading_not_valid = 설정 "{ $data }"은 현재 프로그램 버전에 존재하지 않습니다.
|
||||
# Invalid symlinks
|
||||
invalid_symlink_infinite_recursion = 무한 재귀
|
||||
invalid_symlink_non_existent_destination = 목표 파일이 없음
|
||||
# Other
|
||||
selected_all_reference_folders = 모든 디렉터리가 기준 폴더이므로, 검색을 시작할 수 없습니다.
|
||||
searching_for_data = 검색 중. 잠시만 기다려주세요...
|
||||
text_view_messages = 알림
|
||||
text_view_warnings = 경고
|
||||
text_view_errors = 오류
|
||||
about_window_motto = 이 프로그램은 무료이며, 앞으로도 항상 그럴 것이다.
|
||||
# Various dialog
|
||||
dialogs_ask_next_time = 다음에도 묻기
|
||||
delete_file_failed = { $name } 파일 삭제 실패. 이유: { $reason }
|
||||
delete_title_dialog = 삭제 확인
|
||||
delete_question_label = 정말로 파일들을 삭제합니까?
|
||||
delete_all_files_in_group_title = 그룹의 모든 파일 삭제 확인
|
||||
delete_all_files_in_group_label1 = 일부 그룹 내에 있는 모든 파일이 선택되어 있습니다.
|
||||
delete_all_files_in_group_label2 = 정말로 해당 파일을 모두 삭제합니까?
|
||||
delete_folder_failed = { $dir } 폴더가 존재하지 않거나, 권한이 없거나, 폴더가 비어있지 않아 삭제할 수 없습니다.
|
||||
delete_items_label = { $items }개의 파일이 삭제됩니다.
|
||||
delete_items_groups_label = { $groups }개 그룹에서 { $items }개의 파일이 삭제됩니다.
|
||||
hardlink_failed = 하드 링크 생성 실패
|
||||
hard_sym_invalid_selection_title_dialog = 일부 그룹의 선택이 유효하지 않습니다.
|
||||
hard_sym_invalid_selection_label_1 = 일부 그룹에서 1개의 항목만이 선택되었으며, 해당 항목은 무시됩니다.
|
||||
hard_sym_invalid_selection_label_2 = 하드 링크/심볼릭 링크를 생성하려면, 그룹 내에서 최소 2개의 파일이 선택되어야 합니다.
|
||||
hard_sym_invalid_selection_label_3 = 그룹 내의 첫 번째가 원본으로 설정되며, 나머지는 수정될 것입니다.
|
||||
hard_sym_link_title_dialog = 링크 생성 확인
|
||||
hard_sym_link_label = 정말로 해당 파일들을 링크합니까?
|
||||
move_folder_failed = { $name } 폴더 이동 실패. 이유: { $reason }
|
||||
move_file_failed = { $name } 파일 이동 실패. 이유: { $reason }
|
||||
move_files_title_dialog = 중복 파일을 이동할 폴더를 선택하세요.
|
||||
move_files_choose_more_than_1_path = 중복 파일을 복사할 1개의 폴더만 지정해야 하지만, { $path_number }개의 경로를 선택했습니다.
|
||||
move_stats = { $num_files }/{ $all_files }개의 항목을 이동함
|
||||
save_results_to_file = Saved results both to txt and json files into { $name } folder.
|
||||
search_not_choosing_any_music = 경고: 최소한 하나의 검색 방법을 선택해야 합니다.
|
||||
search_not_choosing_any_broken_files = 경고: 최소한 하나 이상의 검색할 파일 분류를 선택해야 합니다.
|
||||
include_folders_dialog_title = 검색할 폴더 추가
|
||||
exclude_folders_dialog_title = 제외할 폴더 추가
|
||||
include_manually_directories_dialog_title = 수동으로 디렉터리 추가
|
||||
cache_properly_cleared = 캐시를 성공적으로 정리했습니다.
|
||||
cache_clear_duplicates_title = 중복 파일 캐시 정리
|
||||
cache_clear_similar_images_title = 유사한 이미지 캐시 정리
|
||||
cache_clear_similar_videos_title = 유사한 영상 캐시 정리
|
||||
cache_clear_message_label_1 = 유효하지 않은 캐시 항목을 제거할까요?
|
||||
cache_clear_message_label_2 = 이 동작은 더 이상 유효하지 않은 파일에 대한 캐시 항목을 제거합니다.
|
||||
cache_clear_message_label_3 = 이를 통해 더 빠른 캐시 저장/불러오기가 가능할 수 있습니다.
|
||||
cache_clear_message_label_4 = 경고! 이 동작은 연결되지 않은 외장 저장장치에 위치한 모든 항목을 제거합니다. 따라서 해당 파일들에 대한 캐시는 다시 생성되어야 합니다.
|
||||
# Show preview
|
||||
preview_image_resize_failure = { $name } 이미지 크기 조정 실패.
|
||||
preview_image_opening_failure = { $name } 이미지 열기 실패. 이유: { $reason }
|
||||
# Compare images (L is short Left, R is short Right - they can't take too much space)
|
||||
compare_groups_number = 그룹 { $current_group }/{ $all_groups } ({ $images_in_group } 이미지)
|
||||
compare_move_left_button = 이전
|
||||
compare_move_right_button = 다음
|
@ -0,0 +1,500 @@
|
||||
# Window titles
|
||||
window_settings_title = Instellingen
|
||||
window_main_title = Czkawka (Hiccup)
|
||||
window_progress_title = Scannen
|
||||
window_compare_images = Vergelijk afbeeldingen
|
||||
# General
|
||||
general_ok_button = OK
|
||||
general_close_button = Afsluiten
|
||||
# Main window
|
||||
music_title_checkbox = Aanspreektitel
|
||||
music_artist_checkbox = Kunstenaar
|
||||
music_year_checkbox = jaar
|
||||
music_bitrate_checkbox = Bitsnelheid
|
||||
music_genre_checkbox = genre
|
||||
music_length_checkbox = longueur
|
||||
music_comparison_checkbox = Geschatte vergelijking
|
||||
music_checking_by_tags = Labels
|
||||
music_checking_by_content = Inhoud
|
||||
same_music_seconds_label = Minimale fragment tweede duur
|
||||
same_music_similarity_label = Maximum verschil
|
||||
same_music_tooltip =
|
||||
Zoeken naar vergelijkbare muziekbestanden door de inhoud ervan kan worden geconfigureerd door instelling:
|
||||
|
||||
- De minimale fragmenttijd waarna muziekbestanden kunnen worden geïdentificeerd als vergelijkbaar
|
||||
- Het maximale verschil tussen twee geteste fragmenten
|
||||
|
||||
De sleutel tot goede resultaten is om verstandige combinaties van deze parameters te vinden, voor opgegeven.
|
||||
|
||||
Instelling van de minimale tijd op 5 en het maximale verschil op 1.0, zal zoeken naar bijna identieke fragmenten in de bestanden.
|
||||
Een tijd van 20 en een maximaal verschil van 6,0 werkt daarentegen goed voor het vinden van remixes/live versies, enz.
|
||||
|
||||
Standaard wordt elk muziekbestand met elkaar vergeleken en dit kan veel tijd in beslag nemen bij het testen van veel bestanden, dus is het meestal beter om referentie-mappen te gebruiken en aan te geven welke bestanden met elkaar moeten worden vergeleken (met dezelfde hoeveelheid bestanden, Het vergelijken van vingerafdrukken is sneller dan zonder referentiemateriaal).
|
||||
music_comparison_checkbox_tooltip =
|
||||
Het zoekt naar vergelijkbare muziekbestanden met behulp van AI, die machine-leren gebruikt om haakjes uit een zin te verwijderen. Bijvoorbeeld met deze optie ingeschakeld de bestanden in kwestie zullen als duplicaten worden beschouwd:
|
||||
|
||||
SØ wieľdzizive b --- S000000wie.pldzizľb (Remix Lato 2021)
|
||||
duplicate_case_sensitive_name = Kist gevoelig
|
||||
duplicate_case_sensitive_name_tooltip =
|
||||
Wanneer ingeschakeld, groep alleen records wanneer ze precies dezelfde naam hebben, b.v. Zit ołd <-> ZØ ołd
|
||||
|
||||
Uitschakelen van een dergelijke optie zal namen groeperen zonder te controleren of elke letter hetzelfde formaat heeft, bijv. zghaoŁD <-> Zit ołd
|
||||
duplicate_mode_size_name_combo_box = Grootte en naam
|
||||
duplicate_mode_name_combo_box = naam
|
||||
duplicate_mode_size_combo_box = Grootte
|
||||
duplicate_mode_hash_combo_box = Toegangssleutel
|
||||
duplicate_hash_type_tooltip =
|
||||
Czkawka biedt 3 soorten hashes:
|
||||
|
||||
Blake3 - cryptografische hash-functie. Dit is de standaard omdat het erg snel is.
|
||||
|
||||
CRC32 - eenvoudige hashfunctie. Dit zou sneller moeten zijn dan Blake3, maar kan zeer zelden een botsing veroorzaken.
|
||||
|
||||
XXH3 - erg vergelijkbaar in prestaties en hashkwaliteit naar Blake3 (maar niet-cryptografie). Dergelijke modi kunnen dus eenvoudig worden verwisseld.
|
||||
duplicate_check_method_tooltip =
|
||||
Op dit moment biedt Czkawka drie soorten methode aan om duplicaten te vinden door:
|
||||
|
||||
Naam - Gevonden bestanden met dezelfde naam.
|
||||
|
||||
Grootte - Gevonden bestanden die dezelfde grootte hebben.
|
||||
|
||||
Hash - Gevonden bestanden die dezelfde inhoud hebben. Deze modus hashet het bestand en vergelijkt deze hash later om duplicaten te vinden. Deze modus is de veiligste manier om duplicaten te vinden. App gebruikt zwaar cache, dus de tweede en verdere scans van dezelfde gegevens zou veel sneller moeten zijn dan de eerste.
|
||||
image_hash_size_tooltip =
|
||||
Elke gecontroleerde afbeelding produceert een speciale hash die met elkaar kan worden vergeleken en een klein verschil tussen hen betekent dat deze afbeeldingen vergelijkbaar zijn.
|
||||
|
||||
8 hash size is vrij goed om afbeeldingen te vinden die maar een beetje lijken op origineel. Met een grotere set afbeeldingen (>1000) levert dit een grote hoeveelheid valse positieven op. Dus ik raad in dit geval aan een grotere hashgrootte te gebruiken.
|
||||
|
||||
16 is de standaard hash-afmeting, wat een heel goed compromis is tussen het vinden van zelfs een beetje gelijksoortige afbeeldingen en het hebben van slechts een klein aantal hash-botsingen.
|
||||
|
||||
32 en 64 hashes vinden slechts zeer gelijksoortige afbeeldingen, maar zouden bijna geen valse positieve motieven moeten hebben (behalve sommige afbeeldingen met alpha kanaal).
|
||||
image_resize_filter_tooltip =
|
||||
Om hash van de afbeelding te berekenen, moet de bibliotheek deze eerst grootschalen.
|
||||
|
||||
Afhankelijk van het gekozen algoritme, zal de uiteindelijke afbeelding die gebruikt wordt om hash te berekenen er een beetje anders uitzien.
|
||||
|
||||
Het snelste algoritme te gebruiken, maar ook het algoritme dat de slechtste resultaten geeft, is het dichtstbijst. Het is standaard ingeschakeld, want met 16x16 hash grootte is het niet echt zichtbaar.
|
||||
|
||||
met 8x8 hash grootte is het raadzaam om een ander algoritme te gebruiken dan Nearest, om betere groepen afbeeldingen te hebben.
|
||||
image_hash_alg_tooltip =
|
||||
Gebruikers kunnen kiezen uit een van de vele algoritmes om de hash te berekenen.
|
||||
|
||||
Elk van deze punten heeft sterke en zwakke punten en zal soms betere en soms slechtere resultaten opleveren voor verschillende afbeeldingen.
|
||||
|
||||
Dus om het beste voor u te bepalen, is handmatige test vereist.
|
||||
big_files_mode_combobox_tooltip = Maakt het mogelijk om naar kleinste/grootste bestanden te zoeken
|
||||
big_files_mode_label = Gecontroleerde bestanden
|
||||
big_files_mode_smallest_combo_box = De Kleinste
|
||||
big_files_mode_biggest_combo_box = De Grootste
|
||||
main_notebook_duplicates = Dupliceer Bestanden
|
||||
main_notebook_empty_directories = Lege mappen
|
||||
main_notebook_big_files = Grote bestanden
|
||||
main_notebook_empty_files = Lege bestanden
|
||||
main_notebook_temporary = Tijdelijke bestanden
|
||||
main_notebook_similar_images = Vergelijkbare afbeeldingen
|
||||
main_notebook_similar_videos = Soortgelijke video's
|
||||
main_notebook_same_music = Muziek duplicaten
|
||||
main_notebook_symlinks = Ongeldige Symlinks
|
||||
main_notebook_broken_files = Kapotte Bestanden
|
||||
main_notebook_bad_extensions = Slechte extensies
|
||||
main_tree_view_column_file_name = File Name
|
||||
main_tree_view_column_folder_name = Map Naam
|
||||
main_tree_view_column_path = Pad
|
||||
main_tree_view_column_modification = Wijziging datum
|
||||
main_tree_view_column_size = Grootte
|
||||
main_tree_view_column_similarity = Vergelijkbaarheid
|
||||
main_tree_view_column_dimensions = Mål
|
||||
main_tree_view_column_title = Aanspreektitel
|
||||
main_tree_view_column_artist = Kunstenaar
|
||||
main_tree_view_column_year = jaar
|
||||
main_tree_view_column_bitrate = Bitsnelheid
|
||||
main_tree_view_column_length = longueur
|
||||
main_tree_view_column_genre = genre
|
||||
main_tree_view_column_symlink_file_name = Symlink bestandsnaam
|
||||
main_tree_view_column_symlink_folder = Symlink map
|
||||
main_tree_view_column_destination_path = Bestemming pad
|
||||
main_tree_view_column_type_of_error = Type fout
|
||||
main_tree_view_column_current_extension = Huidige extensie
|
||||
main_tree_view_column_proper_extensions = Proper Extensie
|
||||
main_label_check_method = Controleer methode
|
||||
main_label_hash_type = Soort hash
|
||||
main_label_hash_size = Hash grootte
|
||||
main_label_size_bytes = Grootte (bytes)
|
||||
main_label_min_size = Min.
|
||||
main_label_max_size = Max.
|
||||
main_label_shown_files = Aantal getoonde bestanden
|
||||
main_label_resize_algorithm = Algoritme aanpassen
|
||||
main_label_similarity = Similarity{ " " }
|
||||
main_check_box_broken_files_audio = Geluid
|
||||
main_check_box_broken_files_pdf = PDF
|
||||
main_check_box_broken_files_archive = Archief
|
||||
main_check_box_broken_files_image = Afbeelding
|
||||
check_button_general_same_size = Negeer dezelfde grootte
|
||||
check_button_general_same_size_tooltip = Bestanden met identieke grootte in resultaten negeren - meestal zijn deze 1:1 duplicaten
|
||||
main_label_size_bytes_tooltip = Grootte van bestanden die zullen worden gebruikt in scan
|
||||
# Upper window
|
||||
upper_tree_view_included_folder_column_title = Mappen om te zoeken
|
||||
upper_tree_view_included_reference_column_title = Referentie Mappen
|
||||
upper_recursive_button = Recursief
|
||||
upper_recursive_button_tooltip = Indien geselecteerd, zoek ook naar bestanden die niet direct onder de gekozen mappen worden geplaatst.
|
||||
upper_manual_add_included_button = Handmatig toevoegen
|
||||
upper_add_included_button = Toevoegen
|
||||
upper_remove_included_button = Verwijderen
|
||||
upper_manual_add_excluded_button = Handmatig toevoegen
|
||||
upper_add_excluded_button = Toevoegen
|
||||
upper_remove_excluded_button = Verwijderen
|
||||
upper_manual_add_included_button_tooltip =
|
||||
Voeg mapnaam toe om met de hand te zoeken.
|
||||
|
||||
Om meerdere paden tegelijk toe te voegen, scheiden ze met ;
|
||||
|
||||
/home/roman;/home/rozkaz zal twee mappen / home/roman en /home/rozkaz toevoegen
|
||||
upper_add_included_button_tooltip = Voeg nieuwe map toe om te zoeken.
|
||||
upper_remove_included_button_tooltip = Map verwijderen uit zoekopdracht.
|
||||
upper_manual_add_excluded_button_tooltip =
|
||||
Voeg uitgesloten mapnaam met de hand toe.
|
||||
|
||||
Om meerdere paden tegelijk toe te voegen, scheid ze met
|
||||
|
||||
/home/roman;/home/krokiet zal twee mappen / home/roman en /home/keokiet toevoegen
|
||||
upper_add_excluded_button_tooltip = Voeg map toe om uitgesloten te worden in zoekopdracht.
|
||||
upper_remove_excluded_button_tooltip = Verwijder map van uitgesloten.
|
||||
upper_notebook_items_configuration = Artikelen configuratie
|
||||
upper_notebook_excluded_directories = Uitgesloten Mappen
|
||||
upper_notebook_included_directories = Inbegrepen Mappen
|
||||
upper_allowed_extensions_tooltip =
|
||||
Toegestane extensies moeten door komma's gescheiden worden (standaard zijn alle beschikbaar).
|
||||
|
||||
De volgende macro's die meerdere extensies in één keer toevoegen, zijn ook beschikbaar: IMAGE, VIDEO, MUSIC, TEXT.
|
||||
|
||||
Gebruiksgebruik voorbeeld ".exe, IMAGE, VIDEO, .rar, 7z" - dit betekent dat afbeeldingen (e. . jpg, png), video's (bijv. avi, mp4), exe, rr en 7z bestanden worden gescand.
|
||||
upper_excluded_extensions_tooltip =
|
||||
Lijst van uitgeschakelde bestanden die genegeerd zullen worden in scan.
|
||||
|
||||
Wanneer gebruik wordt gemaakt van toegestane en uitgeschakelde extensies, heeft deze hogere prioriteit, dus het bestand zal niet worden gecontroleerd.
|
||||
upper_excluded_items_tooltip =
|
||||
Uitgesloten items moeten * jokertekens bevatten en moeten gescheiden worden door komma's.
|
||||
Dit is langzamer dan uitgesloten mappen, dus gebruik het zorgvuldig.
|
||||
upper_excluded_items = Uitgesloten artikelen:
|
||||
upper_allowed_extensions = Toegestane extensies:
|
||||
upper_excluded_extensions = Uitgeschakelde extensies:
|
||||
# Popovers
|
||||
popover_select_all = Alles selecteren
|
||||
popover_unselect_all = Selectie ongedaan maken
|
||||
popover_reverse = Omgekeerde selectie
|
||||
popover_select_all_except_oldest = Alles selecteren behalve oudste
|
||||
popover_select_all_except_newest = Selecteer alles behalve nieuwste
|
||||
popover_select_one_oldest = Selecteer één oudste
|
||||
popover_select_one_newest = Selecteer een nieuwste
|
||||
popover_select_custom = Selecteer aangepaste
|
||||
popover_unselect_custom = Aangepaste deselecteer ongedaan maken
|
||||
popover_select_all_images_except_biggest = Alles selecteren behalve de grootste
|
||||
popover_select_all_images_except_smallest = Selecteer alles behalve de kleinste
|
||||
popover_custom_path_check_button_entry_tooltip =
|
||||
Records per pad selecteren.
|
||||
|
||||
Voorbeeld gebruik:
|
||||
/home/pimpek/rzecz.txt kan worden gevonden met /home/pim*
|
||||
popover_custom_name_check_button_entry_tooltip =
|
||||
Records selecteren op bestandnamen.
|
||||
|
||||
Voorbeeld gebruik:
|
||||
/usr/ping/pong.txt kan worden gevonden met *ong*
|
||||
popover_custom_regex_check_button_entry_tooltip =
|
||||
Select records by specified Regex.
|
||||
|
||||
In this mode is searched text Path with Name.
|
||||
|
||||
Voorbeeld use usage:
|
||||
/usr/bin/ziemniak. xt kan gevonden worden met /ziem[a-z]+
|
||||
|
||||
Dit gebruikt de standaard Rust regex implementatie. Je kunt hier meer over lezen: https://docs.rs/regex.
|
||||
popover_custom_case_sensitive_check_button_tooltip =
|
||||
Maakt hoofdlettergevoelige detectie mogelijk.
|
||||
|
||||
Wanneer uitgeschakeld /home/* vindt zowel /HoMe/roman en /home/roman.
|
||||
popover_custom_not_all_check_button_tooltip =
|
||||
Voorkomt dat alle records in de groep worden geselecteerd.
|
||||
|
||||
Dit is standaard ingeschakeld, omdat in de meeste situaties u wilt niet zowel origineel als duplicaten verwijderen, maar ten minste één bestand achterlaten.
|
||||
|
||||
WAARSCHUWING: Deze instelling werkt niet als je al handmatig alle resultaten hebt geselecteerd in een groep.
|
||||
popover_custom_regex_path_label = Pad
|
||||
popover_custom_regex_name_label = naam
|
||||
popover_custom_regex_regex_label = Regex pad + naam
|
||||
popover_custom_case_sensitive_check_button = Hoofdletter gevoelig
|
||||
popover_custom_all_in_group_label = Niet alle records in groep selecteren
|
||||
popover_custom_mode_unselect = Aangepaste deselecteren
|
||||
popover_custom_mode_select = Selecteer aangepast
|
||||
popover_sort_file_name = Bestandsnaam is vereist
|
||||
popover_sort_folder_name = Folder Name
|
||||
popover_sort_full_name = Volledige naam
|
||||
popover_sort_size = Grootte
|
||||
popover_sort_selection = Selectie
|
||||
popover_invalid_regex = Regex is ongeldig
|
||||
popover_valid_regex = Regex is geldig
|
||||
# Bottom buttons
|
||||
bottom_search_button = Zoeken
|
||||
bottom_select_button = Selecteren
|
||||
bottom_delete_button = Verwijderen
|
||||
bottom_save_button = Opslaan
|
||||
bottom_symlink_button = Symlink
|
||||
bottom_hardlink_button = Hardlink
|
||||
bottom_move_button = Verplaatsen
|
||||
bottom_sort_button = Sorteren
|
||||
bottom_search_button_tooltip = Zoeken starten
|
||||
bottom_select_button_tooltip = Selecteer records. Alleen geselecteerde bestanden/mappen kunnen later worden verwerkt.
|
||||
bottom_delete_button_tooltip = Verwijder geselecteerde bestanden/mappen.
|
||||
bottom_save_button_tooltip = Gegevens opslaan van zoekopdracht naar bestand
|
||||
bottom_symlink_button_tooltip =
|
||||
Maak symbolische links.
|
||||
Werkt alleen wanneer ten minste twee resultaten in een groep zijn geselecteerd.
|
||||
De eerste is ongewijzigd en de tweede is symgekoppeld naar eerst.
|
||||
bottom_hardlink_button_tooltip =
|
||||
Maak hardlinks.
|
||||
Werkt alleen wanneer ten minste twee resultaten in een groep worden geselecteerd.
|
||||
De eerste is ongewijzigd en de tweede keer en later zijn vastgekoppeld aan eerst.
|
||||
bottom_hardlink_button_not_available_tooltip =
|
||||
Maak hardlinks.
|
||||
Knop is uitgeschakeld, omdat hardlinks niet kunnen worden gemaakt.
|
||||
Hardlinks werkt alleen met beheerdersrechten op Windows, dus zorg ervoor dat je de app als administrator gebruikt.
|
||||
Als de app al werkt met dergelijke privileges controle op gelijksoortige issues op Github.
|
||||
bottom_move_button_tooltip =
|
||||
Verplaatst bestanden naar de gekozen map.
|
||||
Het kopieert alle bestanden naar de map zonder de mapstructuur te bewaren.
|
||||
Wanneer twee bestanden met dezelfde naam naar de map worden verplaatst, zal de tweede mislukt en de fout worden weergegeven.
|
||||
bottom_sort_button_tooltip = Sorteert bestanden/mappen op de geselecteerde methode.
|
||||
bottom_show_errors_tooltip = Onderste tekstvenster tonen/verbergen
|
||||
bottom_show_upper_notebook_tooltip = Toon/Verberg bovenste notitieboekpaneel.
|
||||
# Progress Window
|
||||
progress_stop_button = Stoppen
|
||||
progress_stop_additional_message = Stop aangevraagd
|
||||
# About Window
|
||||
about_repository_button_tooltip = Link naar de repository pagina met broncode.
|
||||
about_donation_button_tooltip = Link naar donatie pagina.
|
||||
about_instruction_button_tooltip = Link naar instructiepagina.
|
||||
about_translation_button_tooltip = Link naar de Crowdin pagina met appvertalingen. Officieel worden Pools en Engels ondersteund.
|
||||
about_repository_button = Bewaarplaats
|
||||
about_donation_button = Donatie
|
||||
about_instruction_button = Instructie
|
||||
about_translation_button = Vertaling
|
||||
# Header
|
||||
header_setting_button_tooltip = Opent instellingen dialoogvenster.
|
||||
header_about_button_tooltip = Opent dialoogvenster met info over app.
|
||||
|
||||
# Settings
|
||||
|
||||
|
||||
## General
|
||||
|
||||
settings_number_of_threads = Aantal gebruikte threads
|
||||
settings_number_of_threads_tooltip = Aantal gebruikte threads, 0 betekent dat alle beschikbare threads zullen worden gebruikt.
|
||||
settings_label_restart = U moet de app herstarten om de instellingen toe te passen!
|
||||
settings_ignore_other_filesystems = Negeer andere bestandssystemen (alleen Linux)
|
||||
settings_ignore_other_filesystems_tooltip =
|
||||
negeert bestanden die niet in hetzelfde bestandssysteem zitten als gezochte mappen.
|
||||
|
||||
Werkt dezelfde als -xdev optie in het zoekcommando voor Linux
|
||||
settings_save_at_exit_button_tooltip = Configuratie opslaan in bestand bij het sluiten van de app.
|
||||
settings_load_at_start_button_tooltip =
|
||||
Laad de configuratie van het bestand bij het openen van de app.
|
||||
|
||||
Indien niet ingeschakeld, worden standaard instellingen gebruikt.
|
||||
settings_confirm_deletion_button_tooltip = Bevestigingsvenster tonen bij het klikken op de knop verwijderen.
|
||||
settings_confirm_link_button_tooltip = Toon bevestigingsvenster bij het klikken op de hard/symlink knop.
|
||||
settings_confirm_group_deletion_button_tooltip = Waarschuwingsvenster weergeven wanneer geprobeerd wordt om alle records uit de groep te verwijderen.
|
||||
settings_show_text_view_button_tooltip = Tekstpaneel aan de onderkant van de gebruikersinterface weergeven.
|
||||
settings_use_cache_button_tooltip = Gebruik bestandscache.
|
||||
settings_save_also_as_json_button_tooltip = Cache opslaan in (menselijk leesbaar) JSON formaat. Het is mogelijk om de inhoud te wijzigen. Cache van dit bestand wordt automatisch gelezen door de app als er een binaire cache (met bin extensie) ontbreekt.
|
||||
settings_use_trash_button_tooltip = Verplaatst bestanden naar prullenbak in plaats daarvan ze permanent te verwijderen.
|
||||
settings_language_label_tooltip = Taal voor de gebruikersinterface.
|
||||
settings_save_at_exit_button = Configuratie opslaan bij het sluiten van app
|
||||
settings_load_at_start_button = Laad configuratie bij het openen van app
|
||||
settings_confirm_deletion_button = Toon bevestigingsdialoog bij het verwijderen van bestanden
|
||||
settings_confirm_link_button = Melding bevestigen bij hard/symlinks van bestanden
|
||||
settings_confirm_group_deletion_button = Toon het bevestigingsvenster bij het verwijderen van alle bestanden in de groep
|
||||
settings_show_text_view_button = Toon onderaan tekstpaneel
|
||||
settings_use_cache_button = Gebruik cache
|
||||
settings_save_also_as_json_button = Sla ook de cache op als JSON-bestand
|
||||
settings_use_trash_button = Verwijderde bestanden verplaatsen naar prullenbak
|
||||
settings_language_label = Taal
|
||||
settings_multiple_delete_outdated_cache_checkbutton = Verouderde cache vermeldingen automatisch verwijderen
|
||||
settings_multiple_delete_outdated_cache_checkbutton_tooltip =
|
||||
Verwijder verouderde cacheresultaten die verwijzen naar niet-bestaande bestanden.
|
||||
|
||||
Indien ingeschakeld, zorgt de app ervoor dat bij het laden van records, dat alle records naar geldige bestanden verwijzen (gebroken bestanden worden genegeerd).
|
||||
|
||||
Dit uitschakelen zal helpen bij het scannen van bestanden op externe schijven, dus cache-items over deze zullen niet worden gewist in de volgende scan.
|
||||
|
||||
In het geval van honderdduizenden records in de cache, het wordt aangeraden om dit in te schakelen, dit zal de cache laden/opslaan aan het starten/einde van de scan versnellen.
|
||||
settings_notebook_general = Algemeen
|
||||
settings_notebook_duplicates = Duplicaten
|
||||
settings_notebook_images = Vergelijkbare afbeeldingen
|
||||
settings_notebook_videos = Gelijkaardige Video
|
||||
|
||||
## Multiple - settings used in multiple tabs
|
||||
|
||||
settings_multiple_image_preview_checkbutton_tooltip = Toont voorbeeld aan rechterkant (bij het selecteren van een afbeeldingsbestand).
|
||||
settings_multiple_image_preview_checkbutton = Toon voorvertoning afbeelding
|
||||
settings_multiple_clear_cache_button_tooltip =
|
||||
Handmatig de cache van verouderde items wissen.
|
||||
Dit mag alleen worden gebruikt als automatisch wissen is uitgeschakeld.
|
||||
settings_multiple_clear_cache_button = Verwijder verouderde resultaten uit de cache.
|
||||
|
||||
## Duplicates
|
||||
|
||||
settings_duplicates_hide_hard_link_button_tooltip =
|
||||
Verbergt alle bestanden behalve één, als alle naar dezelfde gegevens verwijst (zijn hardlinked).
|
||||
|
||||
Voorbeeld: In het geval waar er (op schijf) zeven bestanden zijn die zijn gekoppeld aan specifieke data en één ander bestand met dezelfde gegevens, maar een andere inode, dan in dubbele zoeker, slechts één uniek bestand en één bestand van de hardgelinkte bestanden zullen worden weergegeven.
|
||||
settings_duplicates_minimal_size_entry_tooltip =
|
||||
Stel de minimale bestandsgrootte in die gecached zal worden.
|
||||
|
||||
kiezen van een kleinere waarde zal meer records genereren. Dit zal het zoeken versnellen, maar de cache aan het laden/opslaan.
|
||||
settings_duplicates_prehash_checkbutton_tooltip =
|
||||
Hiermee kan het cachen van prehash (een hash berekend van een klein deel van het bestand) eerder verwijderen van niet-gedupliceerde resultaten.
|
||||
|
||||
Het is standaard uitgeschakeld omdat het in sommige situaties vertraging kan veroorzaken.
|
||||
|
||||
Het is sterk aanbevolen om het te gebruiken bij het scannen van honderdduizenden of miljoen bestanden, omdat het zoeken meerdere keren kan versnellen.
|
||||
settings_duplicates_prehash_minimal_entry_tooltip = Minimale grootte van gecachete invoer.
|
||||
settings_duplicates_hide_hard_link_button = Verberg harde links (alleen Linux en macOS)
|
||||
settings_duplicates_prehash_checkbutton = Gebruik prehash cache
|
||||
settings_duplicates_minimal_size_cache_label = Minimale bestandsgrootte (in bytes) opgeslagen in de cache
|
||||
settings_duplicates_minimal_size_cache_prehash_label = Minimale grootte van bestanden (in bytes) opgeslagen naar prehash cache
|
||||
|
||||
## Saving/Loading settings
|
||||
|
||||
settings_saving_button_tooltip = De huidige instellingen configuratie opslaan in bestand.
|
||||
settings_loading_button_tooltip = Laad de instellingen uit het bestand en vervang de huidige configuratie.
|
||||
settings_reset_button_tooltip = De huidige configuratie terugzetten naar de standaard.
|
||||
settings_saving_button = Configuratie opslaan
|
||||
settings_loading_button = Laad configuratie
|
||||
settings_reset_button = Reset configuratie
|
||||
|
||||
## Opening cache/config folders
|
||||
|
||||
settings_folder_cache_open_tooltip =
|
||||
Opent de map waar de cache txt bestanden zijn opgeslagen.
|
||||
|
||||
Het wijzigen van de cachebestanden kan ervoor zorgen dat ongeldige resultaten worden getoond. Het wijzigen van een pad kan echter tijd besparen bij het verplaatsen van een grote hoeveelheid bestanden naar een andere locatie.
|
||||
|
||||
U kunt deze bestanden tussen computers kopiëren om tijd te besparen bij het scannen van bestanden (van natuurlijk als ze een vergelijkbare directory structuur hebben).
|
||||
|
||||
In geval van problemen met de cache kunnen deze bestanden worden verwijderd. De app zal ze automatisch opnieuw genereren.
|
||||
settings_folder_settings_open_tooltip =
|
||||
Opent de map waar de Czkawka config is opgeslagen.
|
||||
|
||||
WAARSCHUWING: Handmatig wijzigen van de configuratie kan uw workflow verbreken.
|
||||
settings_folder_cache_open = Open cachemap
|
||||
settings_folder_settings_open = Instellingenmap openen
|
||||
# Compute results
|
||||
compute_stopped_by_user = Zoeken is gestopt door gebruiker
|
||||
compute_found_duplicates_hash_size = Gevonden { $number_files } duplicaten in { $number_groups } groepen die { $size } namen
|
||||
compute_found_duplicates_name = Gevonden { $number_files } duplicaten in { $number_groups } groepen
|
||||
compute_found_empty_folders = Gevonden { $number_files } lege mappen
|
||||
compute_found_empty_files = Gevonden { $number_files } lege bestanden
|
||||
compute_found_big_files = Gevonden { $number_files } grote bestanden
|
||||
compute_found_temporary_files = Gevonden { $number_files } tijdelijke bestanden
|
||||
compute_found_images = Gevonden { $number_files } soortgelijke afbeeldingen in { $number_groups } groepen
|
||||
compute_found_videos = Gevonden { $number_files } vergelijkbare video's in { $number_groups } groepen
|
||||
compute_found_music = Gevonden { $number_files } vergelijkbare muziekbestanden in { $number_groups } groepen
|
||||
compute_found_invalid_symlinks = Gevonden { $number_files } ongeldige symlinks
|
||||
compute_found_broken_files = Gevonden { $number_files } gebroken bestanden
|
||||
compute_found_bad_extensions = { $number_files } bestanden met ongeldige extensies gevonden
|
||||
# Progress window
|
||||
progress_scanning_general_file = Scannen van { $file_number } bestand
|
||||
progress_scanning_extension_of_files = Extensie van { $file_checked }/{ $all_files } bestand controleren
|
||||
progress_scanning_broken_files = Controleren { $file_checked }/{ $all_files } bestand
|
||||
progress_scanning_video = Hashing van { $file_checked }/{ $all_files } video
|
||||
progress_scanning_image = Hashing van { $file_checked }/{ $all_files } afbeelding
|
||||
progress_comparing_image_hashes = Vergelijk { $file_checked }/{ $all_files } afbeelding hash
|
||||
progress_scanning_music_tags_end = Tags vergelijken van { $file_checked }/{ $all_files } muziekbestand
|
||||
progress_scanning_music_tags = Leestags van { $file_checked }/{ $all_files } muziekbestand
|
||||
progress_scanning_music_content_end = Vingerafdruk van { $file_checked }/{ $all_files } muziekbestand vergelijken
|
||||
progress_scanning_music_content = Vingerafdruk berekenen van { $file_checked }/{ $all_files } muziekbestand
|
||||
progress_scanning_empty_folders = Scannen { $folder_number } map
|
||||
progress_scanning_size = Scannen grootte van { $file_number } bestand
|
||||
progress_scanning_size_name = Scannen van naam en grootte van { $file_number } bestand
|
||||
progress_scanning_name = Scannen van naam { $file_number } bestand
|
||||
progress_analyzed_partial_hash = Geanalyseerde gedeeltelijke hash van { $file_checked }/{ $all_files } bestanden
|
||||
progress_analyzed_full_hash = Volledige hash van { $file_checked }/{ $all_files } bestanden geanalyseerd
|
||||
progress_prehash_cache_loading = Prehash cache laden
|
||||
progress_prehash_cache_saving = Opslaan van prehash cache
|
||||
progress_hash_cache_loading = hash-cache laden
|
||||
progress_hash_cache_saving = hash cache opslaan
|
||||
progress_cache_loading = Cache laden
|
||||
progress_cache_saving = Cache opslaan
|
||||
progress_current_stage = Current Stage:{ " " }
|
||||
progress_all_stages = All Stages:{ " " }
|
||||
# Saving loading
|
||||
saving_loading_saving_success = Configuratie opgeslagen in bestand { $name }.
|
||||
saving_loading_saving_failure = Kan configuratiegegevens niet opslaan in bestand { $name }.
|
||||
saving_loading_reset_configuration = Huidige configuratie is gewist.
|
||||
saving_loading_loading_success = Goed geladen app configuratie.
|
||||
saving_loading_invalid_string = Voor sleutel "{ $key }" vond een ongeldig resultaat - "{ $result }" wat geen string is.
|
||||
saving_loading_invalid_int = Voor sleutel "{ $key }" vond een ongeldig resultaat - "{ $result }" wat geen geheel getal is.
|
||||
saving_loading_invalid_bool = Voor sleutel "{ $key }" vond een ongeldig resultaat - "{ $result }" wat geen baas is.
|
||||
saving_loading_decode_problem_bool = Kan bool van sleutel niet decoderen "{ $key }" gevonden "{ $result }" maar toegestane waarden zijn 0, 1, waar of onwaar.
|
||||
saving_loading_saving_same_keys = Proberen de instelling op te slaan met de gedupliceerde sleutel "{ $key }".
|
||||
saving_loading_failed_to_get_home_directory = Fout bij het ophalen van de home directory naar configuratiebestand openen/opslaan.
|
||||
saving_loading_folder_config_instead_file = Kan configuratiebestand niet aanmaken of openen in pad "{ $path }" omdat er al een map is.
|
||||
saving_loading_failed_to_create_configuration_folder = Configuratie mislukt om configuratiemap "{ $path }", reden "{ $reason } " te maken.
|
||||
saving_loading_failed_to_create_config_file = Fout bij het aanmaken van het configuratiebestand "{ $path }", reden "{ $reason }".
|
||||
saving_loading_failed_to_read_config_file = Kan configuratie niet laden van "{ $path }" omdat deze niet bestaat of geen bestand is.
|
||||
saving_loading_failed_to_read_data_from_file = Kan gegevens niet lezen van bestand "{ $path }", reden "{ $reason }".
|
||||
saving_loading_orphan_data = orphan data gevonden "{ $data }" in regel "{ $line }".
|
||||
saving_loading_not_valid = Instelling "{ $data }" bestaat niet in de huidige versie van de app.
|
||||
# Invalid symlinks
|
||||
invalid_symlink_infinite_recursion = Oneindige recursie
|
||||
invalid_symlink_non_existent_destination = Niet-bestaand doelbestand
|
||||
# Other
|
||||
selected_all_reference_folders = Kan zoeken niet starten, als alle mappen als referentie mappen zijn ingesteld
|
||||
searching_for_data = Gegevens zoeken, het kan een tijdje duren, even wachten...
|
||||
text_view_messages = BERICHTEN
|
||||
text_view_warnings = LET OP
|
||||
text_view_errors = FOUTEN
|
||||
about_window_motto = Dit programma is gratis te gebruiken en zal dat altijd zijn.
|
||||
# Various dialog
|
||||
dialogs_ask_next_time = Volgende keer vragen
|
||||
delete_file_failed = Kan het bestand { $name }niet verwijderen, reden { $reason }
|
||||
delete_title_dialog = Bevestiging verwijderen
|
||||
delete_question_label = Weet u zeker dat u bestanden wilt verwijderen?
|
||||
delete_all_files_in_group_title = Bevestiging van het verwijderen van alle bestanden in groep
|
||||
delete_all_files_in_group_label1 = In sommige groepen worden alle records geselecteerd.
|
||||
delete_all_files_in_group_label2 = Weet u zeker dat u deze wilt verwijderen?
|
||||
delete_folder_failed = Kan de map { $dir } niet verwijderen omdat de map niet bestaat, u hebt geen toestemming of de map is niet leeg.
|
||||
delete_items_label = { $items } bestanden worden verwijderd.
|
||||
delete_items_groups_label = { $items } bestanden van { $groups } groepen worden verwijderd.
|
||||
hardlink_failed = Hardlink mislukt
|
||||
hard_sym_invalid_selection_title_dialog = Ongeldige selectie met sommige groepen
|
||||
hard_sym_invalid_selection_label_1 = In sommige groepen is er slechts één record geselecteerd en zal worden genegeerd.
|
||||
hard_sym_invalid_selection_label_2 = Om deze bestanden hard/sym te kunnen koppelen, moeten ten minste twee resultaten in de groep worden geselecteerd.
|
||||
hard_sym_invalid_selection_label_3 = Eerst wordt de groep als origineel erkend en niet veranderd, en vervolgens worden de tweede wijzigingen aangebracht.
|
||||
hard_sym_link_title_dialog = Bevestiging link
|
||||
hard_sym_link_label = Weet u zeker dat u deze bestanden wilt koppelen?
|
||||
move_folder_failed = Map { $name }kon niet verplaatst worden, reden { $reason }
|
||||
move_file_failed = Kon bestand niet verplaatsen { $name }, reden { $reason }
|
||||
move_files_title_dialog = Kies de map waarnaar u gedupliceerde bestanden wilt verplaatsen
|
||||
move_files_choose_more_than_1_path = Er kan slechts één pad geselecteerd zijn om hun gedupliceerde bestanden te kopiëren, geselecteerde { $path_number }.
|
||||
move_stats = Naar behoren verplaatst { $num_files }/{ $all_files } items
|
||||
save_results_to_file = Opgeslagen resultaten zowel in txt als in json bestanden in { $name } map.
|
||||
search_not_choosing_any_music = FOUT: U moet ten minste één selectievakje met muziekinstypes selecteren.
|
||||
search_not_choosing_any_broken_files = FOUT: U moet ten minste één selectievakje selecteren met type van aangevinkte bestanden.
|
||||
include_folders_dialog_title = Mappen om op te nemen
|
||||
exclude_folders_dialog_title = Mappen om uit te sluiten
|
||||
include_manually_directories_dialog_title = Voeg map handmatig toe
|
||||
cache_properly_cleared = Cache op juiste wijze gewist
|
||||
cache_clear_duplicates_title = Duplicaten cache wissen
|
||||
cache_clear_similar_images_title = Leeg soortgelijke afbeeldingen-cache
|
||||
cache_clear_similar_videos_title = Leeg soortgelijke video cache
|
||||
cache_clear_message_label_1 = Wilt u de cache van verouderde items wissen?
|
||||
cache_clear_message_label_2 = Deze actie zal alle cache-items verwijderen die naar ongeldige bestanden wijzen.
|
||||
cache_clear_message_label_3 = Dit kan de laden/opslaan enigszins versnellen.
|
||||
cache_clear_message_label_4 = WAARSCHUWING: De bewerking zal alle opgeslagen data van externe schijven verwijderen. Daarom zal elke hash opnieuw moeten worden gegenereerd.
|
||||
# Show preview
|
||||
preview_image_resize_failure = Formaat wijzigen van afbeelding { $name } is mislukt.
|
||||
preview_image_opening_failure = Kan afbeelding { $name }niet openen, reden { $reason }
|
||||
# Compare images (L is short Left, R is short Right - they can't take too much space)
|
||||
compare_groups_number = Groep { $current_group }/{ $all_groups } ({ $images_in_group } afbeeldingen)
|
||||
compare_move_left_button = L
|
||||
compare_move_right_button = R
|
@ -0,0 +1,500 @@
|
||||
# Window titles
|
||||
window_settings_title = Innstillinger
|
||||
window_main_title = Czkawka (Hiccup)
|
||||
window_progress_title = Skanner
|
||||
window_compare_images = Sammenlign bilder
|
||||
# General
|
||||
general_ok_button = Ok
|
||||
general_close_button = Lukk
|
||||
# Main window
|
||||
music_title_checkbox = Tittel
|
||||
music_artist_checkbox = Artist
|
||||
music_year_checkbox = År
|
||||
music_bitrate_checkbox = Bitrate
|
||||
music_genre_checkbox = Sjanger
|
||||
music_length_checkbox = Lengde
|
||||
music_comparison_checkbox = Omtrentlig sammenligning
|
||||
music_checking_by_tags = Tagger
|
||||
music_checking_by_content = Innhold
|
||||
same_music_seconds_label = Minste fragment andre varighet
|
||||
same_music_similarity_label = Maksimal differanse
|
||||
same_music_tooltip =
|
||||
Søker etter lignende musikkfiler av innholdet kan konfigureres ved å gå inn:
|
||||
|
||||
- Minimumsfragmenteringstiden etter hvilken musikkfiler som kan identifiseres som lignende
|
||||
- Maksimal forskjell mellom to testede fragmenter
|
||||
|
||||
Nøkkelen til gode resultater er å finne fornuftige kombinasjoner av disse parametrene, for utlevert.
|
||||
|
||||
Angir minimum tid til 5 s og maksimal forskjell til 1,0, vil se etter nesten identiske fragmenter i filene.
|
||||
En tid på 20 s og en maksimal forskjell på 6.0, for den andre siden fungerer bra for å finne remikser/levende versjoner osv.
|
||||
|
||||
Som standard kan hver musikkfil sammenlignes med hverandre, og dette kan ta mye tid når du tester mange filer, slik at det vanligvis er bedre å bruke referanselapper og spesifisere hvilke filer som skal sammenlignes med hverandre (med samme mengde filer, å sammenligne fingeravtrykk vil være raskere minst 4 x enn uten referansemapper).
|
||||
music_comparison_checkbox_tooltip =
|
||||
Den søker etter lignende musikkfiler ved hjelp av AI, som bruker maskiner til å fjerne parenteser fra et frase. For eksempel, med dette alternativet er aktivert. filene du vil bli betraktet som duplikater:
|
||||
|
||||
Świędziżłób --- Świędziżłób (Remix Lato 2021)
|
||||
duplicate_case_sensitive_name = Skill mellom små og store bokstaver
|
||||
duplicate_case_sensitive_name_tooltip =
|
||||
Når aktivert, vil du bare gruppere når de har nøyaktig samme navn, f.eks. Żołd <-> Żołd
|
||||
|
||||
Deaktivering av en slik opsjon vil gi deg egne navn uten å sjekke om hver bokstav er like stort, f.eks. żoŁD <-> Żołd
|
||||
duplicate_mode_size_name_combo_box = Størrelse og navn
|
||||
duplicate_mode_name_combo_box = Navn
|
||||
duplicate_mode_size_combo_box = Størrelse
|
||||
duplicate_mode_hash_combo_box = Hash
|
||||
duplicate_hash_type_tooltip =
|
||||
Tsjekkia har 3 typer hashes:
|
||||
|
||||
Blake3 - kryptografisk hash-funksjon. Dette er standard fordi den er veldig rask.
|
||||
|
||||
CRC32 - enkel hash-funksjon. Dette bør være raskere enn Blake3, men kan svært sjelden ha noen kollisjoner.
|
||||
|
||||
XXH3 - meget likt i ytelse og hash-kvalitet til Blake3 (men ikke-kryptografisk). Såfremt kan slike moduser endres enkelt.
|
||||
duplicate_check_method_tooltip =
|
||||
Tsjekkka tilbyr tre typer metoder for å finne duplikater av:
|
||||
|
||||
Navn - Finner filer med samme navn.
|
||||
|
||||
Størrelse på funnet finner du filer med samme størrelse.
|
||||
|
||||
Hash - Finner filer med samme innhold. Denne modusen ligner filen og senere sammenligner dette hashen for å finne duplikater. Denne modusen er den sikreste måten å finne duplikater. Appen bruker stort, så sekund og ytterligere skanninger av de samme dataene bør være mye raskere enn det første.
|
||||
image_hash_size_tooltip =
|
||||
Hvert avmerkede bilde gir en spesiell hash som kan sammenlignes med hverandre, og en liten forskjell mellom dem betyr at disse bildene er like.
|
||||
|
||||
8 hash-størrelse er ganske bra for å finne bilder som er litt likt original. Med et større sett med bilder (>1000) vil dette gi svært mange falske positive. Derfor anbefaler jeg å bruke en større hash-størrelse i denne saken.
|
||||
|
||||
16 er standard hash-størrelse som er et godt kompromiss mellom å finne selv små lignende bilder og å ha bare en liten mengde hash-kollisjoner.
|
||||
|
||||
32 og 64 hashes finner bare lignende bilder, men bør ha nesten ingen falske positiver (kanskje unntatt bilder med alfa-kanal).
|
||||
image_resize_filter_tooltip =
|
||||
To compute hash of image, the library must first resize it.
|
||||
|
||||
Depend on chosen algorithm, the resulting image used to calculate hash will looks a little different.
|
||||
|
||||
The fastest algorithm to use, but also the one which gives the worst results, is Nearest. It is enabled by default, because with 16x16 hash size lower quality it is not really visible.
|
||||
|
||||
With 8x8 hash size it is recommended to use a different algorithm than Nearest, to have better groups of images.
|
||||
image_hash_alg_tooltip =
|
||||
Brukere kan velge mellom en av mange algoritmer i beregningen av hashen.
|
||||
|
||||
Hver har både sterke og svakere poeng, og vil noen ganger gi bedre og noen ganger verre resultater for ulike bilder.
|
||||
|
||||
Så for å bestemme det beste for deg, kreves manuell testing.
|
||||
big_files_mode_combobox_tooltip = Lar deg søke etter minste/største filer
|
||||
big_files_mode_label = Avmerkede filer
|
||||
big_files_mode_smallest_combo_box = Den minste
|
||||
big_files_mode_biggest_combo_box = Den største
|
||||
main_notebook_duplicates = Dupliser filer
|
||||
main_notebook_empty_directories = Tomme mapper
|
||||
main_notebook_big_files = Store filer
|
||||
main_notebook_empty_files = Tomme filer
|
||||
main_notebook_temporary = Midlertidige filer
|
||||
main_notebook_similar_images = Lignende bilder
|
||||
main_notebook_similar_videos = Lignende videoer
|
||||
main_notebook_same_music = Musikk dupliserer
|
||||
main_notebook_symlinks = Ugyldige Symlinks
|
||||
main_notebook_broken_files = Ødelagte filer
|
||||
main_notebook_bad_extensions = Feil utvidelser
|
||||
main_tree_view_column_file_name = Filnavn
|
||||
main_tree_view_column_folder_name = Mappenavn
|
||||
main_tree_view_column_path = Sti
|
||||
main_tree_view_column_modification = Endret dato
|
||||
main_tree_view_column_size = Størrelse
|
||||
main_tree_view_column_similarity = Likhet
|
||||
main_tree_view_column_dimensions = Dimensjoner
|
||||
main_tree_view_column_title = Tittel
|
||||
main_tree_view_column_artist = Artist
|
||||
main_tree_view_column_year = År
|
||||
main_tree_view_column_bitrate = Bitrate
|
||||
main_tree_view_column_length = Lengde
|
||||
main_tree_view_column_genre = Sjanger
|
||||
main_tree_view_column_symlink_file_name = Symlink filnavn
|
||||
main_tree_view_column_symlink_folder = Mappe for Symlink
|
||||
main_tree_view_column_destination_path = Destinasjonssti
|
||||
main_tree_view_column_type_of_error = Type feil
|
||||
main_tree_view_column_current_extension = Gjeldende utvidelse
|
||||
main_tree_view_column_proper_extensions = Riktig utvidelse
|
||||
main_label_check_method = Sjekkmetode
|
||||
main_label_hash_type = Type hash
|
||||
main_label_hash_size = Størrelse på hash
|
||||
main_label_size_bytes = Størrelse (bytes)
|
||||
main_label_min_size = Min
|
||||
main_label_max_size = Maks
|
||||
main_label_shown_files = Antall filer som vises
|
||||
main_label_resize_algorithm = Endre algoritmen
|
||||
main_label_similarity = Similarity{ " " }
|
||||
main_check_box_broken_files_audio = Lyd
|
||||
main_check_box_broken_files_pdf = Pdf
|
||||
main_check_box_broken_files_archive = Arkiv
|
||||
main_check_box_broken_files_image = Bilde
|
||||
check_button_general_same_size = Ignorer samme størrelse
|
||||
check_button_general_same_size_tooltip = Ignorer filer med identisk størrelse i resultater - vanligvis disse er 1:1 duplikater
|
||||
main_label_size_bytes_tooltip = Størrelse på filer som vil bli brukt i skanning
|
||||
# Upper window
|
||||
upper_tree_view_included_folder_column_title = Mapper å søke etter
|
||||
upper_tree_view_included_reference_column_title = Referanse mapper
|
||||
upper_recursive_button = Rekursivt
|
||||
upper_recursive_button_tooltip = Hvis valgt, søk også etter filer som ikke er plassert direkte under valgte mapper.
|
||||
upper_manual_add_included_button = Manuelt legg til
|
||||
upper_add_included_button = Legg til
|
||||
upper_remove_included_button = Fjern
|
||||
upper_manual_add_excluded_button = Manuelt legg til
|
||||
upper_add_excluded_button = Legg til
|
||||
upper_remove_excluded_button = Fjern
|
||||
upper_manual_add_included_button_tooltip =
|
||||
Legg til mappenavn for å søke etter hånd.
|
||||
|
||||
For å legge til flere baner samtidig, separer dem med ;
|
||||
|
||||
/home/roman;/home/rozkaz vil legge til to kataloger /home/roman og /home/rozkaz
|
||||
upper_add_included_button_tooltip = Legg til ny mappe i søk.
|
||||
upper_remove_included_button_tooltip = Slett mappen fra søk.
|
||||
upper_manual_add_excluded_button_tooltip =
|
||||
Legg til ekskludert mappenavn for hånd.
|
||||
|
||||
For å legge til flere baner på en gang, separer dem med ;
|
||||
|
||||
/home/roman;/home/krokiet vil legge til to kataloger /home/roman and /home/keokiet
|
||||
upper_add_excluded_button_tooltip = Legg til mappe som skal utelukkes i søk.
|
||||
upper_remove_excluded_button_tooltip = Slett mappen fra ekskludert.
|
||||
upper_notebook_items_configuration = Konfigurasjon av elementer
|
||||
upper_notebook_excluded_directories = Ekskluderte kataloger
|
||||
upper_notebook_included_directories = Inkluderte mapper
|
||||
upper_allowed_extensions_tooltip =
|
||||
Tillatte utvidelser må være atskilt med komma (ved at alle er tilgjengelige).
|
||||
|
||||
Følgende makroer, som legger til flere utvidelser samtidig, er også tilgjengelige: IMAGE, VIDEO, MUSIC, TEXT.
|
||||
|
||||
Bruk eksempel ".exe, IMAGE, VIDEO, .rar, 7z" - dette betyr at bilder (e. . jpg, png), videoer (f.eks. avi, mp4), exe, rar og 7z filer vil bli skannet.
|
||||
upper_excluded_extensions_tooltip =
|
||||
Liste over deaktiverte filer som vil bli ignorert i skanning.
|
||||
|
||||
Ved bruk av både tillatte og deaktiverte utvidelser, har denne prioriteten høyere enn prioritet, så filen vil ikke bli sjekket.
|
||||
upper_excluded_items_tooltip =
|
||||
Ekskluderte elementer må inneholde * jokertegn og bør separeres med komma.
|
||||
Dette er tregere enn ekskluderte kataloger, så bruk den med forsiktighet.
|
||||
upper_excluded_items = Ekskluderte elementer:
|
||||
upper_allowed_extensions = Tillatte utvidelser:
|
||||
upper_excluded_extensions = Deaktiverte utvidelser:
|
||||
# Popovers
|
||||
popover_select_all = Velg alle
|
||||
popover_unselect_all = Fjern alle valg
|
||||
popover_reverse = Omvendt utvalg
|
||||
popover_select_all_except_oldest = Velg alt unntatt det eldste
|
||||
popover_select_all_except_newest = Velg alle unntatt nyeste
|
||||
popover_select_one_oldest = Velg en eldste
|
||||
popover_select_one_newest = Velg en nyeste
|
||||
popover_select_custom = Velg egendefinert
|
||||
popover_unselect_custom = Avvelg egendefinert
|
||||
popover_select_all_images_except_biggest = Velg alle unntatt største
|
||||
popover_select_all_images_except_smallest = Velg alle unntatt minste
|
||||
popover_custom_path_check_button_entry_tooltip =
|
||||
Velg poster som sti.
|
||||
|
||||
Eksempelbruk:
|
||||
/home/pimpek/rzecz.txt kan du finne med /home/pim*
|
||||
popover_custom_name_check_button_entry_tooltip =
|
||||
Velg poster etter filnavn.
|
||||
|
||||
Eksempelbruk:
|
||||
/usr/ping/pong.txt kan finnes med *ong*
|
||||
popover_custom_regex_check_button_entry_tooltip =
|
||||
Velg elementer ved angitt Regex.
|
||||
|
||||
Med denne modus, vil søppelteksten være Sti med navn.
|
||||
|
||||
Eksempel på bruk:
|
||||
/usr/bin/ziemniak. xt finner du med /ziem[a-z]+
|
||||
|
||||
Dette bruker standard Rust regex implementasjon. Du kan lese mer om den her: https://docs.rs/regex.
|
||||
popover_custom_case_sensitive_check_button_tooltip =
|
||||
Aktiverer case-sensitiv deteksjon.
|
||||
|
||||
Når deaktivert/hjem/* funn både /HoMe/roman og /home/roman.
|
||||
popover_custom_not_all_check_button_tooltip =
|
||||
Hindrer å velge alle poster i gruppen.
|
||||
|
||||
Dette er aktivert som standard, fordi i de fleste situasjoner du ikke vil slette både originale og duplikatfiler, men vil forlate minst en fil.
|
||||
|
||||
ADVARSEL: Denne innstillingen fungerer ikke hvis du allerede har valgt alle resultater i en gruppe.
|
||||
popover_custom_regex_path_label = Sti
|
||||
popover_custom_regex_name_label = Navn
|
||||
popover_custom_regex_regex_label = Regex sti + navn
|
||||
popover_custom_case_sensitive_check_button = Skill store og små bokstaver
|
||||
popover_custom_all_in_group_label = Ikke velg alle poster i gruppen
|
||||
popover_custom_mode_unselect = Avvelg egendefinert
|
||||
popover_custom_mode_select = Velg egendefinert
|
||||
popover_sort_file_name = Filnavn
|
||||
popover_sort_folder_name = Mappenavn
|
||||
popover_sort_full_name = Fullt navn
|
||||
popover_sort_size = Størrelse
|
||||
popover_sort_selection = Utvalg
|
||||
popover_invalid_regex = Regex er ugyldig
|
||||
popover_valid_regex = Regex er gyldig
|
||||
# Bottom buttons
|
||||
bottom_search_button = Søk
|
||||
bottom_select_button = Velg
|
||||
bottom_delete_button = Slett
|
||||
bottom_save_button = Save
|
||||
bottom_symlink_button = Symlink
|
||||
bottom_hardlink_button = Hardlink
|
||||
bottom_move_button = Flytt
|
||||
bottom_sort_button = Sorter
|
||||
bottom_search_button_tooltip = Starte søk
|
||||
bottom_select_button_tooltip = Velg oppføringer. Bare valgte filer/mapper kan bli behandlet senere.
|
||||
bottom_delete_button_tooltip = Slett valgte filer/mapper.
|
||||
bottom_save_button_tooltip = Lagre data om søk i fil
|
||||
bottom_symlink_button_tooltip =
|
||||
Opprett symbolske lenker.
|
||||
Virker bare når minst to resultater i en gruppe er valgt.
|
||||
Først er uendret og sekund og senere er symlinket til først.
|
||||
bottom_hardlink_button_tooltip =
|
||||
Opprette fastkoblinger.
|
||||
Virker bare når minst to resultater i en gruppe er valgt.
|
||||
Først er uendret og annet og senere er vanskelig knyttet til først.
|
||||
bottom_hardlink_button_not_available_tooltip =
|
||||
Opprett faste koblinger.
|
||||
Knappen er deaktivert, fordi faste koblinger ikke kan opprettes.
|
||||
Faste koblinger fungerer bare med administratorrettigheter i Windows, så pass på at du kjører programmet som administrator.
|
||||
Hvis programmet allerede fungerer med slike privilegier, sjekk om lignende problemer er observert på GitHub.
|
||||
bottom_move_button_tooltip =
|
||||
Flytter filer til valgt mappe.
|
||||
Den kopierer alle filer til mappen uten å lagre mappetreet.
|
||||
Når du prøver å flytte to filer med identisk navn til mappe, vil det andre feile og vise feil.
|
||||
bottom_sort_button_tooltip = Sorter filer/mapper etter valgt metode.
|
||||
bottom_show_errors_tooltip = Vis/Skjul bunntekstpanelet.
|
||||
bottom_show_upper_notebook_tooltip = Vis/Skjul øvre notebook panel.
|
||||
# Progress Window
|
||||
progress_stop_button = Stopp
|
||||
progress_stop_additional_message = Stopp forespurt
|
||||
# About Window
|
||||
about_repository_button_tooltip = Link til pakkesiden med kildekoden.
|
||||
about_donation_button_tooltip = Lenke til donasjonssiden.
|
||||
about_instruction_button_tooltip = Lenke til instruksjonssiden.
|
||||
about_translation_button_tooltip = Link til Crowdin-siden med app oversettelser. Officialt Polsk og engelsk støttes.
|
||||
about_repository_button = Pakkebrønn
|
||||
about_donation_button = Donasjon
|
||||
about_instruction_button = Instruksjon
|
||||
about_translation_button = Oversettelse
|
||||
# Header
|
||||
header_setting_button_tooltip = Åpner dialogboksen for innstillinger.
|
||||
header_about_button_tooltip = Åpner dialog med info om app.
|
||||
|
||||
# Settings
|
||||
|
||||
|
||||
## General
|
||||
|
||||
settings_number_of_threads = Antall brukte tråder
|
||||
settings_number_of_threads_tooltip = Antall brukte tråder. 0 betyr at alle tilgjengelige tråder vil bli brukt.
|
||||
settings_label_restart = Start programmet på nytt for å bruke innstillingene!
|
||||
settings_ignore_other_filesystems = Ignorer andre filsystemer (bare Linux)
|
||||
settings_ignore_other_filesystems_tooltip =
|
||||
ignorerer filer som ikke er i samme filsystem som søk-kataloger.
|
||||
|
||||
Fungerer samme som -xdev alternativet i å finne kommandoen på Linux
|
||||
settings_save_at_exit_button_tooltip = Lagre konfigurasjon som fil når appen lukkes.
|
||||
settings_load_at_start_button_tooltip =
|
||||
Last inn konfigurasjon fra filen når du åpner appen.
|
||||
|
||||
Hvis ikke er aktivert brukes standard innstillinger.
|
||||
settings_confirm_deletion_button_tooltip = Vis bekreftelsesdialog når du klikker på Slette-knappen.
|
||||
settings_confirm_link_button_tooltip = Vis bekreftelsesdialog når du klikker på knappen hard/symlink.
|
||||
settings_confirm_group_deletion_button_tooltip = Vis advarselsdialog når du prøver å slette alle poster fra gruppen.
|
||||
settings_show_text_view_button_tooltip = Vis tekstpanelet nederst av brukergrensesnittet.
|
||||
settings_use_cache_button_tooltip = Bruk filmellomlager.
|
||||
settings_save_also_as_json_button_tooltip = Lagre cache til (human lesbar) JSON-format. Det er mulig å endre innholdet. Cachen fra denne filen vil automatisk bli lest av app dersom binært format mellomlager (med «bøi-utvidelsen») mangler.
|
||||
settings_use_trash_button_tooltip = Flytter filer til papirkurv istedenfor å slette dem permanent.
|
||||
settings_language_label_tooltip = Språk til brukergrensesnitt.
|
||||
settings_save_at_exit_button = Lagre konfigurasjon når appen lukkes
|
||||
settings_load_at_start_button = Last inn konfigurasjon når du åpner appen
|
||||
settings_confirm_deletion_button = Vis bekreftelsesdialog ved sletting av filer
|
||||
settings_confirm_link_button = Vis bekreftelsesdialog når noen filer er fast/symlinker
|
||||
settings_confirm_group_deletion_button = Vis "Bekreft"-dialog når du sletter alle filer i gruppen
|
||||
settings_show_text_view_button = Vis nederste tekstpanel
|
||||
settings_use_cache_button = Bruk buffer
|
||||
settings_save_also_as_json_button = Lagre også mellomlager som JSON-fil
|
||||
settings_use_trash_button = Flytt slettede filer til papirkurv
|
||||
settings_language_label = Language
|
||||
settings_multiple_delete_outdated_cache_checkbutton = Slett utdaterte cache-oppføringer automatisk
|
||||
settings_multiple_delete_outdated_cache_checkbutton_tooltip =
|
||||
Slett utdaterte cache-resultater som peker til ikke-eksisterende filer.
|
||||
|
||||
Når aktivert sørger appen for å laste inn poster, at alle oppføringer peker til gyldige filer (ødelagte blir ignorert).
|
||||
|
||||
Deaktivering av dette vil hjelpe når du skanner filer på eksterne stasjoner, så cacheoppføringer om dem vil ikke bli tømt i neste skanning.
|
||||
|
||||
Når det gjelder å ha hundre og tusenvis av registreringer i cache, det er foreslått å aktivere dette, som vil øke hurtigbufferen innlasting/lagring ved start/slutten av skanningen.
|
||||
settings_notebook_general = Generelt
|
||||
settings_notebook_duplicates = Duplikater
|
||||
settings_notebook_images = Lignende bilder
|
||||
settings_notebook_videos = Lignende video
|
||||
|
||||
## Multiple - settings used in multiple tabs
|
||||
|
||||
settings_multiple_image_preview_checkbutton_tooltip = Viser forhåndsvisning på høyre side (når du velger en bildefil).
|
||||
settings_multiple_image_preview_checkbutton = Vis forhåndsvisning av bilde
|
||||
settings_multiple_clear_cache_button_tooltip =
|
||||
Manuelt tømmer hurtigbufferen av utdaterte oppføringer.
|
||||
Dette bør bare brukes hvis automatisk tømming er deaktivert.
|
||||
settings_multiple_clear_cache_button = Fjern utdaterte resultater fra mellomlager.
|
||||
|
||||
## Duplicates
|
||||
|
||||
settings_duplicates_hide_hard_link_button_tooltip =
|
||||
Skjuler alle filer unntatt en, hvis alle peker til samme data (knyttes sammen).
|
||||
|
||||
Eksempel: I det tilfellet hvor det (på disk) er syv filer som er vanskelige å koble til bestemte data og én annen fil med samme data men en annen innhold, deretter i duplisert finer, vises bare én unik fil og én fil fra hardkoblede vil vises.
|
||||
settings_duplicates_minimal_size_entry_tooltip =
|
||||
Angi minste filstørrelse som blir bufret i cachen.
|
||||
|
||||
Hvis du velger en mindre verdi, genererer du flere poster. Dette vil fremskynde søk, men tregere hurtigbufferet lasting/lagring.
|
||||
settings_duplicates_prehash_checkbutton_tooltip =
|
||||
Aktiverer hurtigbufring av prehash (en hash beregnet fra en liten del av filen) som tillater tidligere fjerning av ikke-dupliserte resultater.
|
||||
|
||||
Den er deaktivert som standard fordi den kan forårsake langsommere i noen situasjoner.
|
||||
|
||||
Det anbefales å bruke det når det skannes hundre eller millioner filer, fordi det kan fremskynde søk med flere ganger.
|
||||
settings_duplicates_prehash_minimal_entry_tooltip = Minimal størrelse på mellomlagret oppføring.
|
||||
settings_duplicates_hide_hard_link_button = Skjul hardlinker (kun Linux og macOS)
|
||||
settings_duplicates_prehash_checkbutton = Bruk prehash cache
|
||||
settings_duplicates_minimal_size_cache_label = Minimal størrelse på filer (i byte) lagret i mellomlager
|
||||
settings_duplicates_minimal_size_cache_prehash_label = Minimal størrelse på filer (i byte) lagret i hurtigbuffer for prehash
|
||||
|
||||
## Saving/Loading settings
|
||||
|
||||
settings_saving_button_tooltip = Lagre gjeldende innstillingskonfigurasjon til filen.
|
||||
settings_loading_button_tooltip = Last innstillinger fra fil og erstatt gjeldende konfigurasjon med dem.
|
||||
settings_reset_button_tooltip = Tilbakestill den gjeldende konfigurasjonen til standard.
|
||||
settings_saving_button = Lagre konfigurasjonen
|
||||
settings_loading_button = Last inn konfigurasjon
|
||||
settings_reset_button = Tilbakestill konfigurasjon
|
||||
|
||||
## Opening cache/config folders
|
||||
|
||||
settings_folder_cache_open_tooltip =
|
||||
Åpner mappen der cache txt filene er lagret.
|
||||
|
||||
Modifisere cachefilene kan forårsake ugyldige resultater. Imidlertid kan modifisere stien spare tid når du flytter store mengder filer til en annen posisjon.
|
||||
|
||||
Du kan kopiere disse filene mellom datamaskiner for å spare tid ved skanning igjen for filer (hvis de har en lignende katalogstruktur).
|
||||
|
||||
Hvis det oppstår problemer med cachen, kan disse filene fjernes. Appen vil automatisk regenerere dem.
|
||||
settings_folder_settings_open_tooltip =
|
||||
Åpner mappen der Czkawka konfigurasjonen er lagret.
|
||||
|
||||
ADVARSEL: Manuelt endre konfigurasjonen kan ødelegge arbeidsflyten din.
|
||||
settings_folder_cache_open = Åpne mappe for hurtigbuffer
|
||||
settings_folder_settings_open = Åpne innstillingsmappen
|
||||
# Compute results
|
||||
compute_stopped_by_user = Søket ble stoppet av bruker
|
||||
compute_found_duplicates_hash_size = Fant { $number_files } duplikater i { $number_groups } grupper som tok { $size }
|
||||
compute_found_duplicates_name = Fant { $number_files } duplikater i { $number_groups } grupper
|
||||
compute_found_empty_folders = Fant { $number_files } tomme mapper
|
||||
compute_found_empty_files = Fant { $number_files } tomme filer
|
||||
compute_found_big_files = Fant { $number_files } store filer
|
||||
compute_found_temporary_files = Fant { $number_files } midlertidige filer
|
||||
compute_found_images = Fant { $number_files } lignende bilder i { $number_groups } grupper
|
||||
compute_found_videos = Fant { $number_files } lignende videoer i { $number_groups } grupper
|
||||
compute_found_music = Fant { $number_files } lignende musikkfiler i { $number_groups } grupper
|
||||
compute_found_invalid_symlinks = Fant { $number_files } ugyldige symlinker
|
||||
compute_found_broken_files = Fant { $number_files } ødelagte filer
|
||||
compute_found_bad_extensions = Fant { $number_files } filer med ugyldige utvidelser
|
||||
# Progress window
|
||||
progress_scanning_general_file = Skanner { $file_number } fil
|
||||
progress_scanning_extension_of_files = Sjekker utvidelse av { $file_checked }/{ $all_files } fil
|
||||
progress_scanning_broken_files = Kontrollerer { $file_checked }/{ $all_files } fil
|
||||
progress_scanning_video = Hashing av { $file_checked }/{ $all_files } video
|
||||
progress_scanning_image = Hashing av { $file_checked }/{ $all_files } bilde
|
||||
progress_comparing_image_hashes = Sammenligner { $file_checked }/{ $all_files } bilde-hash
|
||||
progress_scanning_music_tags_end = Sammenligner tagger med { $file_checked }/{ $all_files } musikkfil
|
||||
progress_scanning_music_tags = Leser tagger på { $file_checked }/{ $all_files } musikkfil
|
||||
progress_scanning_music_content_end = Sammenligner fingeravtrykk på { $file_checked }/{ $all_files } musikkfil
|
||||
progress_scanning_music_content = Beregner fingeravtrykk på { $file_checked }/{ $all_files } musikkfil
|
||||
progress_scanning_empty_folders = Skanner { $folder_number } mappe
|
||||
progress_scanning_size = Skanner størrelse på { $file_number } fil
|
||||
progress_scanning_size_name = Skanning av navn og størrelse på { $file_number } fil
|
||||
progress_scanning_name = Skanning av navn på { $file_number } fil
|
||||
progress_analyzed_partial_hash = Analyserte delvis hash med { $file_checked }/{ $all_files } filer
|
||||
progress_analyzed_full_hash = Analyserte full hash med { $file_checked }/{ $all_files } filer
|
||||
progress_prehash_cache_loading = Laster prehash cache
|
||||
progress_prehash_cache_saving = Lagrer prehash-cache
|
||||
progress_hash_cache_loading = Laster hash-cache
|
||||
progress_hash_cache_saving = Lagrer hurtigbufferen for hash
|
||||
progress_cache_loading = Laster cache
|
||||
progress_cache_saving = Lagrer cachen
|
||||
progress_current_stage = Gjeldende trinn: { " " }
|
||||
progress_all_stages = Alle stadier:{ " " }
|
||||
# Saving loading
|
||||
saving_loading_saving_success = Lagret konfigurasjon til filen { $name }.
|
||||
saving_loading_saving_failure = Klarte ikke å lagre konfigurasjonsdataene til filen { $name }.
|
||||
saving_loading_reset_configuration = Gjeldende konfigurasjon ble fjernet.
|
||||
saving_loading_loading_success = Godt lastet applikasjonskonfigurasjon.
|
||||
saving_loading_invalid_string = For nøkkelen "{ $key }" fant du ugyldig resultat - "{ $result }" som ikke er en streng.
|
||||
saving_loading_invalid_int = I nøkkelen "{ $key }" fant du ugyldig resultat - "{ $result }" som ikke er et heltall.
|
||||
saving_loading_invalid_bool = For nøkkelen "{ $key }" fant ugyldig resultat - "{ $result }" som ikke er en bool.
|
||||
saving_loading_decode_problem_bool = Kan ikke dekode bool fra nøkkelen "{ $key }" funnet "{ $result }", men tillatte verdier er 0, 1, sanne eller usann.
|
||||
saving_loading_saving_same_keys = Prøver å lagre innstillinger med duplisert nøkkel "{ $key }".
|
||||
saving_loading_failed_to_get_home_directory = Klarte ikke å hente hjemmappen for å åpne og lagre konfigurasjonsfilen.
|
||||
saving_loading_folder_config_instead_file = Kan ikke opprette eller åpne lagringsfilbanen{ $path }" fordi allerede finnes en mappe.
|
||||
saving_loading_failed_to_create_configuration_folder = Kunne ikke konfigurere opprette konfigurasjonsmappen "{ $path }", grunn "{ $reason }".
|
||||
saving_loading_failed_to_create_config_file = Kunne ikke opprette konfigurasjonsfilen{ $path }", grunn "{ $reason }".
|
||||
saving_loading_failed_to_read_config_file = Kan ikke laste konfigurasjonen fra "{ $path }" fordi den ikke eksisterer eller ikke er en fil.
|
||||
saving_loading_failed_to_read_data_from_file = Kan ikke lese data fra filen{ $path }", grunn "{ $reason }".
|
||||
saving_loading_orphan_data = Funnet orphan data "{ $data }" i linje "{ $line }".
|
||||
saving_loading_not_valid = Setter "{ $data }" finnes ikke i gjeldende appversjon.
|
||||
# Invalid symlinks
|
||||
invalid_symlink_infinite_recursion = Uendelig rekursjon
|
||||
invalid_symlink_non_existent_destination = Ikke-eksisterende målfil
|
||||
# Other
|
||||
selected_all_reference_folders = Kan ikke starte søk, når alle kataloger er angitt som referanselapper
|
||||
searching_for_data = Søker data, det kan ta en stund, vennligst vent...
|
||||
text_view_messages = MELDINGER
|
||||
text_view_warnings = ADVARSELSER
|
||||
text_view_errors = FEILSER
|
||||
about_window_motto = Dette programmet er gratis å bruke og vil alltid være.
|
||||
# Various dialog
|
||||
dialogs_ask_next_time = Spør neste gang
|
||||
delete_file_failed = Kunne ikke slette filen { $name }, årsak { $reason }
|
||||
delete_title_dialog = Bekreft sletting
|
||||
delete_question_label = Er du sikker på at du vil slette filer?
|
||||
delete_all_files_in_group_title = Bekreftelse på sletting av alle filer i gruppen
|
||||
delete_all_files_in_group_label1 = For noen grupper er alle poster valgt.
|
||||
delete_all_files_in_group_label2 = Er du sikker på at du vil slette dem?
|
||||
delete_folder_failed = Kunne ikke slette mappen { $dir } fordi mappen ikke eksisterer, du har ikke tillatelse eller mappen er ikke tom.
|
||||
delete_items_label = { $items } filer vil bli slettet.
|
||||
delete_items_groups_label = { $items } filer fra { $groups } grupper vil bli slettet.
|
||||
hardlink_failed = Mislyktes i å koble sammen
|
||||
hard_sym_invalid_selection_title_dialog = Ugyldig valg med noen grupper
|
||||
hard_sym_invalid_selection_label_1 = I noen grupper er det bare én post valgt og det vil bli ignorert.
|
||||
hard_sym_invalid_selection_label_2 = For å kunne feste koblingen til disse filene, må minst to resultater i gruppen velges.
|
||||
hard_sym_invalid_selection_label_3 = Først i gruppen gjenkjennes som originalen og endres ikke, men sekund og senere endres.
|
||||
hard_sym_link_title_dialog = Lenke bekreftelse
|
||||
hard_sym_link_label = Er du sikker på at du vil koble disse filene?
|
||||
move_folder_failed = Kunne ikke flytte mappen { $name }, årsak { $reason }
|
||||
move_file_failed = Kunne ikke flytte filen { $name }, årsak { $reason }
|
||||
move_files_title_dialog = Velg mappen du vil flytte dupliserte filer til
|
||||
move_files_choose_more_than_1_path = Bare én sti kan velges for å kunne kopiere sine dupliserte filer, valgt { $path_number }.
|
||||
move_stats = Flott flyttet { $num_files }/{ $all_files } elementer
|
||||
save_results_to_file = Lagrede resultater både i txt og json-filer i { $name } mappe.
|
||||
search_not_choosing_any_music = FEIL: Du må velge minst en avkrysningsboks med musikk som søker.
|
||||
search_not_choosing_any_broken_files = FEIL: Du må velge minst en avkrysningsboks med sjekket ødelagte filer.
|
||||
include_folders_dialog_title = Mapper å inkludere
|
||||
exclude_folders_dialog_title = Mapper som skal ekskluderes
|
||||
include_manually_directories_dialog_title = Legg til mappe manuelt
|
||||
cache_properly_cleared = Riktig tømt cache
|
||||
cache_clear_duplicates_title = Tømmer duplikatene
|
||||
cache_clear_similar_images_title = Fjerner lignende bilde-mellomlager
|
||||
cache_clear_similar_videos_title = Tømmer hurtigbufferen for videoer
|
||||
cache_clear_message_label_1 = Vil du slette cachen med utdaterte oppføringer?
|
||||
cache_clear_message_label_2 = Denne operasjonen vil fjerne alle cacheoppføringer som peker til ugyldige filer.
|
||||
cache_clear_message_label_3 = Dette kan øke lasting og lagring på cache.
|
||||
cache_clear_message_label_4 = ADVARSEL: Operasjonen vil fjerne alle bufrede data fra eksterne stasjoner som ikke er koblet til. Så hver hash må regenereres.
|
||||
# Show preview
|
||||
preview_image_resize_failure = Kunne ikke endre størrelse på bildet { $name }.
|
||||
preview_image_opening_failure = Klarte ikke å åpne bilde { $name }, årsak { $reason }
|
||||
# Compare images (L is short Left, R is short Right - they can't take too much space)
|
||||
compare_groups_number = Gruppe { $current_group }/{ $all_groups } ({ $images_in_group } bilder)
|
||||
compare_move_left_button = L
|
||||
compare_move_right_button = R
|
@ -0,0 +1,500 @@
|
||||
# Window titles
|
||||
window_settings_title = Setări
|
||||
window_main_title = Czkawka (Hiccup)
|
||||
window_progress_title = Scanare
|
||||
window_compare_images = Compară imaginile
|
||||
# General
|
||||
general_ok_button = Ok
|
||||
general_close_button = Inchide
|
||||
# Main window
|
||||
music_title_checkbox = Titlu
|
||||
music_artist_checkbox = Artist
|
||||
music_year_checkbox = An
|
||||
music_bitrate_checkbox = Bitrate
|
||||
music_genre_checkbox = Gen
|
||||
music_length_checkbox = Lungime
|
||||
music_comparison_checkbox = Comparație aproximativă
|
||||
music_checking_by_tags = Etichete
|
||||
music_checking_by_content = Conținut
|
||||
same_music_seconds_label = Fragment minim a doua durată
|
||||
same_music_similarity_label = Diferența maximă
|
||||
same_music_tooltip =
|
||||
Căutarea fişierelor muzicale similare după conţinutul său poate fi configurată prin setarea:
|
||||
|
||||
- Timpul minim de fragment după care fişierele muzicale pot fi identificate ca fiind similare
|
||||
- Diferenţa maximă între două fragmente testate
|
||||
|
||||
Cheia pentru rezultate bune este de a găsi combinaţii rezonabile ale acestor parametri, pentru furnizare.
|
||||
|
||||
Setarea timpului minim la 5 s și diferența maximă la 1.0, va căuta fragmente aproape identice în fișiere.
|
||||
O perioadă de 20 de ani și o diferență maximă de 6,0, pe de altă parte, funcționează bine pentru a găsi remixuri/versiuni live etc.
|
||||
|
||||
În mod implicit, fiecare fișier muzical este comparat unul cu altul și acest lucru poate dura mult timp când testezi mai multe fișiere, astfel încât este de obicei mai bine să se utilizeze dosare de referință și să se precizeze care fișiere trebuie comparate între ele (cu același volum de fișiere; compararea amprentelor digitale va fi mai rapidă de cel puțin 4x decât fără dosare de referință).
|
||||
music_comparison_checkbox_tooltip =
|
||||
Caută fișiere muzicale similare folosind AI, care folosește învățarea mașinăriei pentru a elimina paranteze dintr-o frază. De exemplu, cu această opțiune activată, fișierele în cauză vor fi considerate duplicate:
|
||||
|
||||
Remix Lato 2021)
|
||||
duplicate_case_sensitive_name = Sensibil la caz
|
||||
duplicate_case_sensitive_name_tooltip =
|
||||
Când este activată, grupul înregistrează doar atunci când are exact același nume, de ex. Trunchiul <-> Z<unk> ołd
|
||||
|
||||
Dezactivarea acestei opțiuni va grupa numele fără a verifica dacă fiecare literă are aceeași mărime, de ex. z<unk> oŁD <-> Z<unk> ołd
|
||||
duplicate_mode_size_name_combo_box = Dimensiune și nume
|
||||
duplicate_mode_name_combo_box = Nume
|
||||
duplicate_mode_size_combo_box = Dimensiune
|
||||
duplicate_mode_hash_combo_box = Hash
|
||||
duplicate_hash_type_tooltip =
|
||||
Czkawka oferă 3 tipuri de hash-uri:
|
||||
|
||||
Blake3 - funcţie criptografică hash. Acesta este implicit pentru că este foarte rapid.
|
||||
|
||||
CRC32 - funcţia simplă de hash. Acest lucru ar trebui să fie mai rapid decât Blake3, dar foarte rar poate avea unele coliziuni.
|
||||
|
||||
XXH3 - foarte asemănător din punct de vedere al performanței și al calității hash-ului cu Blake3 (dar non-criptografic). Astfel de moduri pot fi ușor interschimbate.
|
||||
duplicate_check_method_tooltip =
|
||||
Deocamdată, Czkawka oferă trei tipuri de metode pentru a găsi duplicate după:
|
||||
|
||||
Nume - Găseşte fişiere care au acelaşi nume.
|
||||
|
||||
Dimensiune - Găseşte fişiere cu aceeaşi dimensiune.
|
||||
|
||||
Hash - Găseşte fişiere care au acelaşi conţinut. Acest mod hashează fişierul şi mai târziu compară acest hash pentru a găsi duplicate. Acest mod este cel mai sigur mod de a găsi duplicate. Aplicaţiile folosesc foarte mult cache, astfel încât scanările de la secundă şi mai departe ale aceloraşi date ar trebui să fie mult mai rapide decât primul.
|
||||
image_hash_size_tooltip =
|
||||
Fiecare imagine verificată produce un hash special, care poate fi comparat între ele, si o diferenta mica intre ele inseamna ca aceste imagini sunt similare.
|
||||
|
||||
dimensiunea de 8 hash este destul de bună pentru a găsi imagini care sunt doar puţin similare cu originalul. Cu un set mai mare de imagini (>1000), acesta va produce o cantitate mare de fals pozitiv, Aşa că vă recomand să utilizaţi o mărime mai mare de hash în acest caz.
|
||||
|
||||
16 este dimensiunea implicită a hash-ului care este un compromis destul de bun între a găsi chiar și imagini similare și a avea doar o mică coliziune a hash-ului.
|
||||
|
||||
32 și 64 de hash-uri găsesc doar imagini foarte similare, dar nu ar trebui să aibă aproape nicio poziție falsă (poate cu excepția unor imagini cu un canal alfa).
|
||||
image_resize_filter_tooltip =
|
||||
Pentru a calcula hash of imagine, biblioteca trebuie mai întâi să o redimensioneze.
|
||||
|
||||
În funcție de algoritmul ales, imaginea rezultată folosită pentru a calcula hash va arăta puțin diferit.
|
||||
|
||||
Cel mai rapid algoritm de utilizat, dar şi cel care dă cele mai slabe rezultate, este Nearest. Acesta este activat în mod implicit, deoarece cu dimensiunea de 16x16 a hash-ului este de calitate mai mică decât cea vizibilă.
|
||||
|
||||
Cu dimensiunea hash de 8x8 este recomandat să se folosească un algoritm diferit de Nearest, pentru a avea grupuri mai bune de imagini.
|
||||
image_hash_alg_tooltip =
|
||||
Utilizatorii pot alege unul dintre multele algoritmi de calculare a hash-ului.
|
||||
|
||||
Fiecare are atât puncte puternice, cât şi puncte mai slabe şi va da uneori rezultate mai bune şi uneori mai proaste pentru imagini diferite.
|
||||
|
||||
Deci, pentru a determina cel mai bun dintre voi, este necesară testarea manuală.
|
||||
big_files_mode_combobox_tooltip = Permite căutarea celor mai mici/mai mari fişiere
|
||||
big_files_mode_label = Fișiere verificate
|
||||
big_files_mode_smallest_combo_box = Cel mai mic
|
||||
big_files_mode_biggest_combo_box = Miggest
|
||||
main_notebook_duplicates = Fișiere duplicate
|
||||
main_notebook_empty_directories = Dosare goale
|
||||
main_notebook_big_files = Fișiere mari
|
||||
main_notebook_empty_files = Fișiere goale
|
||||
main_notebook_temporary = Fișiere temporare
|
||||
main_notebook_similar_images = Imagini similare
|
||||
main_notebook_similar_videos = Video similare
|
||||
main_notebook_same_music = Duplicate Muzică
|
||||
main_notebook_symlinks = Simboluri invalide
|
||||
main_notebook_broken_files = Fișiere defecte
|
||||
main_notebook_bad_extensions = Extensii rele
|
||||
main_tree_view_column_file_name = Numele fișierului
|
||||
main_tree_view_column_folder_name = Nume folder
|
||||
main_tree_view_column_path = Cale
|
||||
main_tree_view_column_modification = Data modificării
|
||||
main_tree_view_column_size = Dimensiune
|
||||
main_tree_view_column_similarity = Similaritate
|
||||
main_tree_view_column_dimensions = Dimensiuni
|
||||
main_tree_view_column_title = Titlu
|
||||
main_tree_view_column_artist = Artist
|
||||
main_tree_view_column_year = An
|
||||
main_tree_view_column_bitrate = Bitrate
|
||||
main_tree_view_column_length = Lungime
|
||||
main_tree_view_column_genre = Gen
|
||||
main_tree_view_column_symlink_file_name = Numele fișierului Symlink
|
||||
main_tree_view_column_symlink_folder = Dosar Symlink
|
||||
main_tree_view_column_destination_path = Calea destinației
|
||||
main_tree_view_column_type_of_error = Tip de eroare
|
||||
main_tree_view_column_current_extension = Extensia curentă
|
||||
main_tree_view_column_proper_extensions = Extensie corectă
|
||||
main_label_check_method = Metoda de verificare
|
||||
main_label_hash_type = Tip hash
|
||||
main_label_hash_size = Dimensiune hash
|
||||
main_label_size_bytes = Dimensiune (octeți)
|
||||
main_label_min_size = Minim
|
||||
main_label_max_size = Maxim
|
||||
main_label_shown_files = Numărul de fișiere afișate
|
||||
main_label_resize_algorithm = Redimensionare algoritm
|
||||
main_label_similarity = Similarity{ " " }
|
||||
main_check_box_broken_files_audio = Audio
|
||||
main_check_box_broken_files_pdf = Pdf
|
||||
main_check_box_broken_files_archive = Arhivează
|
||||
main_check_box_broken_files_image = Imagine
|
||||
check_button_general_same_size = Ignoră aceeași dimensiune
|
||||
check_button_general_same_size_tooltip = Ignoră fișierele cu rezultate de dimensiune identică - de obicei, acestea sunt de 1:1 duplicate
|
||||
main_label_size_bytes_tooltip = Dimensiunea fişierelor care vor fi utilizate în scanare
|
||||
# Upper window
|
||||
upper_tree_view_included_folder_column_title = Dosare de căutat
|
||||
upper_tree_view_included_reference_column_title = Dosare de referință
|
||||
upper_recursive_button = Recursiv
|
||||
upper_recursive_button_tooltip = Dacă este selectat, caută și fișiere care nu sunt plasate direct în dosarele alese.
|
||||
upper_manual_add_included_button = Adăugare manuală
|
||||
upper_add_included_button = Adăugare
|
||||
upper_remove_included_button = Elimină
|
||||
upper_manual_add_excluded_button = Adăugare manuală
|
||||
upper_add_excluded_button = Adăugare
|
||||
upper_remove_excluded_button = Elimină
|
||||
upper_manual_add_included_button_tooltip =
|
||||
Adăugați numele directorului pentru a căuta manual.
|
||||
|
||||
Pentru a adăuga căi multiple simultan, separați-le de ;
|
||||
|
||||
/home/roman;/home/rozkaz va adăuga două directoare /home/roman și /home/rozkaz
|
||||
upper_add_included_button_tooltip = Adăugați un nou director pentru căutare.
|
||||
upper_remove_included_button_tooltip = Ștergeți directorul de căutare.
|
||||
upper_manual_add_excluded_button_tooltip =
|
||||
Adaugă numele folderului exclus manual.
|
||||
|
||||
Pentru a adăuga căi multiple simultan, separați-le de ;
|
||||
|
||||
/home/roman;/home/krokiet va adăuga două directoare /home/roman și /home/keokiet
|
||||
upper_add_excluded_button_tooltip = Adauga directorul pentru a fi exclus in cautare.
|
||||
upper_remove_excluded_button_tooltip = Ştergeţi directorul din excludere.
|
||||
upper_notebook_items_configuration = Configurare articole
|
||||
upper_notebook_excluded_directories = Dosare excluse
|
||||
upper_notebook_included_directories = Dosare incluse
|
||||
upper_allowed_extensions_tooltip =
|
||||
Extensiile permise trebuie separate prin virgulă (implicit toate sunt disponibile).
|
||||
|
||||
Următoarele macro care adaugă simultan extensii multiple sunt de asemenea disponibile: IMAGE, VIDEO, MUSIC, TEXT.
|
||||
|
||||
Foloseste exemplul ".exe, IMAGE, VIDEO, .rar, 7z" - asta inseamna ca imaginile (e. . fișiere jpg, png), videoclipuri (de ex. avi, mp4), exe, rar și 7z vor fi scanate.
|
||||
upper_excluded_extensions_tooltip =
|
||||
Lista fişierelor dezactivate care vor fi ignorate în scanare.
|
||||
|
||||
La utilizarea extensiilor permise și dezactivate, aceasta are prioritate mai mare, deci fișierul nu va fi verificat.
|
||||
upper_excluded_items_tooltip =
|
||||
Elementele excluse trebuie sa contina * wildcard si sa fie separate prin virgule.
|
||||
Acest lucru este mai lent decat directoarele excluse, asa ca il folositi cu atentie.
|
||||
upper_excluded_items = Elemente excluse:
|
||||
upper_allowed_extensions = Extensii permise:
|
||||
upper_excluded_extensions = Extensii dezactivate:
|
||||
# Popovers
|
||||
popover_select_all = Selectează tot
|
||||
popover_unselect_all = Deselectează tot
|
||||
popover_reverse = Selectare inversă
|
||||
popover_select_all_except_oldest = Selectează toate cu excepția celor mai vechi
|
||||
popover_select_all_except_newest = Selectează toate cu excepția celor noi
|
||||
popover_select_one_oldest = Selectează unul mai vechi
|
||||
popover_select_one_newest = Selectaţi unul dintre cele mai noi
|
||||
popover_select_custom = Selectare particularizată
|
||||
popover_unselect_custom = Deselectare particularizată
|
||||
popover_select_all_images_except_biggest = Selectează toate cu excepția celui mai mare
|
||||
popover_select_all_images_except_smallest = Selectează toate cu excepția celor mici
|
||||
popover_custom_path_check_button_entry_tooltip =
|
||||
Selectaţi înregistrările după cale.
|
||||
|
||||
Exemplu de utilizare:
|
||||
/home/pimpek/rzecz.txt poate fi găsit cu /home/pim*
|
||||
popover_custom_name_check_button_entry_tooltip =
|
||||
Selectaţi înregistrările cu numele fişierelor.
|
||||
|
||||
Exemplu de utilizare:
|
||||
/usr/ping/pong.txt poate fi găsit cu *ong*
|
||||
popover_custom_regex_check_button_entry_tooltip =
|
||||
Selectaţi înregistrările specificate de Regex.
|
||||
|
||||
Cu acest mod, textul căutat este calea cu numele.
|
||||
|
||||
Exemplu de utilizare:
|
||||
/usr/bin/ziemniak. xt poate fi găsit cu /ziem[a-z]+
|
||||
|
||||
Acest lucru folosește implementările implicite Rust regex. Puteți citi mai multe despre ele aici: https://docs.rs/regex.
|
||||
popover_custom_case_sensitive_check_button_tooltip =
|
||||
Activează detectarea cazurilor sensibile.
|
||||
|
||||
Când este dezactivat /home/* găsește atât /HoMe/roman cât și /home/roman.
|
||||
popover_custom_not_all_check_button_tooltip =
|
||||
Previne selectarea tuturor înregistrărilor din grup.
|
||||
|
||||
Aceasta este activată în mod implicit, deoarece în majoritatea situațiilor, nu doriţi să ştergeţi atât fişierele originale, cât şi duplicate, dar doriţi să lăsaţi cel puţin un fişier.
|
||||
|
||||
ATENŢIE: Această setare nu funcţionează dacă aţi selectat deja manual toate rezultatele într-un grup.
|
||||
popover_custom_regex_path_label = Cale
|
||||
popover_custom_regex_name_label = Nume
|
||||
popover_custom_regex_regex_label = Cale Regex + Nume
|
||||
popover_custom_case_sensitive_check_button = Sensibil la caz
|
||||
popover_custom_all_in_group_label = Nu selectaţi toate înregistrările în grup
|
||||
popover_custom_mode_unselect = Deselectare particularizată
|
||||
popover_custom_mode_select = Selectare particularizată
|
||||
popover_sort_file_name = Nume fișier
|
||||
popover_sort_folder_name = Nume dosar
|
||||
popover_sort_full_name = Numele complet
|
||||
popover_sort_size = Dimensiune
|
||||
popover_sort_selection = Selecţie
|
||||
popover_invalid_regex = Regex nu este valid
|
||||
popover_valid_regex = Regex este valid
|
||||
# Bottom buttons
|
||||
bottom_search_button = Caută
|
||||
bottom_select_button = Selectare
|
||||
bottom_delete_button = Ștergere
|
||||
bottom_save_button = Salvează
|
||||
bottom_symlink_button = Symlink
|
||||
bottom_hardlink_button = Hardlink
|
||||
bottom_move_button = Mutare
|
||||
bottom_sort_button = Sortează
|
||||
bottom_search_button_tooltip = Începe căutarea
|
||||
bottom_select_button_tooltip = Selectaţi înregistrările. Numai fişierele/dosarele selectate pot fi procesate ulterior.
|
||||
bottom_delete_button_tooltip = Ştergeţi fişierele/dosarele selectate.
|
||||
bottom_save_button_tooltip = Salvează datele despre căutare în fișier
|
||||
bottom_symlink_button_tooltip =
|
||||
Creaţi link-uri simbolice.
|
||||
Funcţionează numai atunci când cel puţin două rezultate într-un grup sunt selectate.
|
||||
Prima este neschimbată, iar a doua și mai târziu simpatizează cu primul.
|
||||
bottom_hardlink_button_tooltip =
|
||||
Creează link-uri hardware.
|
||||
Funcţionează numai atunci când cel puţin două rezultate sunt selectate într-un grup.
|
||||
Prima este neschimbată, iar a doua și mai târziu sunt greu legate mai întâi.
|
||||
bottom_hardlink_button_not_available_tooltip =
|
||||
Creează link-uri hardware.
|
||||
Butonul este dezactivat, deoarece hardlink-urile nu pot fi create.
|
||||
Legăturile fizice funcționează doar cu privilegii de administrator pe Windows, așa că asigură-te că rulezi aplicația ca administrator.
|
||||
Dacă aplicația funcționează deja cu astfel de privilegii verificați pentru probleme similare pe Giwhere,
|
||||
bottom_move_button_tooltip =
|
||||
Mută fișierele în directorul ales.
|
||||
Copiază toate fișierele în director fără a păstra directorul arborescent.
|
||||
Când se încearcă mutarea a două fișiere cu nume identic în folder, al doilea va eșua și va afișa eroarea.
|
||||
bottom_sort_button_tooltip = Sortează fișierele/dosarele în funcție de metoda selectată.
|
||||
bottom_show_errors_tooltip = Arată/ascunde panoul de text de jos.
|
||||
bottom_show_upper_notebook_tooltip = Arată/Ascunde panoul de notebook-uri de sus.
|
||||
# Progress Window
|
||||
progress_stop_button = Oprește
|
||||
progress_stop_additional_message = Oprire solicitată
|
||||
# About Window
|
||||
about_repository_button_tooltip = Link către pagina de depozit cu codul sursă.
|
||||
about_donation_button_tooltip = Link la pagina de donare.
|
||||
about_instruction_button_tooltip = Link către pagina de instrucțiuni.
|
||||
about_translation_button_tooltip = Link catre pagina Crowdin cu traducerea aplicatiilor. Oficial, limba poloneza si engleza sunt suportate.
|
||||
about_repository_button = Depozit
|
||||
about_donation_button = Donație
|
||||
about_instruction_button = Instrucțiuni
|
||||
about_translation_button = Traducere
|
||||
# Header
|
||||
header_setting_button_tooltip = Deschide dialogul de setări.
|
||||
header_about_button_tooltip = Deschide dialogul cu informații despre aplicație.
|
||||
|
||||
# Settings
|
||||
|
||||
|
||||
## General
|
||||
|
||||
settings_number_of_threads = Numar discutii folosite
|
||||
settings_number_of_threads_tooltip = Numărul de teme folosite, 0 înseamnă că vor fi folosite toate temele disponibile.
|
||||
settings_label_restart = Trebuie să reporniți aplicația pentru a aplica setările!
|
||||
settings_ignore_other_filesystems = Ignorați alte sisteme de fișiere (doar Linux)
|
||||
settings_ignore_other_filesystems_tooltip =
|
||||
ignoră fişierele care nu se află în acelaşi sistem de fişiere ca şi directoarele căutate.
|
||||
|
||||
Funcţionează la fel ca opţiunea -xdev în găsirea comenzii în Linux
|
||||
settings_save_at_exit_button_tooltip = Salvați configurația în fișier la închiderea aplicației.
|
||||
settings_load_at_start_button_tooltip =
|
||||
Încarcă configurația din fișier la deschiderea aplicației.
|
||||
|
||||
Dacă nu este activată, se vor folosi setările implicite.
|
||||
settings_confirm_deletion_button_tooltip = Afișați caseta de confirmare când faceți clic pe butonul de ștergere.
|
||||
settings_confirm_link_button_tooltip = Afișați caseta de confirmare când faceți clic pe butonul hard/symlink.
|
||||
settings_confirm_group_deletion_button_tooltip = Arată dialogul de avertizare când se încearcă ștergerea tuturor înregistrărilor din grup.
|
||||
settings_show_text_view_button_tooltip = Arată panoul de text în partea de jos a interfeței utilizatorului.
|
||||
settings_use_cache_button_tooltip = Foloseşte cache-ul fişierelor.
|
||||
settings_save_also_as_json_button_tooltip = Salvează cache-ul în formatul JSON (citibil uman). Este posibil să îi modifici conținutul. Geocutia din acest fişier va fi citită automat de aplicaţie dacă nu există geocutie în format binar (cu extensie bin)
|
||||
settings_use_trash_button_tooltip = Mută fișierele la gunoi în loc să le ștergi definitiv.
|
||||
settings_language_label_tooltip = Limba interfeței utilizatorului.
|
||||
settings_save_at_exit_button = Salvați configurația la închiderea aplicației
|
||||
settings_load_at_start_button = Încarcă configurația la deschiderea aplicației
|
||||
settings_confirm_deletion_button = Arată dialog de confirmare la ștergerea oricăror fișiere
|
||||
settings_confirm_link_button = Arată dialog de confirmare atunci când fişierele hard/symlink
|
||||
settings_confirm_group_deletion_button = Arată dialog de confirmare la ștergerea tuturor fișierelor din grup
|
||||
settings_show_text_view_button = Arată panoul de text jos
|
||||
settings_use_cache_button = Utilizare geocutie
|
||||
settings_save_also_as_json_button = De asemenea, salvează cache-ul ca fișier JSON
|
||||
settings_use_trash_button = Mută fișierele șterse în gunoi
|
||||
settings_language_label = Limba
|
||||
settings_multiple_delete_outdated_cache_checkbutton = Şterge automat intrările învechite
|
||||
settings_multiple_delete_outdated_cache_checkbutton_tooltip =
|
||||
Ştergeţi rezultatele învechite ale geocutiei care indică fişierele inexistente.
|
||||
|
||||
Atunci când este activată, aplicația se asigură la încărcarea înregistrărilor, că toate înregistrările indică către fișiere valide (cele decongelate sunt ignorate).
|
||||
|
||||
Dezactivarea acestui lucru va ajuta la scanarea fişierelor pe unităţi externe, astfel încât intrările de cache despre acestea nu vor fi şterse în următoarea scanare.
|
||||
|
||||
În cazul în care există sute de mii de înregistrări în cache; se sugerează să activezi acest lucru, care va încărca/salva cache-ul la start/end al scanării.
|
||||
settings_notebook_general = Generalități
|
||||
settings_notebook_duplicates = Duplicate
|
||||
settings_notebook_images = Imagini similare
|
||||
settings_notebook_videos = Video similar
|
||||
|
||||
## Multiple - settings used in multiple tabs
|
||||
|
||||
settings_multiple_image_preview_checkbutton_tooltip = Afișează previzualizarea în partea dreaptă (când se selectează un fișier imagine).
|
||||
settings_multiple_image_preview_checkbutton = Arată previzualizarea imaginii
|
||||
settings_multiple_clear_cache_button_tooltip =
|
||||
Curăță manual cache-ul intrărilor învechite.
|
||||
Acest lucru ar trebui folosit doar dacă curățarea automată a fost dezactivată.
|
||||
settings_multiple_clear_cache_button = Elimină rezultatele învechite din geocutie.
|
||||
|
||||
## Duplicates
|
||||
|
||||
settings_duplicates_hide_hard_link_button_tooltip =
|
||||
Ascunde toate fişierele, cu excepţia unuia, dacă toate arată spre aceleaşi date (sunt conectate).
|
||||
|
||||
Exemplu: În cazul în care sunt (pe disc) şapte fişiere care sunt greu legate de date specifice şi un fişier diferit cu aceleaşi date, dar un alt inventar, apoi în duplicat va fi afișat un singur fișier unic și un fișier de la cele hardlink-ului.
|
||||
settings_duplicates_minimal_size_entry_tooltip =
|
||||
Setaţi dimensiunea minimă a fişierului care va fi memorată în cache.
|
||||
|
||||
Alegerea unei valori mai mici va genera mai multe înregistrări. (Automatic Translation) Aceasta va accelera căutarea, dar va încetini încărcarea/salvarea cache-ului.
|
||||
settings_duplicates_prehash_checkbutton_tooltip =
|
||||
Permite stocarea în cache a prehash (un hash calculat dintr-o mică parte a fișierului) care permite concedierea mai timpurie a rezultatelor nereplicate.
|
||||
|
||||
este dezactivat implicit deoarece poate cauza încetiniri în unele situații.
|
||||
|
||||
Este foarte recomandat sa il utilizezi cand scanezi sute de mii sau milioane de fisiere, pentru ca poate accelera cautarea de mai multe ori.
|
||||
settings_duplicates_prehash_minimal_entry_tooltip = Dimensiunea minimă a intrării în cache
|
||||
settings_duplicates_hide_hard_link_button = Ascunde link-urile hard (doar Linux și macOS)
|
||||
settings_duplicates_prehash_checkbutton = Foloseste cache-ul prehash
|
||||
settings_duplicates_minimal_size_cache_label = Dimensiunea minimă a fişierelor (în octeţi) salvate în cache
|
||||
settings_duplicates_minimal_size_cache_prehash_label = Dimensiunea minimă a fişierelor (în octeţi) salvate în cache de prehash
|
||||
|
||||
## Saving/Loading settings
|
||||
|
||||
settings_saving_button_tooltip = Salvați setările curente în fișier.
|
||||
settings_loading_button_tooltip = Încarcă setările din fișier și înlocuiește configurația curentă cu ele.
|
||||
settings_reset_button_tooltip = Resetați configurația curentă la cea implicită.
|
||||
settings_saving_button = Salvează configurația
|
||||
settings_loading_button = Încarcă configurația
|
||||
settings_reset_button = Resetare configurație
|
||||
|
||||
## Opening cache/config folders
|
||||
|
||||
settings_folder_cache_open_tooltip =
|
||||
Deschide folderul unde sunt stocate fișierele txt cache-ul.
|
||||
|
||||
Modificarea fișierelor de cache poate duce la afișarea unor rezultate invalide. Cu toate acestea, modificarea traiectoriei poate salva timpul atunci când mutați un număr mare de fișiere într-o locație diferită.
|
||||
|
||||
Puteţi copia aceste fişiere între computere pentru a salva timp la scanarea din nou pentru fişiere (desigur, dacă au o structură de directoare similară).
|
||||
|
||||
În caz de probleme cu geocutia, aceste fişiere pot fi şterse. Aplicaţia le va regenera automat.
|
||||
settings_folder_settings_open_tooltip =
|
||||
Deschide folderul unde este stocată configurația Czkawka.
|
||||
|
||||
AVERTISMENT: Modificarea manuală a configurației poate rupe fluxul de lucru.
|
||||
settings_folder_cache_open = Deschide dosarul cache
|
||||
settings_folder_settings_open = Deschide folderul de setări
|
||||
# Compute results
|
||||
compute_stopped_by_user = Căutarea a fost oprită de utilizator
|
||||
compute_found_duplicates_hash_size = Am găsit { $number_files } duplicate în { $number_groups } grupuri care au luat { $size }
|
||||
compute_found_duplicates_name = Am găsit { $number_files } duplicate în grupurile { $number_groups }
|
||||
compute_found_empty_folders = Foldere goale { $number_files }
|
||||
compute_found_empty_files = Fisiere goale gasite { $number_files }
|
||||
compute_found_big_files = Fisiere mari gasite { $number_files }
|
||||
compute_found_temporary_files = Fișiere temporare găsite { $number_files }
|
||||
compute_found_images = S-au găsit imagini similare { $number_files } în grupurile { $number_groups }
|
||||
compute_found_videos = S-au găsit videoclipuri similare { $number_files } în grupurile { $number_groups }
|
||||
compute_found_music = Am găsit { $number_files } fişiere muzicale similare în grupurile { $number_groups }
|
||||
compute_found_invalid_symlinks = { $number_files } link-uri simbolice invalide găsite
|
||||
compute_found_broken_files = Fișiere defecte { $number_files } găsite
|
||||
compute_found_bad_extensions = Fișiere { $number_files } cu extensii invalide
|
||||
# Progress window
|
||||
progress_scanning_general_file = Se scanează fişierul { $file_number }
|
||||
progress_scanning_extension_of_files = Se verifică extensia fișierului { $file_checked }/{ $all_files }
|
||||
progress_scanning_broken_files = Se verifică fişierul { $file_checked }/{ $all_files }
|
||||
progress_scanning_video = Hashing of { $file_checked }/{ $all_files } video
|
||||
progress_scanning_image = Hashing of { $file_checked }/{ $all_files } image
|
||||
progress_comparing_image_hashes = Comparare hash imagine { $file_checked }/{ $all_files }
|
||||
progress_scanning_music_tags_end = Compararea etichetelor fișierului de muzică { $file_checked }/{ $all_files }
|
||||
progress_scanning_music_tags = Citirea etichetelor din fişierul de muzică { $file_checked }/{ $all_files }
|
||||
progress_scanning_music_content_end = Compararea amprentelor fișierului de muzică { $file_checked }/{ $all_files }
|
||||
progress_scanning_music_content = Calcularea amprentei fişierului de muzică { $file_checked }/{ $all_files }
|
||||
progress_scanning_empty_folders = Se scanează directorul { $folder_number }
|
||||
progress_scanning_size = Dimensiune scanare fișier { $file_number }
|
||||
progress_scanning_size_name = Se scanează numele și dimensiunea fișierului { $file_number }
|
||||
progress_scanning_name = Se scanează numele fișierului { $file_number }
|
||||
progress_analyzed_partial_hash = S-a analizat hash-ul parțial al fișierelor { $file_checked }/{ $all_files }
|
||||
progress_analyzed_full_hash = A fost analizat hash complet al fişierelor { $file_checked }/{ $all_files }
|
||||
progress_prehash_cache_loading = Se încarcă cache-ul prehash
|
||||
progress_prehash_cache_saving = Salvare cache prehash
|
||||
progress_hash_cache_loading = Încărcare cache hash
|
||||
progress_hash_cache_saving = Salvare cache hash
|
||||
progress_cache_loading = Se încarcă geocutia
|
||||
progress_cache_saving = Salvare geocutie
|
||||
progress_current_stage = Current Stage:{ " " }
|
||||
progress_all_stages = All Stages:{ " " }
|
||||
# Saving loading
|
||||
saving_loading_saving_success = Configurație salvată în fișierul { $name }.
|
||||
saving_loading_saving_failure = Salvarea datelor de configurare în fișierul { $name } a eșuat.
|
||||
saving_loading_reset_configuration = Configurația curentă a fost ștearsă.
|
||||
saving_loading_loading_success = Configurare aplicație încărcată corespunzător.
|
||||
saving_loading_invalid_string = Pentru cheia "{ $key }" a găsit un rezultat nevalid - "{ $result }" care nu este un șir.
|
||||
saving_loading_invalid_int = Pentru cheia "{ $key }" a găsit un rezultat invalid - "{ $result }" care nu este un număr întreg.
|
||||
saving_loading_invalid_bool = Pentru cheia "{ $key }" a găsit rezultat nevalid - "{ $result }" care nu este un bool.
|
||||
saving_loading_decode_problem_bool = Nu s-a reușit decodificarea boolului de la tasta "{ $key }" găsit "{ $result }" dar valorile permise sunt 0, 1, adevărat sau false.
|
||||
saving_loading_saving_same_keys = Se încearcă salvarea setării cu cheie duplicată "{ $key }".
|
||||
saving_loading_failed_to_get_home_directory = Nu s-a putut obține directorul acasă pentru a deschide/salva fișierul de configurare.
|
||||
saving_loading_folder_config_instead_file = Nu se poate crea sau deschide fișierul de configurare în calea "{ $path }" deoarece există deja un dosar.
|
||||
saving_loading_failed_to_create_configuration_folder = Nu s-a reuşit configurarea pentru a crea folderul de configurare "{ $path }", motivul "{ $reason }".
|
||||
saving_loading_failed_to_create_config_file = Nu s-a putut crea fișierul de configurare "{ $path }", motivul "{ $reason }".
|
||||
saving_loading_failed_to_read_config_file = Nu se poate încărca configurația din "{ $path }" deoarece nu există sau nu este un fișier.
|
||||
saving_loading_failed_to_read_data_from_file = Datele din fişierul "{ $path }", motivul "{ $reason }".
|
||||
saving_loading_orphan_data = Am găsit date orfane "{ $data }" în rândul "{ $line }".
|
||||
saving_loading_not_valid = Setarea "{ $data }" nu există în versiunea curentă a aplicației.
|
||||
# Invalid symlinks
|
||||
invalid_symlink_infinite_recursion = Recepţie infinită
|
||||
invalid_symlink_non_existent_destination = Fișier destinație inexistent
|
||||
# Other
|
||||
selected_all_reference_folders = Nu se poate începe căutarea, atunci când toate directoarele sunt setate ca dosare de referință
|
||||
searching_for_data = Se caută date, poate dura ceva timp, vă rugăm așteptați...
|
||||
text_view_messages = MESAJE
|
||||
text_view_warnings = ATENȚIONĂRI
|
||||
text_view_errors = EROARE
|
||||
about_window_motto = Acest program este liber de utilizat și va fi întotdeauna.
|
||||
# Various dialog
|
||||
dialogs_ask_next_time = Întreabă data viitoare
|
||||
delete_file_failed = Nu s-a reușit ștergerea fișierului { $name }, motivul { $reason }
|
||||
delete_title_dialog = Ștergeți confirmarea
|
||||
delete_question_label = Sunteţi sigur că doriţi să ştergeţi fişierele?
|
||||
delete_all_files_in_group_title = Confirmarea ștergerii tuturor fișierelor din grup
|
||||
delete_all_files_in_group_label1 = In unele grupuri, toate inregistrarile sunt selectate.
|
||||
delete_all_files_in_group_label2 = Sunteţi sigur că doriţi să le ştergeţi?
|
||||
delete_folder_failed = Nu s-a reușit ștergerea dosarului { $dir } deoarece directorul nu există, nu aveți permisiunea sau folderul nu este gol.
|
||||
delete_items_label = { $items } fișiere vor fi șterse.
|
||||
delete_items_groups_label = { $items } fișiere din grupurile { $groups } vor fi șterse.
|
||||
hardlink_failed = Eșuare la hardlink
|
||||
hard_sym_invalid_selection_title_dialog = Selecţie invalidă cu unele grupuri
|
||||
hard_sym_invalid_selection_label_1 = În unele grupuri există doar o înregistrare selectată și va fi ignorată.
|
||||
hard_sym_invalid_selection_label_2 = Pentru a putea lega hard/sym aceste fișiere, cel puțin două rezultate în grup trebuie să fie selectate.
|
||||
hard_sym_invalid_selection_label_3 = Prima în grup este recunoscută ca fiind originală şi nu se modifică, dar se modifică a doua şi mai târziu.
|
||||
hard_sym_link_title_dialog = Confirmare link
|
||||
hard_sym_link_label = Sunteţi sigur că doriţi să conectaţi aceste fişiere?
|
||||
move_folder_failed = Nu s-a reușit mutarea dosarului { $name }, motivul { $reason }
|
||||
move_file_failed = Nu s-a reușit mutarea fișierului { $name }, motivul { $reason }
|
||||
move_files_title_dialog = Alegeți directorul în care doriți să mutați fișierele duplicate
|
||||
move_files_choose_more_than_1_path = Poate fi selectată doar o singură cale pentru a putea copia fişierele duplicate, selectate { $path_number }.
|
||||
move_stats = Elemente corect mutate { $num_files }/{ $all_files }
|
||||
save_results_to_file = Rezultate salvate atât pentru fişierele txt cât şi pentru fişierele json în directorul { $name }.
|
||||
search_not_choosing_any_music = EROARE: Trebuie să selectaţi cel puţin o casetă cu tipuri de căutare de muzică.
|
||||
search_not_choosing_any_broken_files = EROARE: Trebuie să selectaţi cel puţin o casetă de selectare cu tipul de fişiere bifate.
|
||||
include_folders_dialog_title = Dosare de inclus
|
||||
exclude_folders_dialog_title = Dosare de exclus
|
||||
include_manually_directories_dialog_title = Adaugă director manual
|
||||
cache_properly_cleared = Geocutie golită corect
|
||||
cache_clear_duplicates_title = Golire duplicate cache
|
||||
cache_clear_similar_images_title = Curăță cache imagini similare
|
||||
cache_clear_similar_videos_title = Curățare cache video similar
|
||||
cache_clear_message_label_1 = Vrei să ştergi memoria cache a intrărilor învechite?
|
||||
cache_clear_message_label_2 = Această operaţie va elimina toate intrările din cache-ul care indică fişiere invalide.
|
||||
cache_clear_message_label_3 = Aceasta poate încărca/salva uşor accelerat în cache.
|
||||
cache_clear_message_label_4 = AVERTISMENT: Operația va elimina toate datele stocate în cache din unplugged external drive. Deci fiecare hash va trebui să fie regenerat.
|
||||
# Show preview
|
||||
preview_image_resize_failure = Redimensionarea imaginii { $name } a eșuat.
|
||||
preview_image_opening_failure = Nu s-a reușit deschiderea imaginii { $name }, motivul { $reason }
|
||||
# Compare images (L is short Left, R is short Right - they can't take too much space)
|
||||
compare_groups_number = Grup { $current_group }/{ $all_groups } ({ $images_in_group } imagini)
|
||||
compare_move_left_button = l
|
||||
compare_move_right_button = R
|
@ -0,0 +1,500 @@
|
||||
# Window titles
|
||||
window_settings_title = Inställningar
|
||||
window_main_title = Czkawka (Hiccup)
|
||||
window_progress_title = Scannar
|
||||
window_compare_images = Jämför bilder
|
||||
# General
|
||||
general_ok_button = Ok
|
||||
general_close_button = Stäng
|
||||
# Main window
|
||||
music_title_checkbox = Titel
|
||||
music_artist_checkbox = Artist
|
||||
music_year_checkbox = År
|
||||
music_bitrate_checkbox = Bitrate
|
||||
music_genre_checkbox = Genre
|
||||
music_length_checkbox = Längd
|
||||
music_comparison_checkbox = Ungefärlig jämförelse
|
||||
music_checking_by_tags = Taggar
|
||||
music_checking_by_content = Innehåll
|
||||
same_music_seconds_label = Minsta fragment sekund varaktighet
|
||||
same_music_similarity_label = Maximal skillnad
|
||||
same_music_tooltip =
|
||||
Sökning efter liknande musikfiler genom dess innehåll kan konfigureras genom att ställa in:
|
||||
|
||||
- Minsta fragmenttid efter vilken musikfiler kan identifieras som liknande
|
||||
- Maximal skillnad mellan två testade fragment
|
||||
|
||||
Nyckeln till bra resultat är att hitta förnuftiga kombinationer av dessa parametrar, för tillhandahållen.
|
||||
|
||||
Att ställa in den minsta tiden till 5s och den maximala skillnaden till 1.0, kommer att leta efter nästan identiska fragment i filerna.
|
||||
En tid på 20-talet och en maximal skillnad på 6,0, å andra sidan, fungerar bra för att hitta remixer/live-versioner etc.
|
||||
|
||||
Som standard jämförs varje musikfil med varandra och detta kan ta mycket tid vid testning av många filer, så är det oftast bättre att använda referensmappar och ange vilka filer som ska jämföras med varandra(med samma mängd filer, Att jämföra fingeravtryck kommer att vara snabbare minst 4x än utan referensmappar).
|
||||
music_comparison_checkbox_tooltip =
|
||||
Den söker efter liknande musikfiler med AI, som använder maskininlärning för att ta bort parenteser från en fras. Till exempel, med detta alternativ aktiverat, filerna i fråga kommer att betraktas som dubbletter:
|
||||
|
||||
Świędziżłób --- Świędziżłób (Remix Lato 2021)
|
||||
duplicate_case_sensitive_name = Skiftlägeskänslig
|
||||
duplicate_case_sensitive_name_tooltip =
|
||||
När detta är aktiverat spelar gruppen bara in när de har exakt samma namn t.ex. Żołd <-> Żołd
|
||||
|
||||
Inaktivera sådana alternativ kommer gruppnamn utan att kontrollera om varje bokstav är samma storlek t.ex. żoŁD <-> Żołd
|
||||
duplicate_mode_size_name_combo_box = Storlek och namn
|
||||
duplicate_mode_name_combo_box = Namn
|
||||
duplicate_mode_size_combo_box = Storlek
|
||||
duplicate_mode_hash_combo_box = Hash
|
||||
duplicate_hash_type_tooltip =
|
||||
Czkawka erbjuder 3 typer av hash:
|
||||
|
||||
Blake3 - kryptografisk hash-funktion. Detta är standard eftersom det är mycket snabbt.
|
||||
|
||||
CRC32 - enkel hash-funktion. Detta bör vara snabbare än Blake3, men kan mycket sällan ha några kollisioner.
|
||||
|
||||
XXH3 - mycket lik i prestanda och hashkvalitet till Blake3 (men icke-kryptografisk). Så, sådana lägen kan lätt bytas ut.
|
||||
duplicate_check_method_tooltip =
|
||||
För tillfället erbjuder Czkawka tre typer av metoder för att hitta dubbletter av:
|
||||
|
||||
Namn - Hittar filer som har samma namn.
|
||||
|
||||
Storlek - Hittar filer som har samma storlek.
|
||||
|
||||
Hash - Hittar filer som har samma innehåll. Detta läge hashar filen och senare jämför denna hash för att hitta dubbletter. Detta läge är det säkraste sättet att hitta dubbletter. Appen använder starkt cache, så andra och ytterligare skanningar av samma data bör vara mycket snabbare än den första.
|
||||
image_hash_size_tooltip =
|
||||
Varje kontrollerad bild ger en speciell hash som kan jämföras med varandra, och en liten skillnad mellan dem innebär att dessa bilder är liknande.
|
||||
|
||||
8 hash storlek är ganska bra att hitta bilder som bara är lite liknande till originalet. Med en större uppsättning bilder (>1000), kommer detta att producera en stor mängd falska positiva, så jag rekommenderar att använda en större hash storlek i detta fall.
|
||||
|
||||
16 är standard hashstorlek vilket är en ganska bra kompromiss mellan att hitta även lite liknande bilder och att bara ha en liten mängd hashkollisioner.
|
||||
|
||||
32 och 64 hashen finner endast mycket liknande bilder, men bör ha nästan inga falska positiva (kanske förutom vissa bilder med alfa-kanal).
|
||||
image_resize_filter_tooltip =
|
||||
För att beräkna hash av bilden, måste biblioteket först ändra storlek på den.
|
||||
|
||||
Beroende på vald algoritm kommer den resulterande bilden som används för att beräkna hash att se lite annorlunda ut.
|
||||
|
||||
Den snabbaste algoritmen att använda, men också den som ger de sämsta resultaten, är nära! Det är aktiverat som standard, eftersom med 16x16 hash storlek lägre kvalitet är det inte riktigt synligt.
|
||||
|
||||
Med 8x8 hashstorlek rekommenderas att använda en annan algoritm än Närmaste för att få bättre grupper av bilder.
|
||||
image_hash_alg_tooltip =
|
||||
Användare kan välja mellan en av många algoritmer för att beräkna hash.
|
||||
|
||||
Var och en har både starka och svagare punkter och ger ibland bättre och ibland sämre resultat för olika bilder.
|
||||
|
||||
Så, för att bestämma den bästa för dig krävs manuell testning.
|
||||
big_files_mode_combobox_tooltip = Gör det möjligt att söka efter minsta/största filer
|
||||
big_files_mode_label = Markerade filer
|
||||
big_files_mode_smallest_combo_box = Den minsta
|
||||
big_files_mode_biggest_combo_box = Den största
|
||||
main_notebook_duplicates = Duplicera filer
|
||||
main_notebook_empty_directories = Tomma kataloger
|
||||
main_notebook_big_files = Stora filer
|
||||
main_notebook_empty_files = Tomma filer
|
||||
main_notebook_temporary = Tillfälliga filer
|
||||
main_notebook_similar_images = Liknande bilder
|
||||
main_notebook_similar_videos = Liknande videor
|
||||
main_notebook_same_music = Musik Duplicerar
|
||||
main_notebook_symlinks = Ogiltiga Symlinks
|
||||
main_notebook_broken_files = Trasiga filer
|
||||
main_notebook_bad_extensions = Dåliga tillägg
|
||||
main_tree_view_column_file_name = Filnamn
|
||||
main_tree_view_column_folder_name = Mappens namn
|
||||
main_tree_view_column_path = Sökväg
|
||||
main_tree_view_column_modification = Senast ändrad
|
||||
main_tree_view_column_size = Storlek
|
||||
main_tree_view_column_similarity = Likhet
|
||||
main_tree_view_column_dimensions = Dimensioner
|
||||
main_tree_view_column_title = Titel
|
||||
main_tree_view_column_artist = Artist
|
||||
main_tree_view_column_year = År
|
||||
main_tree_view_column_bitrate = Bitrate
|
||||
main_tree_view_column_length = Längd
|
||||
main_tree_view_column_genre = Genre
|
||||
main_tree_view_column_symlink_file_name = Symlink filnamn
|
||||
main_tree_view_column_symlink_folder = Symlink mapp
|
||||
main_tree_view_column_destination_path = Målsökvägen
|
||||
main_tree_view_column_type_of_error = Typ av fel
|
||||
main_tree_view_column_current_extension = Nuvarande tillägg
|
||||
main_tree_view_column_proper_extensions = Rätt tillägg
|
||||
main_label_check_method = Kontrollera metod
|
||||
main_label_hash_type = Hash typ
|
||||
main_label_hash_size = Hashstorlek
|
||||
main_label_size_bytes = Storlek (bytes)
|
||||
main_label_min_size = Min
|
||||
main_label_max_size = Max
|
||||
main_label_shown_files = Antal visade filer
|
||||
main_label_resize_algorithm = Ändra storlek på algoritm
|
||||
main_label_similarity = Similarity{ " " }
|
||||
main_check_box_broken_files_audio = Ljud
|
||||
main_check_box_broken_files_pdf = Pdf
|
||||
main_check_box_broken_files_archive = Arkiv
|
||||
main_check_box_broken_files_image = Bild
|
||||
check_button_general_same_size = Ignorera samma storlek
|
||||
check_button_general_same_size_tooltip = Ignorera filer med samma storlek i resultat - vanligtvis är dessa 1:1 dubbletter
|
||||
main_label_size_bytes_tooltip = Storlek på filer som kommer att användas vid skanning
|
||||
# Upper window
|
||||
upper_tree_view_included_folder_column_title = Mappar att söka
|
||||
upper_tree_view_included_reference_column_title = Referens mappar
|
||||
upper_recursive_button = Rekursiv
|
||||
upper_recursive_button_tooltip = Om vald, sök även efter filer som inte placeras direkt under valda mappar.
|
||||
upper_manual_add_included_button = Manuell Lägg till
|
||||
upper_add_included_button = Lägg till
|
||||
upper_remove_included_button = Ta bort
|
||||
upper_manual_add_excluded_button = Manuell Lägg till
|
||||
upper_add_excluded_button = Lägg till
|
||||
upper_remove_excluded_button = Ta bort
|
||||
upper_manual_add_included_button_tooltip =
|
||||
Lägg till katalognamn för att söka för hand.
|
||||
|
||||
För att lägga till flera sökvägar samtidigt, separera dem med ;
|
||||
|
||||
/home/roman;/home/rozkaz lägger till två kataloger /home/roman och /home/rozkaz
|
||||
upper_add_included_button_tooltip = Lägg till ny katalog att söka.
|
||||
upper_remove_included_button_tooltip = Ta bort katalog från sökning.
|
||||
upper_manual_add_excluded_button_tooltip =
|
||||
Lägg till exkluderat katalognamn för hand.
|
||||
|
||||
För att lägga till flera sökvägar samtidigt, separera dem med ;
|
||||
|
||||
/home/roman;/home/krokiet kommer att lägga till två kataloger /home/roman och /home/keokiet
|
||||
upper_add_excluded_button_tooltip = Lägg till katalog som ska exkluderas i sökningen.
|
||||
upper_remove_excluded_button_tooltip = Ta bort katalog från utesluten.
|
||||
upper_notebook_items_configuration = Objekt konfiguration
|
||||
upper_notebook_excluded_directories = Uteslutna kataloger
|
||||
upper_notebook_included_directories = Inkluderade kataloger
|
||||
upper_allowed_extensions_tooltip =
|
||||
Tillåtna tillägg måste separeras med kommatecken (som standard alla är tillgängliga).
|
||||
|
||||
Följande makron som lägger till flera tillägg samtidigt, finns också: IMAGE, VIDEO, MUSIC, TEXT.
|
||||
|
||||
Användningsexempel ".exe, IMAGE, VIDEO, .rar, 7z" - det betyder att bilder (e. . jpg, png), videor (t.ex. avi, mp4), exe, rar, och 7z filer kommer att skannas.
|
||||
upper_excluded_extensions_tooltip =
|
||||
Lista över inaktiverade filer som kommer att ignoreras i skanning.
|
||||
|
||||
Vid användning av både tillåtna och inaktiverade tillägg har denna högre prioritet, så filen kommer inte att kontrolleras.
|
||||
upper_excluded_items_tooltip =
|
||||
Exkluderade artiklar måste innehålla * jokertecken och bör separeras med kommatecken.
|
||||
Detta är långsammare än uteslutna kataloger, så använd det noggrant.
|
||||
upper_excluded_items = Exkluderade objekt:
|
||||
upper_allowed_extensions = Tillåtna tillägg:
|
||||
upper_excluded_extensions = Inaktiverade tillägg:
|
||||
# Popovers
|
||||
popover_select_all = Radera
|
||||
popover_unselect_all = Avmarkera alla
|
||||
popover_reverse = Omvänd markering
|
||||
popover_select_all_except_oldest = Välj alla utom äldsta
|
||||
popover_select_all_except_newest = Välj alla utom nyaste
|
||||
popover_select_one_oldest = Välj en äldsta
|
||||
popover_select_one_newest = Välj en nyaste
|
||||
popover_select_custom = Välj anpassad
|
||||
popover_unselect_custom = Avmarkera anpassade
|
||||
popover_select_all_images_except_biggest = Välj alla utom största
|
||||
popover_select_all_images_except_smallest = Välj alla utom minsta
|
||||
popover_custom_path_check_button_entry_tooltip =
|
||||
Välj poster efter sökväg.
|
||||
|
||||
Exempel användning:
|
||||
/home/pimpek/rzecz.txt hittas med /home/pim*
|
||||
popover_custom_name_check_button_entry_tooltip =
|
||||
Välj poster efter filnamn.
|
||||
|
||||
Exempel användning:
|
||||
/usr/ping/pong.txt finns med *ong*
|
||||
popover_custom_regex_check_button_entry_tooltip =
|
||||
Välj poster efter specificerad Regex.
|
||||
|
||||
Med detta läge är sökord sökväg med namn.
|
||||
|
||||
Exempel användning:
|
||||
/usr/bin/ziemniak. xt kan hittas med /ziem[a-z]+
|
||||
|
||||
Detta använder Rust regex-implementationen. Du kan läsa mer om det här: https://docs.rs/regex.
|
||||
popover_custom_case_sensitive_check_button_tooltip =
|
||||
Aktiverar skiftlägeskänslig detektion.
|
||||
|
||||
När du inaktiverat /home/* hittar du både /HoMe/roman och /home/roman.
|
||||
popover_custom_not_all_check_button_tooltip =
|
||||
Förhindrar att alla poster väljs i grupp.
|
||||
|
||||
Detta är aktiverat som standard, eftersom i de flesta situationer, du inte vill ta bort både original och dubbletter filer, men vill lämna minst en fil.
|
||||
|
||||
VARNING: Den här inställningen fungerar inte om du redan manuellt har valt alla resultat i en grupp.
|
||||
popover_custom_regex_path_label = Sökväg
|
||||
popover_custom_regex_name_label = Namn
|
||||
popover_custom_regex_regex_label = Regex sökväg + namn
|
||||
popover_custom_case_sensitive_check_button = Skiftlägeskänslighet
|
||||
popover_custom_all_in_group_label = Välj inte alla poster i gruppen
|
||||
popover_custom_mode_unselect = Avmarkera anpassad
|
||||
popover_custom_mode_select = Välj anpassad
|
||||
popover_sort_file_name = Filnamn
|
||||
popover_sort_folder_name = Mapp namn
|
||||
popover_sort_full_name = Fullständigt namn
|
||||
popover_sort_size = Storlek
|
||||
popover_sort_selection = Markerat
|
||||
popover_invalid_regex = Regex är ogiltigt
|
||||
popover_valid_regex = Regex är giltigt
|
||||
# Bottom buttons
|
||||
bottom_search_button = Sökning
|
||||
bottom_select_button = Välj
|
||||
bottom_delete_button = Radera
|
||||
bottom_save_button = Save
|
||||
bottom_symlink_button = Symlink
|
||||
bottom_hardlink_button = Hardlink
|
||||
bottom_move_button = Flytta
|
||||
bottom_sort_button = Sortera
|
||||
bottom_search_button_tooltip = Starta sökning
|
||||
bottom_select_button_tooltip = Välj poster. Endast valda filer/mappar kan senare bearbetas.
|
||||
bottom_delete_button_tooltip = Ta bort markerade filer/mappar.
|
||||
bottom_save_button_tooltip = Spara data om sökning till fil
|
||||
bottom_symlink_button_tooltip =
|
||||
Skapa symboliska länkar.
|
||||
Fungerar endast när minst två resultat i en grupp väljs.
|
||||
Först är oförändrad och andra och senare är symanknutna till först.
|
||||
bottom_hardlink_button_tooltip =
|
||||
Skapa hardlinks.
|
||||
Fungerar endast när minst två resultat i en grupp är valda.
|
||||
Först är oförändrad och andra och senare är hårt länkade till först.
|
||||
bottom_hardlink_button_not_available_tooltip =
|
||||
Skapa hardlinks.
|
||||
Knappen är inaktiverad, eftersom hardlinks inte kan skapas.
|
||||
Hårdlänkar fungerar bara med administratörsrättigheter i Windows, så se till att köra appen som administratör.
|
||||
Om appen redan fungerar med sådana rättigheter kontrollera liknande problem på Github.
|
||||
bottom_move_button_tooltip =
|
||||
Flyttar filer till vald katalog.
|
||||
Det kopierar alla filer till katalogen utan att bevara katalogträdet.
|
||||
När du försöker flytta två filer med identiskt namn till mappen kommer det andra att misslyckas och visa fel.
|
||||
bottom_sort_button_tooltip = Sortera filer/mappar enligt vald metod.
|
||||
bottom_show_errors_tooltip = Visa/Dölj undertextpanelen.
|
||||
bottom_show_upper_notebook_tooltip = Visa/Dölj övre anteckningsbokspanelen.
|
||||
# Progress Window
|
||||
progress_stop_button = Stoppa
|
||||
progress_stop_additional_message = Stoppa begärd
|
||||
# About Window
|
||||
about_repository_button_tooltip = Länk till utvecklingskatalogen med källkod.
|
||||
about_donation_button_tooltip = Länk till donationssidan.
|
||||
about_instruction_button_tooltip = Länk till instruktionssidan.
|
||||
about_translation_button_tooltip = Länk till Crowdin sida med appöversättningar. Officiellt stöds polska och engelska.
|
||||
about_repository_button = Filförråd
|
||||
about_donation_button = Donationer
|
||||
about_instruction_button = Instruktion
|
||||
about_translation_button = Översättning
|
||||
# Header
|
||||
header_setting_button_tooltip = Öppnar dialogrutan för inställningar.
|
||||
header_about_button_tooltip = Öppnar dialog med info om app.
|
||||
|
||||
# Settings
|
||||
|
||||
|
||||
## General
|
||||
|
||||
settings_number_of_threads = Antal använda trådar
|
||||
settings_number_of_threads_tooltip = Antal gängor, 0 betyder att alla gängor kommer att användas.
|
||||
settings_label_restart = Du måste starta om appen för att tillämpa inställningar!
|
||||
settings_ignore_other_filesystems = Ignorera andra filsystem (endast Linux)
|
||||
settings_ignore_other_filesystems_tooltip =
|
||||
ignorerar filer som inte finns i samma filsystem som sökta kataloger.
|
||||
|
||||
Fungerar samma som -xdev alternativ för att hitta kommandot på Linux
|
||||
settings_save_at_exit_button_tooltip = Spara konfigurationen till fil när appen stängs.
|
||||
settings_load_at_start_button_tooltip =
|
||||
Ladda konfigurationen från filen när appen öppnas.
|
||||
|
||||
Om den inte är aktiverad kommer standardinställningarna att användas.
|
||||
settings_confirm_deletion_button_tooltip = Visa bekräftelsedialog när du klickar på knappen ta bort.
|
||||
settings_confirm_link_button_tooltip = Visa bekräftelsedialog när du klickar på den hårda/symboliska länkknappen.
|
||||
settings_confirm_group_deletion_button_tooltip = Visa varningsdialog när du försöker ta bort alla poster från gruppen.
|
||||
settings_show_text_view_button_tooltip = Visa textpanelen längst ner i användargränssnittet.
|
||||
settings_use_cache_button_tooltip = Använd filcache.
|
||||
settings_save_also_as_json_button_tooltip = Spara cache till (läsbar) JSON-format. Det är möjligt att ändra dess innehåll. Cache från denna fil kommer att läsas automatiskt av appen om binärt format cache (med bin extension) saknas.
|
||||
settings_use_trash_button_tooltip = Flyttar filer till papperskorgen istället ta bort dem permanent.
|
||||
settings_language_label_tooltip = Språk för användargränssnitt.
|
||||
settings_save_at_exit_button = Spara konfiguration när appen stängs
|
||||
settings_load_at_start_button = Ladda konfiguration när appen öppnas
|
||||
settings_confirm_deletion_button = Visa bekräftelsedialog vid borttagning av filer
|
||||
settings_confirm_link_button = Visa bekräftelsedialog när hårda/symboliska länkar filer
|
||||
settings_confirm_group_deletion_button = Visa bekräftelsedialog när alla filer tas bort i grupp
|
||||
settings_show_text_view_button = Visa längst ned textpanel
|
||||
settings_use_cache_button = Använd cache
|
||||
settings_save_also_as_json_button = Spara även cache som JSON-fil
|
||||
settings_use_trash_button = Flytta raderade filer till papperskorgen
|
||||
settings_language_label = Language
|
||||
settings_multiple_delete_outdated_cache_checkbutton = Ta bort föråldrade cache-poster automatiskt
|
||||
settings_multiple_delete_outdated_cache_checkbutton_tooltip =
|
||||
Ta bort föråldrade cacheresultat som pekar på obefintliga filer.
|
||||
|
||||
När den är aktiverad, se till att appen när du laddar poster, att alla poster pekar på giltiga filer (trasiga dem ignoreras).
|
||||
|
||||
Att inaktivera detta kommer att hjälpa när du skannar filer på externa enheter, så cacheposter om dem kommer inte att rensas i nästa skanning.
|
||||
|
||||
När det gäller att ha hundratusentals poster i cache, det föreslås för att aktivera detta, vilket kommer att påskynda cache-inläsning/spara vid start/slut av sökningen.
|
||||
settings_notebook_general = Info
|
||||
settings_notebook_duplicates = Dubbletter
|
||||
settings_notebook_images = Liknande bilder
|
||||
settings_notebook_videos = Liknande video
|
||||
|
||||
## Multiple - settings used in multiple tabs
|
||||
|
||||
settings_multiple_image_preview_checkbutton_tooltip = Visar förhandsgranskning på höger sida (vid val av bildfil).
|
||||
settings_multiple_image_preview_checkbutton = Visa förhandsgranskning av bild
|
||||
settings_multiple_clear_cache_button_tooltip =
|
||||
Rensa cache manuellt för föråldrade poster.
|
||||
Detta bör endast användas om automatisk rensning har inaktiverats.
|
||||
settings_multiple_clear_cache_button = Ta bort föråldrade resultat från cachen.
|
||||
|
||||
## Duplicates
|
||||
|
||||
settings_duplicates_hide_hard_link_button_tooltip =
|
||||
Döljer alla filer utom en, om alla pekar på samma data (är hardlinked).
|
||||
|
||||
Exempel: I det fall där det finns (på disk) sju filer som är hårdkopplade till specifika data och en annan fil med samma data men ett annat inode, i dubblettsökare, kommer endast en unik fil och en fil från hårdlänkade att visas.
|
||||
settings_duplicates_minimal_size_entry_tooltip =
|
||||
Ange minimal filstorlek som kommer att cachelagras.
|
||||
|
||||
Att välja ett mindre värde kommer att generera fler poster. Detta kommer att snabba upp sökningen, men bromsa cache-laddning/spara.
|
||||
settings_duplicates_prehash_checkbutton_tooltip =
|
||||
Aktiverar cachelagring av prehash (en hash beräknad från en liten del av filen) vilket tillåter tidigare avfärdande av icke-duplicerade resultat.
|
||||
|
||||
Det är inaktiverat som standard eftersom det kan orsaka nedgångar i vissa situationer.
|
||||
|
||||
Det rekommenderas starkt att använda det när du skannar hundratusentals eller miljoner filer, eftersom det kan påskynda sökningen flera gånger.
|
||||
settings_duplicates_prehash_minimal_entry_tooltip = Minimal storlek på cachad post.
|
||||
settings_duplicates_hide_hard_link_button = Dölj hårda länkar (endast Linux och macOS)
|
||||
settings_duplicates_prehash_checkbutton = Använd prehash cache
|
||||
settings_duplicates_minimal_size_cache_label = Minimal storlek på filer (i bytes) sparade i cache
|
||||
settings_duplicates_minimal_size_cache_prehash_label = Minimal storlek på filer (i bytes) sparade för att kunna använda cache
|
||||
|
||||
## Saving/Loading settings
|
||||
|
||||
settings_saving_button_tooltip = Spara konfigurationen för nuvarande inställningar till filen.
|
||||
settings_loading_button_tooltip = Ladda inställningar från fil och ersätta den aktuella konfigurationen med dem.
|
||||
settings_reset_button_tooltip = Återställ den aktuella konfigurationen till standardkonfigurationen.
|
||||
settings_saving_button = Spara konfiguration
|
||||
settings_loading_button = Ladda konfiguration
|
||||
settings_reset_button = Återställ konfiguration
|
||||
|
||||
## Opening cache/config folders
|
||||
|
||||
settings_folder_cache_open_tooltip =
|
||||
Öppnar mappen där cache-txt-filer lagras.
|
||||
|
||||
Ändring av cache-filer kan leda till att ogiltiga resultat visas. Dock kan ändra sökvägen spara tid när du flyttar en stor mängd filer till en annan plats.
|
||||
|
||||
Du kan kopiera dessa filer mellan datorer för att spara tid på skanning igen för filer (naturligtvis om de har liknande katalogstruktur).
|
||||
|
||||
Vid problem med cachen kan dessa filer tas bort. Appen kommer automatiskt att regenerera dem.
|
||||
settings_folder_settings_open_tooltip =
|
||||
Öppnar mappen där Czkawka-konfigurationen lagras.
|
||||
|
||||
VARNING: Manuellt modifierande av konfigurationen kan bryta ditt arbetsflöde.
|
||||
settings_folder_cache_open = Öppna cachemapp
|
||||
settings_folder_settings_open = Öppna inställningsmapp
|
||||
# Compute results
|
||||
compute_stopped_by_user = Sökandet stoppades av användaren
|
||||
compute_found_duplicates_hash_size = Hittade { $number_files } dubbletter i { $number_groups } grupper som tog { $size }
|
||||
compute_found_duplicates_name = Hittade { $number_files } dubbletter i { $number_groups } grupper
|
||||
compute_found_empty_folders = Hittade { $number_files } tomma mappar
|
||||
compute_found_empty_files = Hittades { $number_files } tomma filer
|
||||
compute_found_big_files = Hittade { $number_files } stora filer
|
||||
compute_found_temporary_files = Hittade { $number_files } tillfälliga filer
|
||||
compute_found_images = Hittade { $number_files } liknande bilder i { $number_groups } grupper
|
||||
compute_found_videos = Hittade { $number_files } liknande videoklipp i { $number_groups } grupper
|
||||
compute_found_music = Hittade { $number_files } liknande musik filer i { $number_groups } grupper
|
||||
compute_found_invalid_symlinks = Hittade { $number_files } ogiltiga symboliska länkar
|
||||
compute_found_broken_files = Hittades { $number_files } trasiga filer
|
||||
compute_found_bad_extensions = Hittades { $number_files } filer med ogiltiga tillägg
|
||||
# Progress window
|
||||
progress_scanning_general_file = Scanning { $file_number } fil
|
||||
progress_scanning_extension_of_files = Kontrollerar tillägg till { $file_checked }/{ $all_files } fil
|
||||
progress_scanning_broken_files = Kontrollerar { $file_checked }/{ $all_files } fil
|
||||
progress_scanning_video = Hashning av { $file_checked }/{ $all_files } video
|
||||
progress_scanning_image = Hashning av { $file_checked }/{ $all_files } bild
|
||||
progress_comparing_image_hashes = Jämföra { $file_checked }/{ $all_files } bildhash
|
||||
progress_scanning_music_tags_end = Jämföra taggar för { $file_checked }/{ $all_files } musikfil
|
||||
progress_scanning_music_tags = Lästaggar för { $file_checked }/{ $all_files } musikfil
|
||||
progress_scanning_music_content_end = Jämföra fingeravtryck av { $file_checked }/{ $all_files } musikfil
|
||||
progress_scanning_music_content = Beräknar fingeravtryck av { $file_checked }/{ $all_files } musikfil
|
||||
progress_scanning_empty_folders = Skannar { $folder_number } mappen
|
||||
progress_scanning_size = Skannar storleken på { $file_number } fil
|
||||
progress_scanning_size_name = Skannar namn och storlek på { $file_number } fil
|
||||
progress_scanning_name = Skannar namn på { $file_number } fil
|
||||
progress_analyzed_partial_hash = Analyserade partiella hash av { $file_checked }/{ $all_files } filer
|
||||
progress_analyzed_full_hash = Analyserad full hash av { $file_checked }/{ $all_files } filer
|
||||
progress_prehash_cache_loading = Laddar prehash cache
|
||||
progress_prehash_cache_saving = Sparar Omfattande cache
|
||||
progress_hash_cache_loading = Laddar hash-cache
|
||||
progress_hash_cache_saving = Sparar hash-cache
|
||||
progress_cache_loading = Laddar cache
|
||||
progress_cache_saving = Sparar cache
|
||||
progress_current_stage = Nuvarande steg:{ " " }
|
||||
progress_all_stages = Alla etapper:{ " " }
|
||||
# Saving loading
|
||||
saving_loading_saving_success = Sparad konfiguration till filen { $name }.
|
||||
saving_loading_saving_failure = Det gick inte att spara konfigurationsdata till filen { $name }.
|
||||
saving_loading_reset_configuration = Aktuell konfiguration har rensats.
|
||||
saving_loading_loading_success = Korrekt laddad app-konfiguration.
|
||||
saving_loading_invalid_string = För nyckel "{ $key }" hittade ogiltigt resultat - "{ $result }" vilket inte är en sträng.
|
||||
saving_loading_invalid_int = För nyckeln "{ $key }" hittade ogiltigt resultat - "{ $result }" vilket inte är ett heltal.
|
||||
saving_loading_invalid_bool = För nyckel "{ $key }" hittade ogiltigt resultat - "{ $result }" vilket inte är en bool.
|
||||
saving_loading_decode_problem_bool = Det gick inte att avkoda Bollen från nyckel "{ $key }" hittade "{ $result }" men tillåtna värden är 0, 1, sanna eller falska.
|
||||
saving_loading_saving_same_keys = Försöker spara inställningen med duplicerad nyckel "{ $key }".
|
||||
saving_loading_failed_to_get_home_directory = Det gick inte att hämta hemkatalogen till att öppna/spara konfigurationsfil.
|
||||
saving_loading_folder_config_instead_file = Kan inte skapa eller öppna spara konfigurationsfilen i sökvägen "{ $path }" eftersom det redan finns en mapp.
|
||||
saving_loading_failed_to_create_configuration_folder = Det gick inte att skapa konfigurationsmappen "{ $path }", orsak "{ $reason }".
|
||||
saving_loading_failed_to_create_config_file = Det gick inte att skapa konfigurationsfil "{ $path }", orsak "{ $reason }".
|
||||
saving_loading_failed_to_read_config_file = Kan inte ladda konfiguration från "{ $path }" eftersom den inte finns eller inte är en fil.
|
||||
saving_loading_failed_to_read_data_from_file = Kan inte läsa data från fil "{ $path }", anledning "{ $reason }".
|
||||
saving_loading_orphan_data = Hittade föräldralösa data "{ $data }" i rad "{ $line }".
|
||||
saving_loading_not_valid = Inställningen "{ $data }" finns inte i nuvarande appversion.
|
||||
# Invalid symlinks
|
||||
invalid_symlink_infinite_recursion = Oändlig recursion
|
||||
invalid_symlink_non_existent_destination = Icke-existerande målfil
|
||||
# Other
|
||||
selected_all_reference_folders = Kan inte börja söka, när alla kataloger är inställda som referensmappar
|
||||
searching_for_data = Söker data, det kan ta en stund, vänta...
|
||||
text_view_messages = MEDDELANDEN
|
||||
text_view_warnings = VARNINGAR
|
||||
text_view_errors = FEL
|
||||
about_window_motto = Detta program är gratis att använda och kommer alltid att vara.
|
||||
# Various dialog
|
||||
dialogs_ask_next_time = Fråga nästa gång
|
||||
delete_file_failed = Det gick inte att ta bort filen { $name } varför { $reason }
|
||||
delete_title_dialog = Ta bort bekräftelse
|
||||
delete_question_label = Är du säker på att du vill ta bort filer?
|
||||
delete_all_files_in_group_title = Bekräftelse av att ta bort alla filer i grupp
|
||||
delete_all_files_in_group_label1 = I vissa grupper är alla poster valda.
|
||||
delete_all_files_in_group_label2 = Är du säker på att du vill radera dem?
|
||||
delete_folder_failed = Det gick inte att ta bort mappen { $dir } eftersom mappen inte existerar, du har inte behörighet eller mappen är inte tom.
|
||||
delete_items_label = { $items } filer kommer att tas bort.
|
||||
delete_items_groups_label = { $items } filer från { $groups } grupper kommer att raderas.
|
||||
hardlink_failed = Det gick inte att hardlink
|
||||
hard_sym_invalid_selection_title_dialog = Ogiltigt val med vissa grupper
|
||||
hard_sym_invalid_selection_label_1 = I vissa grupper finns det bara en post vald och den kommer att ignoreras.
|
||||
hard_sym_invalid_selection_label_2 = För att kunna länka dessa filer måste minst två resultat i gruppen väljas.
|
||||
hard_sym_invalid_selection_label_3 = Först i grupp känns igen som original och ändras inte, men andra och senare ändras.
|
||||
hard_sym_link_title_dialog = Länkbekräftelse
|
||||
hard_sym_link_label = Är du säker på att du vill länka dessa filer?
|
||||
move_folder_failed = Det gick inte att flytta mappen { $name } anledning { $reason }
|
||||
move_file_failed = Det gick inte att flytta filen { $name } anledning { $reason }
|
||||
move_files_title_dialog = Välj mapp som du vill flytta duplicerade filer till
|
||||
move_files_choose_more_than_1_path = Endast en sökväg kan väljas för att kunna kopiera sina duplicerade filer, valda { $path_number }.
|
||||
move_stats = Korrekt flyttad { $num_files }/{ $all_files } objekt
|
||||
save_results_to_file = Sparade resultat både till txt och json filer i { $name } mapp.
|
||||
search_not_choosing_any_music = FEL: Du måste välja minst en kryssruta med söktyper för musik.
|
||||
search_not_choosing_any_broken_files = FEL: Du måste välja minst en kryssruta med typ av markerade trasiga filer.
|
||||
include_folders_dialog_title = Mappar att inkludera
|
||||
exclude_folders_dialog_title = Mappar att exkludera
|
||||
include_manually_directories_dialog_title = Lägg till katalog manuellt
|
||||
cache_properly_cleared = Rensad cache
|
||||
cache_clear_duplicates_title = Rensar dubbletter cache
|
||||
cache_clear_similar_images_title = Rensar liknande bildcache
|
||||
cache_clear_similar_videos_title = Rensar liknande videoklipp cache
|
||||
cache_clear_message_label_1 = Vill du rensa cachen för föråldrade inlägg?
|
||||
cache_clear_message_label_2 = Denna åtgärd kommer att ta bort alla cache-poster som pekar på ogiltiga filer.
|
||||
cache_clear_message_label_3 = Detta kan något speedup ladda/spara till cache.
|
||||
cache_clear_message_label_4 = VARNING: Åtgärden kommer att ta bort alla cachade data från frånkopplade externa enheter. Så varje hash kommer att behöva regenereras.
|
||||
# Show preview
|
||||
preview_image_resize_failure = Kunde inte ändra storlek på bild { $name }.
|
||||
preview_image_opening_failure = Det gick inte att öppna bilden { $name } skäl { $reason }
|
||||
# Compare images (L is short Left, R is short Right - they can't take too much space)
|
||||
compare_groups_number = Grupp { $current_group }/{ $all_groups } ({ $images_in_group } bilder)
|
||||
compare_move_left_button = L
|
||||
compare_move_right_button = R
|
@ -0,0 +1 @@
|
||||
<svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><circle cx="255.998" cy="255.998" fill="#008000" r="245.419"/><path d="m256.001 512c-141.16 0-256.001-114.841-256.001-256.001 0-141.158 114.841-255.999 256.001-255.999s255.999 114.841 255.999 255.999c0 141.16-114.841 256.001-255.999 256.001zm0-490.842c-129.493 0-234.843 105.35-234.843 234.841 0 129.493 105.35 234.841 234.843 234.841s234.841-105.35 234.841-234.841-105.35-234.841-234.841-234.841z"/><g fill="#f2f2f2"><path d="m93.920837 228.48424h327.86569v55.947498h-327.86569z"/><path d="m94.802574-283.03333h327.86569v55.947498h-327.86569z" transform="rotate(90)"/></g></svg>
|
After Width: | Height: | Size: 677 B |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 5.6 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue