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

Ericbrehault/sc 9423/folder sync check if folder exists #45

Merged
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
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
node-version: 20

- name: Get package version
run: node -p -e '`PACKAGE_VERSION=${require("./package.json").version}`' >> $GITHUB_ENV
run: node utils/get-version.js >> $GITHUB_ENV

- name: install dependencies electron-app
run: npm install
Expand Down Expand Up @@ -90,7 +90,7 @@ jobs:
node-version: 20

- name: Get package version
run: node -p -e '`PACKAGE_VERSION=${require("./package.json").version}`' >> $GITHUB_ENV
run: node utils/get-version.js >> $GITHUB_ENV

- name: Set version in source
run: |-
Expand Down Expand Up @@ -161,7 +161,7 @@ jobs:
node-version: 20

- name: Get package version
run: node -p -e "`PACKAGE_VERSION=${require('./package.json').version}`" >> $GITHUB_ENV
run: node utils/get-version.js >> $GITHUB_ENV

- name: install dependencies electron-app
run: npm install
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nuclia-sync-agent-app",
"version": "1.2.12",
"version": "1.2.13",
"description": "This is a Nuclia Sync Agent App",
"main": "build/index.js",
"scripts": {
Expand Down
4 changes: 4 additions & 0 deletions server/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.2.13 (2024-04-04)

- Report errors from the different connectors

# 1.2.7 (2024-03-28)

- Fix file type filtering
Expand Down
2 changes: 1 addition & 1 deletion server/src/logic/connector/domain/connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export type SyncItem = z.infer<typeof SyncItemValidator>;
export interface SearchResults {
items: SyncItem[];
nextPage?: Observable<SearchResults>;
error?: string;
}

export interface Field {
Expand All @@ -52,7 +53,6 @@ export interface IConnector {
areParametersValid(params: ConnectorParameters): boolean;
getParameters(): ConnectorParameters;
getFolders(query?: string): Observable<SearchResults>;
getFiles(query?: string): Observable<SearchResults>;
getFilesFromFolders(folders: SyncItem[]): Observable<SearchResults>;
getLastModified(since: string, folders?: SyncItem[]): Observable<SearchResults>;
// we cannot use the TextField from the SDK because we want to keep connectors independant
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ export class ConfluenceImpl implements IConnector {
return this._getFiles('', true);
}

getFiles(query?: string): Observable<SearchResults> {
return this._getFiles(query);
}

getFilesFromFolders(folders: SyncItem[]): Observable<SearchResults> {
if ((folders ?? []).length === 0) {
return of({
Expand All @@ -67,6 +63,7 @@ export class ConfluenceImpl implements IConnector {
console.error(err);
return of({
items: [],
error: `Error fetching files: ${err}`,
});
}
}
Expand All @@ -85,6 +82,7 @@ export class ConfluenceImpl implements IConnector {
console.error(err);
return of({
items: [],
error: `Error fetching last modified files: ${err}`,
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class DropboxImpl extends OAuthBaseConnector implements IConnector {
} catch (err) {
return of({
items: [],
error: `Error fetching last modified files: ${err}`,
});
}
}
Expand All @@ -86,6 +87,7 @@ export class DropboxImpl extends OAuthBaseConnector implements IConnector {
} catch (err) {
return of({
items: [],
error: `Error fetching files: ${err}`,
});
}
}
Expand All @@ -94,10 +96,6 @@ export class DropboxImpl extends OAuthBaseConnector implements IConnector {
return this._getFiles(query, true, '');
}

getFiles(query?: string): Observable<SearchResults> {
return this._getFiles(query);
}

isAccessTokenValid(): Observable<boolean> {
return from(
fetch('https://api.dropboxapi.com/2/users/get_current_account ', {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Blob as FSBlob } from 'buffer';
import * as fs from 'fs';
import path from 'path';
import { forkJoin, map, Observable, of, switchMap } from 'rxjs';
import { forkJoin, from, map, Observable, of, switchMap } from 'rxjs';
import { ConnectorParameters, FileStatus, IConnector, Link, SearchResults, SyncItem } from '../../domain/connector';
import { SourceConnectorDefinition } from '../factory';
import { lookup } from 'mime-types';
Expand Down Expand Up @@ -40,10 +40,6 @@ class FolderImpl implements IConnector {
throw new Error('Method not supported by Folder connector.');
}

getFiles(query?: string): Observable<SearchResults> {
return this._getFiles(this.params.path, query);
}

getFilesFromFolders(folders: SyncItem[]): Observable<SearchResults> {
if ((folders ?? []).length === 0) {
return of({
Expand Down Expand Up @@ -80,25 +76,42 @@ class FolderImpl implements IConnector {
return forkJoin(
(folders || []).map((folder) =>
this._getFiles(folder.originalId).pipe(
switchMap((results) => this.getFilesModifiedSince(results.items, since)),
switchMap((results) =>
from(this.getFilesModifiedSince(results.items, since)).pipe(
map((items) => ({ items, error: results.error })),
),
),
),
),
).pipe(
map((results) => {
const items = results.reduce((acc, result) => acc.concat(result), [] as SyncItem[]);
const items = results.reduce((acc, result) => acc.concat(result.items), [] as SyncItem[]);
const errors = results
.map((result) => result.error)
.filter((error) => !!error)
.join('. ');
return {
items,
error: errors,
};
}),
);
} catch (err) {
return of({
items: [],
error: 'Error getting last modified files.',
});
}
}

private _getFiles(path: string, query?: string): Observable<SearchResults> {
if (!fs.existsSync(path)) {
console.error(`Folder ${path} does not exist.`);
return of({
items: [],
error: `Folder ${path} does not exist.`,
});
}
return of({
items: this.mapFSFiles(this.listAllFiles(path)).filter((item) =>
query ? item.title.toLocaleLowerCase().includes(query?.toLocaleLowerCase()) : true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export class GDriveImpl extends OAuthBaseConnector implements IConnector {
} catch (err) {
return of({
items: [],
error: `Error fetching last modified files: ${err}`,
});
}
}
Expand All @@ -87,6 +88,7 @@ export class GDriveImpl extends OAuthBaseConnector implements IConnector {
} catch (err) {
return of({
items: [],
error: `Error fetching files: ${err}`,
});
}
}
Expand Down Expand Up @@ -137,10 +139,6 @@ export class GDriveImpl extends OAuthBaseConnector implements IConnector {
);
}

getFiles(query?: string): Observable<SearchResults> {
return this._getFileItems(query);
}

isAccessTokenValid(): Observable<boolean> {
return from(
fetch('https://www.googleapis.com/drive/v3/about?fields=user', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class OneDriveImpl extends OAuthBaseConnector implements IConnector {
} catch (err) {
return of({
items: [],
error: `Error fetching last modified files: ${err}`,
});
}
}
Expand All @@ -86,6 +87,7 @@ export class OneDriveImpl extends OAuthBaseConnector implements IConnector {
} catch (err) {
return of({
items: [],
error: `Error fetching files: ${err}`,
});
}
}
Expand All @@ -94,10 +96,6 @@ export class OneDriveImpl extends OAuthBaseConnector implements IConnector {
return this._getItems(query, '', true);
}

getFiles(query?: string): Observable<SearchResults> {
return this._getItems(query);
}

isAccessTokenValid(): Observable<boolean> {
return from(
fetch('https://graph.microsoft.com/v1.0/me/drive', {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { from, map, Observable, of } from 'rxjs';
import { catchError, from, map, Observable, of } from 'rxjs';
import { ConnectorParameters, FileStatus, IConnector, Link, SearchResults, SyncItem } from '../../domain/connector';
import { SourceConnectorDefinition } from '../factory';
import * as cheerio from 'cheerio';
Expand Down Expand Up @@ -64,7 +64,7 @@ class RSSImpl implements IConnector {
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getFiles(query?: string): Observable<SearchResults> {
private _getFiles(query?: string): Observable<SearchResults> {
const url = this.params['url'];

return from(fetchRSS(url)).pipe(
Expand All @@ -82,6 +82,7 @@ class RSSImpl implements IConnector {
},
})),
})),
catchError((err) => of({ items: [], error: `Error fetching RSS feed: ${err}` })),
);
}

Expand All @@ -100,12 +101,12 @@ class RSSImpl implements IConnector {

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getFilesFromFolders(folders: SyncItem[]): Observable<SearchResults> {
return this.getFiles();
return this._getFiles();
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getLastModified(since: string, folders?: SyncItem[]): Observable<SearchResults> {
return this.getFiles().pipe(
return this._getFiles().pipe(
map((searchResults) => ({
...searchResults,
items: searchResults.items.filter((item) => item.modifiedGMT && item.modifiedGMT > since),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export class SharepointImpl extends OAuthBaseConnector implements IConnector {
} catch (err) {
return of({
items: [],
error: `Error fetching last modified files: ${err}`,
});
}
}
Expand All @@ -67,11 +68,6 @@ export class SharepointImpl extends OAuthBaseConnector implements IConnector {
return this._getItems('', true);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getFiles(query?: string): Observable<SearchResults> {
return this._getItems();
}

getFilesFromFolders(folders: SyncItem[]): Observable<SearchResults> {
if ((folders ?? []).length === 0) {
return of({
Expand All @@ -93,6 +89,7 @@ export class SharepointImpl extends OAuthBaseConnector implements IConnector {
} catch (err) {
return of({
items: [],
error: `Error fetching files: ${err}`,
});
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { from, map, Observable, of, switchMap } from 'rxjs';
import { catchError, from, map, Observable, of, switchMap } from 'rxjs';
import { ConnectorParameters, FileStatus, IConnector, Link, SearchResults, SyncItem } from '../../domain/connector';
import { SourceConnectorDefinition } from '../factory';
import * as cheerio from 'cheerio';
Expand All @@ -16,7 +16,7 @@ async function fetchSitemap(url: string): Promise<string> {
return response.text();
} catch (error) {
console.error('Error fetching sitemap', error);
return Promise.resolve('');
return Promise.reject('Error fetching sitemap');
}
}

Expand Down Expand Up @@ -72,7 +72,7 @@ class SitemapImpl implements IConnector {
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getFiles(query?: string | undefined): Observable<SearchResults> {
private _getFiles(query?: string | undefined): Observable<SearchResults> {
const sitemapUrl = this.params['sitemap'];

return this._getSiteMap(sitemapUrl).pipe(
Expand All @@ -90,6 +90,7 @@ class SitemapImpl implements IConnector {
},
})),
})),
catchError((err) => of({ items: [], error: `${err}` })),
);
}

Expand All @@ -109,12 +110,12 @@ class SitemapImpl implements IConnector {

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getFilesFromFolders(folders: SyncItem[]): Observable<SearchResults> {
return this.getFiles();
return this._getFiles();
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getLastModified(since: string, folders?: SyncItem[]): Observable<SearchResults> {
return this.getFiles().pipe(
return this._getFiles().pipe(
map((searchResults) => ({
...searchResults,
items: searchResults.items.filter(
Expand Down
19 changes: 7 additions & 12 deletions server/src/logic/sync/domain/sync.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,6 @@ export class SyncEntity {
return this.sourceConnector.getFolders();
}

get files(): Observable<SearchResults> {
if (!this.sourceConnector) {
return of({
items: [],
});
}
return this.sourceConnector.getFiles();
}

getLastModified(): Observable<{ success: boolean; results: SyncItem[]; error?: string }> {
const foldersToSyncPending: SyncItem[] = (this.foldersToSync ?? []).filter(
(folder) => folder.status === FileStatus.PENDING || folder.status === undefined,
Expand All @@ -137,15 +128,19 @@ export class SyncEntity {
const getFilesFoldersUpdated =
foldersToSyncUpdated.length > 0
? this.sourceConnector!.getLastModified(this.lastSyncGMT || '2000-01-01T00:00:00.000Z', foldersToSyncUpdated)
: of({ items: [] });
: of({ items: [] } as SearchResults);

const getFilesFolderPending =
foldersToSyncPending.length > 0
? this.sourceConnector!.getFilesFromFolders(foldersToSyncPending)
: of({ items: [] });
: of({ items: [] } as SearchResults);
return forkJoin([getFilesFoldersUpdated, getFilesFolderPending]).pipe(
map(([updated, pending]) => {
return { success: true, results: [...updated.items, ...pending.items] };
return {
success: !updated.error && !pending.error,
results: [...updated.items, ...pending.items],
error: [updated.error, pending.error].filter((err) => err).join('. '),
};
}),
catchError((err) => {
console.error(`Error on ${this.id}: ${err.message}`);
Expand Down
4 changes: 2 additions & 2 deletions server/src/subscribers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ export function initFileSystemSubscribers(basePath: string) {
const saveLog = new SaveLogs(new LogRepository(new FileSystemLogDatasource(basePath)));
saveLog.execute(
new LogEntity({
message: 'Synchronization finished',
level: LogSeverityLevel.low,
message: payload['error'] || 'Synchronization finished',
level: payload['error'] ? LogSeverityLevel.high : LogSeverityLevel.low,
action: EVENTS.FINISH_SYNCHRONIZATION_SYNC_OBJECT,
payload,
}),
Expand Down
2 changes: 2 additions & 0 deletions utils/get-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const { version } = require('../package.json');
console.log(`PACKAGE_VERSION=${version}`);