Skip to content

Commit

Permalink
Merge pull request #297 from oae/296-unescaping-works-not-as-intended…
Browse files Browse the repository at this point in the history
…-and-is-slow

Unescaping works not as intended and is slow
  • Loading branch information
Totto16 authored Jun 4, 2024
2 parents 19f0d20 + c51a844 commit b8cec16
Show file tree
Hide file tree
Showing 13 changed files with 1,497 additions and 1,381 deletions.
20 changes: 16 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
jobs:
build:
name: Yarn CI with Node ${{ matrix.node-version }}
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04

strategy:
matrix:
Expand All @@ -26,13 +26,25 @@ jobs:
node-version: ${{ matrix.node-version }}

- name: Install dependencies
run: yarn install
run: yarn install -D

- name: Validate Formatting
run: yarn run prettier:check

- name: Lint Extension
run: yarn run lint

- name: Build Extension
run: yarn run build

- name: Lint Extension
run: yarn run lint
- name: Prepare Test Runner
run: |
sudo apt-get install meson gjs gir1.2-gda-5.0 gir1.2-gsound-1.0 -y
git clone https://github.com/ptomato/jasmine-gjs
cd jasmine-gjs
meson setup build
meson compile -C build
sudo meson install -C build
- name: Run Tests
run: yarn run test
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -295,4 +295,5 @@ fabric.properties

# ts-for-gjs output

docs-lock.json
docs-lock.json
build/
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.github/
.github/FUNDING.yml
.github/pull_request_template.md
.github/ISSUE_TEMPLATE/
node_modules/
*.md
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ Since Gnome 45 we had to break compatibility with previous Gnome versions, these
sudo dnf install libgda libgda-sqlite
```

- Arch Linux (For gnome-43 or later, you need libgda6)
- Arch Linux

```bash
sudo pacman -S libgda
sudo pacman -S libgda6
```

- Ubuntu/Debian
Expand Down
59 changes: 30 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"clean:schema": "rm -rf ./dist/schemas/*.compiled",
"build:package": "yarn run build && rm -rf './dist/pano@elhan.io.zip' && cd ./dist && zip -qr 'pano@elhan.io.zip' .",
"watch": "yarn run build && yarn run rollup -c --watch",
"test": "echo \"Error: no test specified\" && exit 1",
"test": "jasmine --module --no-config build/tests/",
"lint": "eslint --ext .ts src/",
"shell:restart": "busctl --user call org.gnome.Shell /io/elhan/Pano io.elhan.Pano restart",
"build-and-restart": "yarn run build && yarn run shell:restart",
Expand All @@ -33,36 +33,38 @@
}
},
"devDependencies": {
"@commitlint/cli": "^19.2.2",
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@girs/adw-1": "1.5.0-4.0.0-beta.2",
"@girs/clutter-14": "14.0.0-4.0.0-beta.2",
"@girs/gda-5.0": "5.0.0-4.0.0-beta.2",
"@girs/gda-6.0": "6.0.0-4.0.0-beta.2",
"@girs/gdk-4.0": "4.0.0-4.0.0-beta.2",
"@girs/gdkpixbuf-2.0": "2.0.0-4.0.0-beta.2",
"@girs/gio-2.0": "2.80.0-4.0.0-beta.2",
"@girs/glib-2.0": "2.80.0-4.0.0-beta.2",
"@girs/gnome-shell": "46.0.0-4.0.0-beta.3",
"@girs/gobject-2.0": "2.80.0-4.0.0-beta.2",
"@girs/graphene-1.0": "1.0.0-4.0.0-beta.2",
"@girs/gsound-1.0": "1.0.0-4.0.0-beta.2",
"@girs/gtk-4.0": "4.14.1-4.0.0-beta.2",
"@girs/meta-14": "14.0.0-4.0.0-beta.2",
"@girs/pango-1.0": "1.51.2-4.0.0-beta.2",
"@girs/shell-14": "14.0.0-4.0.0-beta.2",
"@girs/soup-3.0": "3.4.4-4.0.0-beta.2",
"@girs/st-14": "14.0.0-4.0.0-beta.2",
"@rollup/plugin-commonjs": "^25.0.7",
"@girs/adw-1": "1.5.0-4.0.0-beta.5",
"@girs/clutter-14": "14.0.0-4.0.0-beta.5",
"@girs/gda-5.0": "5.0.0-4.0.0-beta.5",
"@girs/gda-6.0": "6.0.0-4.0.0-beta.5",
"@girs/gdk-4.0": "4.0.0-4.0.0-beta.5",
"@girs/gdkpixbuf-2.0": "2.0.0-4.0.0-beta.5",
"@girs/gio-2.0": "2.80.0-4.0.0-beta.5",
"@girs/glib-2.0": "2.80.0-4.0.0-beta.5",
"@girs/gnome-shell": "46.0.0-beta9",
"@girs/gobject-2.0": "2.80.0-4.0.0-beta.5",
"@girs/graphene-1.0": "1.0.0-4.0.0-beta.5",
"@girs/gsound-1.0": "1.0.0-4.0.0-beta.5",
"@girs/gtk-4.0": "4.14.3-4.0.0-beta.5",
"@girs/meta-14": "14.0.0-4.0.0-beta.5",
"@girs/pango-1.0": "1.52.2-4.0.0-beta.5",
"@girs/shell-14": "14.0.0-4.0.0-beta.5",
"@girs/soup-3.0": "3.4.4-4.0.0-beta.5",
"@girs/st-14": "14.0.0-4.0.0-beta.5",
"@rollup/plugin-commonjs": "^25.0.8",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.6",
"@tsconfig/strictest": "^2.0.5",
"@types/events": "^3.0.3",
"@types/gettext-parser": "^4.0.4",
"@types/highlight.js": "^10.1.0",
"@types/is-url": "^1.2.32",
"@types/prismjs": "^1.26.3",
"@typescript-eslint/eslint-plugin": "^7.7.0",
"@typescript-eslint/parser": "^7.7.0",
"@types/jasmine": "^5.1.4",
"@types/prismjs": "^1.26.4",
"@typescript-eslint/eslint-plugin": "^7.12.0",
"@typescript-eslint/parser": "^7.12.0",
"cross-env": "^7.0.3",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
Expand All @@ -71,16 +73,15 @@
"fill-pot-po": "^3.0.4",
"gettext-extractor": "^3.8.0",
"gettext-parser": "^7.0.1",
"glob": "^10.3.12",
"glob": "^10.4.1",
"husky": "^9.0.11",
"prettier": "^3.2.5",
"rollup": "^4.14.3",
"prettier": "^3.3.0",
"rollup": "^4.18.0",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-copy": "^3.5.0",
"rollup-plugin-styles": "^4.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.4.5",
"@tsconfig/strictest": "^2.0.5"
"typescript": "^5.4.5"
},
"dependencies": {
"date-fns": "^2.30.0",
Expand Down
35 changes: 35 additions & 0 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,40 @@ const thirdPartyBuild = thirdParty.map((pkg) => {
};
});

const testFiles = ['db.test'];

const testBuilds = testFiles.map((file) => {
return {
input: `tests/${file}.ts`,
treeshake: {
moduleSideEffects: 'no-external',
},
output: {
file: `build/tests/${file}.js`,
format: 'esm',
name: 'init',
paths: { ...ExtensionEntries, ...GlobalEntries },
assetFileNames: '[name][extname]',
generatedCode: {
constBindings: true,
},
},
external: [...gjsModules, ...globalDefinitionImports],
plugins: [
commonjs(),
nodeResolve({
preferBuiltins: false,
}),
typescript({
tsconfig: './tsconfig.json',
}),
cleanup({
comments: 'none',
}),
],
};
});

const builds = [
...thirdPartyBuild,
{
Expand Down Expand Up @@ -209,6 +243,7 @@ const builds = [
}),
],
},
...testBuilds,
];

export default builds;
3 changes: 2 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
debounceIds,
deleteAppDirs,
getCurrentExtensionSettings,
getDbPath,
loadInterfaceXML,
logger,
removeSoundContext,
Expand Down Expand Up @@ -134,7 +135,7 @@ export default class PanoExtension extends Extension {

private setupResources() {
setupAppDirs(this);
db.setup(this);
db.setup(getDbPath(this));
}

private async clearHistory() {
Expand Down
35 changes: 34 additions & 1 deletion src/utils/compatibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import GLib from '@girs/glib-2.0';
import { Notification, Source as MessageTraySource } from '@girs/gnome-shell/dist/ui/messageTray';
import St from '@girs/st-14';

import { logger } from './shell';

const debug = logger('compatibility');

// better typed functions for GDA

// we get / have to store strings for dates and numbers for boolean
Expand Down Expand Up @@ -39,6 +43,35 @@ export function add_expr_value(builder: Gda5.SqlBuilder | Gda6.SqlBuilder | SqlB
return builder.add_expr_value(null, value);
}

/**
* a faster unescape function for gda
*
* Does not the exact reverse of gda_default_escape_string(): that transforms any "''" into "'", we don't do that,
* since this is incorrect in our usage, just unescape any "\\" into "\" and any "\'" into "'".
* @param input string to unescape
* @returns unescaped string or the input, if an error was be found or nothing needs to be unescaped
*/
export function unescape_string(input: string): string {
// check if we need to escape something, so we don't mutate strings unnecessary, this speeds things up
if (!input.includes('\\')) {
return input;
}

try {
return input.replaceAll(/\\(.)/g, (_all, captured) => {
if (captured === '\\' || captured === "'") {
return captured;
}

throw new Error(`Unexpected escape character '${captured}'`);
});
} catch (error) {
debug(`Error in unescape: ${error}`);
// return the original string
return input;
}
}

// compatibility functions for gnome-shell 45 / 46

function isGnome45Notifications(): boolean {
Expand All @@ -50,7 +83,7 @@ export function newNotification(
text: string,
banner: string,
transient_: boolean,
params: Notification.Params,
params: Notification.ConstructorProps,
): Notification {
if (isGnome45Notifications()) {
// @ts-expect-error gnome 45 type
Expand Down
29 changes: 15 additions & 14 deletions src/utils/db.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Gda5 from '@girs/gda-5.0';
import type { ExtensionBase } from '@girs/gnome-shell/dist/extensions/sharedInternals';
import { add_expr_value, type DataModelIter, type SqlBuilder } from '@pano/utils/compatibility';
import { getDbPath, logger } from '@pano/utils/shell';
import { add_expr_value, type DataModelIter, type SqlBuilder, unescape_string } from '@pano/utils/compatibility';
import { logger } from '@pano/utils/shell';

const debug = logger('database');

Expand All @@ -18,6 +17,8 @@ export type DBItem = {
metaData?: string | undefined;
};

export type SaveDBItem = Omit<DBItem, 'id'>;

class ClipboardQuery {
readonly statement: Gda5.Statement;

Expand Down Expand Up @@ -172,16 +173,16 @@ export class ClipboardQueryBuilder {
class Database {
private connection: Gda5.Connection | null = null;

private init(ext: ExtensionBase) {
private init(dbPath: string) {
this.connection = new Gda5.Connection({
provider: Gda5.Config.get_provider('SQLite'),
cncString: `DB_DIR=${getDbPath(ext)};DB_NAME=pano`,
cncString: `DB_DIR=${dbPath};DB_NAME=pano`,
});
this.connection.open();
}

setup(ext: ExtensionBase) {
this.init(ext);
setup(dbPath: string) {
this.init(dbPath);
if (!this.connection || !this.connection.is_opened()) {
debug('connection is not opened');
return;
Expand All @@ -206,7 +207,7 @@ class Database {
`);
}

save(dbItem: Omit<DBItem, 'id'>): DBItem | null {
save(dbItem: SaveDBItem): DBItem | null {
if (!this.connection || !this.connection.is_opened()) {
debug('connection is not opened');
return null;
Expand Down Expand Up @@ -321,13 +322,13 @@ class Database {
const id = iter.get_value_for_field('id');
const itemType = iter.get_value_for_field('itemType');
const content = iter.get_value_for_field('content');
const contentUnescaped = Gda5.default_unescape_string(content) ?? content;
const contentUnescaped = unescape_string(content) ?? content;
const copyDate = iter.get_value_for_field('copyDate');
const isFavorite = iter.get_value_for_field('isFavorite');
const matchValue = iter.get_value_for_field('matchValue');
const matchValueUnescaped = Gda5.default_unescape_string(matchValue) ?? matchValue;
const matchValueUnescaped = unescape_string(matchValue) ?? matchValue;
const searchValue = iter.get_value_for_field('searchValue');
const searchValueUnescaped = searchValue ? Gda5.default_unescape_string(searchValue) ?? searchValue : undefined;
const searchValueUnescaped = searchValue ? unescape_string(searchValue) ?? searchValue : undefined;
const metaData = iter.get_value_for_field('metaData');

itemList.push({
Expand All @@ -345,9 +346,9 @@ class Database {
return itemList;
}

start(ext: ExtensionBase) {
if (!this.connection) {
this.init(ext);
start(dbPath: string) {
if (!this.connection && dbPath) {
this.init(dbPath);
}

if (this.connection && !this.connection.is_opened()) {
Expand Down
4 changes: 2 additions & 2 deletions src/utils/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const logger =

const debug = logger('shell-utils');

const deleteFile = (file: Gio.File) => {
export const deleteFile = (file: Gio.File) => {
return new Promise((resolve, reject) => {
file.delete_async(GLib.PRIORITY_DEFAULT, null, (_file, res) => {
try {
Expand All @@ -22,7 +22,7 @@ const deleteFile = (file: Gio.File) => {
});
};

const deleteDirectory = async (file: Gio.File) => {
export const deleteDirectory = async (file: Gio.File) => {
try {
const iter: Gio.FileEnumerator | undefined = await new Promise((resolve, reject) => {
file.enumerate_children_async(
Expand Down
Loading

0 comments on commit b8cec16

Please sign in to comment.