-
Notifications
You must be signed in to change notification settings - Fork 5
Feat/add dolphin file system extension #412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6d2babd
30f0731
b357477
19523b2
2aea788
63326dc
8905df4
84a2cdd
1b17de5
836ee7b
3f0032a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| name: File Manager Extension Smoke | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened] | ||
|
|
||
| jobs: | ||
| smoke-file-manager-extension: | ||
| name: "🧪 Smoke ${{ matrix.fileManager }} extension" | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| fileManager: [nautilus, nemo, dolphin] | ||
|
|
||
| container: | ||
| image: ubuntu:22.04 | ||
|
|
||
| steps: | ||
| - name: Install base dependencies | ||
| run: | | ||
| apt-get update | ||
| DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates curl git python3 unzip xdg-utils | ||
|
|
||
| - name: Check out Git repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Use Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version-file: .nvmrc | ||
| cache: npm | ||
|
|
||
| - name: Install file manager for matrix target | ||
| run: | | ||
| case "${{ matrix.fileManager }}" in | ||
| nautilus) | ||
| DEBIAN_FRONTEND=noninteractive apt-get install -y nautilus | ||
| ;; | ||
| nemo) | ||
| DEBIAN_FRONTEND=noninteractive apt-get install -y nemo | ||
| ;; | ||
| dolphin) | ||
| DEBIAN_FRONTEND=noninteractive apt-get install -y dolphin | ||
| ;; | ||
| *) | ||
| echo "Unsupported file manager: ${{ matrix.fileManager }}" | ||
| exit 1 | ||
| ;; | ||
| esac | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: Ensure Electron install | ||
| run: node ./.erb/scripts/ensure-electron-install.cjs | ||
|
|
||
| - name: Run extension smoke test | ||
| env: | ||
| EXPECTED_FILE_MANAGER: ${{ matrix.fileManager }} | ||
| HOME: ${{ github.workspace }}/.tmp/internxt-home | ||
| run: | | ||
| mkdir -p "$HOME" | ||
| npm run smoke:file-manager-extension |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| set -u | ||
|
|
||
| BASE_URL="http://localhost:4567/hydration" | ||
| ROOT_FOLDER="$HOME/Internxt Drive" | ||
|
|
||
| function encode_relative_path() { | ||
| python3 - "$1" "$ROOT_FOLDER" <<'PY' | ||
| import base64 | ||
| import os | ||
| import sys | ||
|
|
||
| file_path = os.path.realpath(sys.argv[1]) | ||
| root_folder = os.path.realpath(sys.argv[2]) | ||
|
|
||
| if not file_path.startswith(root_folder): | ||
| print("") | ||
| sys.exit(0) | ||
|
|
||
| relative_path = file_path[len(root_folder):] | ||
| if relative_path == "": | ||
| relative_path = "/" | ||
|
|
||
| print(base64.b64encode(relative_path.encode("utf-8")).decode("utf-8")) | ||
| PY | ||
| } | ||
|
|
||
| function copy_to_clipboard() { | ||
| local value="$1" | ||
|
|
||
| if command -v wl-copy >/dev/null 2>&1; then | ||
| printf '%s' "$value" | wl-copy | ||
| return | ||
| fi | ||
|
|
||
| if command -v xclip >/dev/null 2>&1; then | ||
| printf '%s' "$value" | xclip -selection clipboard | ||
| return | ||
| fi | ||
|
|
||
| if command -v xsel >/dev/null 2>&1; then | ||
| printf '%s' "$value" | xsel --clipboard --input | ||
| return | ||
| fi | ||
| } | ||
|
|
||
| function copy_link() { | ||
| local file_path="$1" | ||
| local encoded | ||
| encoded="$(encode_relative_path "$file_path")" | ||
|
|
||
| if [ -z "$encoded" ]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| local response | ||
| response="$(curl -sS -X POST "$BASE_URL/copy-link/$encoded" 2>/dev/null || true)" | ||
| if [ -z "$response" ]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| local link | ||
| link="$(python3 - "$response" <<'PY' | ||
| import json | ||
| import sys | ||
|
|
||
| response = sys.argv[1] | ||
| try: | ||
| data = json.loads(response) | ||
| except json.JSONDecodeError: | ||
| print("") | ||
| sys.exit(0) | ||
|
|
||
| print(data.get("link", "")) | ||
| PY | ||
| )" | ||
|
|
||
| if [ -n "$link" ]; then | ||
| copy_to_clipboard "$link" | ||
| fi | ||
| } | ||
|
|
||
| if [ "$#" -lt 2 ]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| action="$1" | ||
| shift | ||
|
|
||
| if [ "$action" = "copy-link" ]; then | ||
| copy_link "$1" | ||
| exit 0 | ||
| fi | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| [Desktop Entry] | ||
| Type=Service | ||
| Name=Internxt Drive Actions | ||
| MimeType=all/allfiles;inode/directory; | ||
| ServiceTypes=KonqPopupMenu/Plugin | ||
| X-KDE-ServiceTypes=KonqPopupMenu/Plugin | ||
| Actions=InternxtCopyLink; | ||
| X-KDE-Submenu=Internxt Drive | ||
| X-KDE-Priority=TopLevel | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For Dolphin, new options must be configured using a new .desktop file that directly modifies the system settings. |
||
| X-KDE-StartupNotify=false | ||
|
|
||
| [Desktop Action InternxtCopyLink] | ||
| Name=Copy Internxt Link | ||
| Icon=insert-link | ||
| Exec=/usr/bin/env bash {{HOME}}/.local/share/internxt-dolphin-extension/internxt-dolphin-actions.sh copy-link %f | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,7 @@ | |
| "test:renderer": "vitest --config vitest.config.renderer.ts", | ||
| "test:renderer:coverage": "vitest --config vitest.config.renderer.ts --coverage", | ||
| "test:coverage": "concurrently \"npm:test:main:coverage\" \"npm:test:renderer:coverage\"", | ||
| "smoke:file-manager-extension": "NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true ts-node -r ./tests/smoke/file-manager-extension/smoke-electron-mock.cjs src/backend/features/file-manager-extension/file-manager-extension-smoke.ts", | ||
| "coverage:merge": "lcov-result-merger 'coverage/*/lcov.info' 'coverage/lcov.info'", | ||
| "type-check": "./scripts/tsc-max-errors.sh", | ||
| "prepare": "husky install", | ||
|
|
@@ -75,7 +76,7 @@ | |
| "category": "Development" | ||
| }, | ||
| "deb": { | ||
| "depends": [ | ||
| "recommends": [ | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The installation of this add-on has been changed to “recommended” because in distributions such as Kubuntu that use KDE, this library is not available by default and prevents the application from being installed. |
||
| "python3-nautilus" | ||
| ] | ||
| }, | ||
|
|
@@ -253,4 +254,4 @@ | |
| "node": ">=24.0.0 <25.0.0", | ||
| "npm": ">=10.0.0 <11.0.0" | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| const supportedFileManagers = ['nautilus', 'nemo', 'dolphin', null] as const; | ||
| export type SupportedFileManager = (typeof supportedFileManagers)[number]; | ||
|
|
||
| export const NAUTILUS_EXTENSION_FILENAME = 'internxt-virtual-drive.py'; | ||
| export const NEMO_EXTENSION_FILENAME = 'internxt-virtual-drive.py'; | ||
| export const DOLPHIN_MENU_FILENAME = 'internxt-virtual-drive.desktop'; | ||
| export const DOLPHIN_HELPER_FILENAME = 'internxt-dolphin-actions.sh'; | ||
|
|
||
| export function isSupportedFileManager(value: SupportedFileManager): value is SupportedFileManager { | ||
| return supportedFileManagers.includes(value); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The functionality to generate the share link is still present in the app's code and can be accessed through the hydration API. This made it easy for us to create this script, which calls the corresponding endpoint and saves the link to the clipboard.
Since the extension's settings are managed directly through the system settings, it was necessary for the actions to be executed through this script.