Skip to content
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

Use chokidar, add polling mode, improve auto cleanup #51

Merged
merged 3 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 77 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"license": "MIT",
"repository": "https://github.com/felipecrs/clipboard-sync.git",
"dependencies": {
"chokidar": "^3.6.0",
"clipboard-event": "^1.6.0",
"electron-clipboard-ex": "^1.3.3",
"electron-log": "^5.1.2",
Expand Down
51 changes: 40 additions & 11 deletions src/main/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ export const isIsReceivingFile = (file: string) => {
// And removes from-others files older than 10 minutes.
export const cleanFiles = async (syncFolder: string) => {
const now = Date.now();
const currentTimeMinus1Min = now - 6000;
const currentTimeMinus5Min = now - 300000;

const files = await fs.readdir(syncFolder);
for (const file of files) {
Expand All @@ -148,8 +146,22 @@ export const cleanFiles = async (syncFolder: string) => {
continue;
}

const fileStat = await fs.lstat(filePath);
if (fileStat.ctime.getTime() <= currentTimeMinus5Min) {
// Delete from myself files older than 5 minutes and
// from others older than 10 minutes
const timeThreshold = parsedFile.from === "myself" ? now - 300000 : now - 600000;

let fileStat;
try {
fileStat = await fs.lstat(filePath);
} catch (error) {
if (error.code === "ENOENT") {
// Ignore ENOENT error (file not found), as our intention is to delete it anyway.
continue;
}
throw error;
}

if (fileStat.ctime.getTime() <= timeThreshold) {
log.info(`Deleting: ${filePath}`);
await deleteFileOrFolderRecursively(filePath);
continue;
Expand All @@ -159,16 +171,27 @@ export const cleanFiles = async (syncFolder: string) => {
if (
process.platform === "win32" &&
parsedFile.from === "others" &&
fileStat.ctime.getTime() <= currentTimeMinus1Min
fileStat.ctime.getTime() <= now - 60000
) {
log.info(`Unsyncing: ${filePath}`);
await unsyncFileOrFolderRecursively(filePath);
}
}
};

export const unsyncFileOrFolderRecursively = async (fileOrFolder: string) => {
// Create a wrapper function for fsWin.setAttributes that follows the Node.js callback pattern
function getAttributesWrapper(
path: string,
callback: (arg0: Error, arg1: fswin.Attributes) => void
) {
fswin.getAttributes(path, function (result) {
if (result) {
callback(null, result);
} else {
callback(new Error(`Failed to set attributes of ${path}`), null);
}
});
}

function setAttributesWrapper(
path: string,
attributes: fswin.SetAttributes,
Expand All @@ -183,13 +206,19 @@ export const unsyncFileOrFolderRecursively = async (fileOrFolder: string) => {
});
}

const getAttributesAsync = promisify(getAttributesWrapper);
const setAttributesAsync = promisify(setAttributesWrapper);

await iterateThroughFilesRecursively([fileOrFolder], async (file) => {
await setAttributesAsync(file, {
IS_UNPINNED: true,
IS_PINNED: false,
});
// Only unsync file if it has IS_REPARSE_POINT attribute
if ((await getAttributesAsync(file)).IS_REPARSE_POINT) {
log.info(`Unsyncing: ${file}`);
await setAttributesAsync(file, {
IS_UNPINNED: true,
IS_PINNED: false,
});
return;
}
});
};

Expand Down
Loading