Recalculate completion for devices and update total properties

This commit is contained in:
Jesse Lucas 2020-04-06 14:30:44 -04:00
parent 1e33cc9720
commit 5a6d79a66e
No known key found for this signature in database
GPG Key ID: 9810010C7FDCD3BB
8 changed files with 94 additions and 31 deletions

View File

@ -3,4 +3,5 @@ export interface Completion {
globalBytes: number; globalBytes: number;
needBytes: number; needBytes: number;
needDeletes: number; needDeletes: number;
needItems: number;
} }

View File

@ -1,4 +1,6 @@
import { colors } from './style'; import { colors } from './style';
import Folder from './folder';
import { Completion } from './completion';
interface Device { interface Device {
deviceID: string; deviceID: string;
@ -7,8 +9,9 @@ interface Device {
state: string; state: string;
paused: boolean; paused: boolean;
connected: boolean; connected: boolean;
completion: number; completion: Completion;
used: boolean; // indicates if a folder is using the device used: boolean; // indicates if a folder is using the device
folders: Folder[];
} }
namespace Device { namespace Device {
@ -80,7 +83,7 @@ namespace Device {
} }
if (d.connected) { if (d.connected) {
if (d.completion === 100) { if (d.completion.completion === 100) {
return d.used ? StateType.Insync : StateType.UnusedInsync; return d.used ? StateType.Insync : StateType.UnusedInsync;
} else { } else {
return StateType.Syncing; return StateType.Syncing;
@ -89,5 +92,35 @@ namespace Device {
return d.used ? StateType.Disconnected : StateType.UnusedDisconnected; return d.used ? StateType.Disconnected : StateType.UnusedDisconnected;
} }
export function recalcCompletion(d: Device) {
if (!d || !d.completion || !d.folders) {
return
}
var total = 0, needed = 0, deletes = 0, items = 0;
d.folders.forEach(folder => {
if (!folder || !folder.completion)
return
needed += folder.completion.needBytes;
items += folder.completion.needItems;
deletes += folder.completion.needDeletes;
});
if (total == 0) {
d.completion.completion = 100;
d.completion.needBytes = 0;
d.completion.needItems = 0;
} else {
d.completion.completion = Math.floor(100 * (1 - needed / total));
d.completion.needBytes = needed;
d.completion.needItems = items + deletes;
}
if (needed == 0 && deletes > 0) {
// We don't need any data, but we have deletes that we need
// to do. Drop down the completion percentage to indicate
// that we have stuff to do.
d.completion.completion = 95;
}
}
} }
export default Device; export default Device;

View File

@ -1,5 +1,6 @@
import Device from './device'; import Device from './device';
import { colors } from './style'; import { colors } from './style';
import { Completion } from './completion';
interface Folder { interface Folder {
id: string; id: string;
@ -9,7 +10,7 @@ interface Folder {
stateType: Folder.StateType; stateType: Folder.StateType;
state: string; state: string;
paused: boolean; paused: boolean;
completion: number; completion: Completion;
path: string; path: string;
} }
@ -144,18 +145,13 @@ namespace Folder {
return StateType.Unknown; return StateType.Unknown;
} }
const needTotalItems = fs.needDeletes + fs.needDirectories + if (fs.needTotalItems > 0) {
fs.needFiles + fs.needSymlinks;
const receiveOnlyTotalItems = fs.receiveOnlyChangedDeletes + fs.receiveOnlyChangedDirectories +
fs.receiveOnlyChangedFiles + fs.receiveOnlyChangedSymlinks;
if (needTotalItems > 0) {
return StateType.OutOfSync; return StateType.OutOfSync;
} }
if (f.status.pullErrors > 0) { if (fs.pullErrors > 0) {
return StateType.FailedItems; return StateType.FailedItems;
} }
if (receiveOnlyTotalItems > 0) { if (fs.receiveOnlyTotalItems > 0) {
return StateType.LocalAdditions; return StateType.LocalAdditions;
} }
if (f.devices.length <= 1) { if (f.devices.length <= 1) {
@ -172,6 +168,7 @@ namespace Folder {
globalDirectories: number; globalDirectories: number;
globalFiles: number; globalFiles: number;
globalSymlinks: number; globalSymlinks: number;
globalTotalItems: number;
ignorePatterns: boolean; ignorePatterns: boolean;
inSyncBytes: number; inSyncBytes: number;
inSyncFiles: number; inSyncFiles: number;
@ -186,12 +183,14 @@ namespace Folder {
needDirectories: number; needDirectories: number;
needFiles: number; needFiles: number;
needSymlinks: number; needSymlinks: number;
needTotalItems: number;
pullErrors: number; pullErrors: number;
receiveOnlyChangedBytes: number; receiveOnlyChangedBytes: number;
receiveOnlyChangedDeletes: number; receiveOnlyChangedDeletes: number;
receiveOnlyChangedDirectories: number; receiveOnlyChangedDirectories: number;
receiveOnlyChangedFiles: number; receiveOnlyChangedFiles: number;
receiveOnlyChangedSymlinks: number; receiveOnlyChangedSymlinks: number;
receiveOnlyTotalItems: number;
sequence: number; sequence: number;
state: string; state: string;
stateChanged: string; stateChanged: string;

View File

@ -5,13 +5,15 @@ export const dbCompletion =
"completion": 100, "completion": 100,
"globalBytes": 156793013575, "globalBytes": 156793013575,
"needBytes": 0, "needBytes": 0,
"needDeletes": 0 "needDeletes": 0,
"needItems": 0
}, },
{ {
"completion": 80, "completion": 80,
"globalBytes": 3013575, "globalBytes": 3013575,
"needBytes": 100, "needBytes": 100,
"needDeletes": 0 "needDeletes": 0,
"needItems": 0
} }
] ]
/* /*

View File

@ -16,6 +16,7 @@ export const dbStatus =
"globalDirectories": 0, "globalDirectories": 0,
"globalFiles": 0, "globalFiles": 0,
"globalSymlinks": 0, "globalSymlinks": 0,
"globalTotalItems": 0,
"ignorePatterns": false, "ignorePatterns": false,
"inSyncBytes": 0, "inSyncBytes": 0,
"inSyncFiles": 0, "inSyncFiles": 0,
@ -25,11 +26,13 @@ export const dbStatus =
"localDirectories": 0, "localDirectories": 0,
"localFiles": 0, "localFiles": 0,
"localSymlinks": 0, "localSymlinks": 0,
"localTotalItems": 0,
"needBytes": 0, "needBytes": 0,
"needDeletes": 0, "needDeletes": 0,
"needDirectories": 0, "needDirectories": 0,
"needFiles": 0, "needFiles": 0,
"needSymlinks": 0, "needSymlinks": 0,
"needTotalItems": 0,
"pullErrors": 0, "pullErrors": 0,
"receiveOnlyChangedBytes": 0, "receiveOnlyChangedBytes": 0,
"receiveOnlyChangedDeletes": 0, "receiveOnlyChangedDeletes": 0,

View File

@ -5,6 +5,7 @@ import { apiURL, apiRetry } from '../api-utils';
import { Completion } from '../completion'; import { Completion } from '../completion';
import { retry, map } from 'rxjs/operators'; import { retry, map } from 'rxjs/operators';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { StType } from '../type';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -14,12 +15,21 @@ export class DbCompletionService {
constructor(private http: HttpClient) { } constructor(private http: HttpClient) { }
getDeviceCompletion(id: string): Observable<Completion> { getCompletion(type: StType, id: string): Observable<Completion> {
let httpOptions: { params: HttpParams }; let httpOptions: { params: HttpParams };
if (id) { if (id) {
switch (type) {
case StType.Device:
httpOptions = { httpOptions = {
params: new HttpParams().set('device', id) params: new HttpParams().set('device', id)
}; };
break;
case StType.Folder:
httpOptions = {
params: new HttpParams().set('folder', id)
};
break;
}
} else { } } else { }
return this.http return this.http
@ -38,6 +48,5 @@ export class DbCompletionService {
return res; return res;
}) })
); );
} }
} }

View File

@ -7,6 +7,7 @@ import { DbCompletionService } from './db-completion.service';
import { SystemConnections } from '../connections'; import { SystemConnections } from '../connections';
import { SystemStatusService } from './system-status.service'; import { SystemStatusService } from './system-status.service';
import { ProgressService } from './progress.service'; import { ProgressService } from './progress.service';
import { StType } from '../type';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -48,16 +49,17 @@ export class DeviceService {
} }
} }
this.dbCompletionService.getDeviceCompletion(device.deviceID).subscribe( this.dbCompletionService.getCompletion(StType.Device, device.deviceID).subscribe(
c => { c => {
device.completion = c.completion; device.completion = c;
Device.recalcCompletion(device);
device.stateType = Device.getStateType(device); device.stateType = Device.getStateType(device);
device.state = Device.stateTypeToString(device.stateType); device.state = Device.stateTypeToString(device.stateType);
observer.next(device); observer.next(device);
this.progressService.addToProgress(1); this.progressService.addToProgress(1);
// recursively get the status of the next folder // recursively get the status of the next device
this.getDeviceStatusInOrder(observer, startIndex); this.getDeviceStatusInOrder(observer, startIndex);
}); });
} }
@ -75,22 +77,29 @@ export class DeviceService {
status => { status => {
this.devices.forEach(device => { this.devices.forEach(device => {
if (device.deviceID === status.myID) { if (device.deviceID === status.myID) {
console.log("found thisDevice!", device); // TODO Determine if it should ignore thisDevice
this.thisDevice = device; this.thisDevice = device;
} }
}); });
// TODO Determine if it should ignore thisDevice
// Check folder devices to see if the device is used // Check folder devices to see if the device is used
this.systemConfigService.getFolders().subscribe( this.systemConfigService.getFolders().subscribe(
folders => { folders => {
// Loop through all folder devices to see if the device is used // Loop through all folder devices to see if the device is used
this.devices.forEach(device => { this.devices.forEach(device => {
// Alloc array if needed
if (!device.folders) {
device.folders = [];
}
folders.forEach(folder => { folders.forEach(folder => {
folder.devices.forEach(fdevice => { folder.devices.forEach(fdevice => {
if (device.deviceID === fdevice.deviceID) { if (device.deviceID === fdevice.deviceID) {
// The device is used by a folder
device.used = true; device.used = true;
// Add a reference to the folder to the device
device.folders.push(folder);
} }
}); });
}); });

View File

@ -4,6 +4,8 @@ import { Observable, Subscriber } from 'rxjs';
import Folder from '../folder'; import Folder from '../folder';
import { DbStatusService } from './db-status.service'; import { DbStatusService } from './db-status.service';
import { ProgressService } from './progress.service'; import { ProgressService } from './progress.service';
import { DbCompletionService } from './db-completion.service';
import { StType } from '../type';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -14,6 +16,7 @@ export class FolderService {
constructor( constructor(
private systemConfigService: SystemConfigService, private systemConfigService: SystemConfigService,
private dbStatusService: DbStatusService, private dbStatusService: DbStatusService,
private dbCompletionService: DbCompletionService,
private progressService: ProgressService, private progressService: ProgressService,
) { } ) { }
@ -28,15 +31,19 @@ export class FolderService {
this.dbStatusService.getFolderStatus(folder.id).subscribe( this.dbStatusService.getFolderStatus(folder.id).subscribe(
status => { status => {
folder.status = status; folder.status = status;
this.dbCompletionService.getCompletion(StType.Folder, folder.id).subscribe(
c => {
folder.completion = c;
folder.stateType = Folder.getStateType(folder); folder.stateType = Folder.getStateType(folder);
folder.state = Folder.stateTypeToString(folder.stateType); folder.state = Folder.stateTypeToString(folder.stateType);
observer.next(folder); observer.next(folder);
// Add one to the progress service
this.progressService.addToProgress(1); this.progressService.addToProgress(1);
// recursively get the status of the next folder // recursively get the status of the next folder
this.getFolderStatusInOrder(observer, startIndex); this.getFolderStatusInOrder(observer, startIndex);
});
} }
); );
} }