mirror of https://github.com/ghostfolio/ghostfolio
committed by
GitHub
10 changed files with 160 additions and 20 deletions
@ -0,0 +1,59 @@ |
|||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { capitalize } from '@ghostfolio/common/helper'; |
||||
|
import { Export } from '@ghostfolio/common/interfaces'; |
||||
|
import { Type } from '@prisma/client'; |
||||
|
import { format, parseISO } from 'date-fns'; |
||||
|
|
||||
|
@Injectable({ |
||||
|
providedIn: 'root' |
||||
|
}) |
||||
|
export class IcsService { |
||||
|
private readonly ICS_DATE_FORMAT = 'yyyyMMdd'; |
||||
|
|
||||
|
public constructor() {} |
||||
|
|
||||
|
public transformActivitiesToIcsContent( |
||||
|
aActivities: Export['activities'] |
||||
|
): string { |
||||
|
const header = [ |
||||
|
'BEGIN:VCALENDAR', |
||||
|
'VERSION:2.0', |
||||
|
'PRODID:-//Ghostfolio//NONSGML v1.0//EN' |
||||
|
]; |
||||
|
const events = aActivities.map((activity) => { |
||||
|
return this.getEvent({ |
||||
|
date: parseISO(activity.date), |
||||
|
id: activity.id, |
||||
|
symbol: activity.symbol, |
||||
|
type: activity.type |
||||
|
}); |
||||
|
}); |
||||
|
const footer = ['END:VCALENDAR']; |
||||
|
|
||||
|
return [...header, ...events, ...footer].join('\n'); |
||||
|
} |
||||
|
|
||||
|
private getEvent({ |
||||
|
date, |
||||
|
id, |
||||
|
symbol, |
||||
|
type |
||||
|
}: { |
||||
|
date: Date; |
||||
|
id: string; |
||||
|
symbol: string; |
||||
|
type: Type; |
||||
|
}) { |
||||
|
const today = format(new Date(), this.ICS_DATE_FORMAT); |
||||
|
|
||||
|
return [ |
||||
|
'BEGIN:VEVENT', |
||||
|
`UID:${id}`, |
||||
|
`DTSTAMP:${today}T000000`, |
||||
|
`DTSTART;VALUE=DATE:${format(date, this.ICS_DATE_FORMAT)}`, |
||||
|
`DTEND;VALUE=DATE:${format(date, this.ICS_DATE_FORMAT)}`, |
||||
|
`SUMMARY:${capitalize(type)} ${symbol}`, |
||||
|
'END:VEVENT' |
||||
|
].join('\n'); |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue