Skip to content

Commit

Permalink
feat: set custom user agent for a playlist
Browse files Browse the repository at this point in the history
This commit closes the feature request from #26
  • Loading branch information
4gray committed Mar 27, 2021
1 parent da60934 commit a8167c4
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 48 deletions.
63 changes: 54 additions & 9 deletions api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
EPG_FETCH_DONE,
EPG_GET_PROGRAM,
EPG_GET_PROGRAM_DONE,
PLAYLIST_SAVE_DETAILS,
} from './ipc-commands';

const fs = require('fs');
Expand All @@ -24,6 +25,9 @@ export class Api {
/** Instance of the main application window */
mainWindow: BrowserWindow;

/** Default user agent stored as a fallback value */
defaultUserAgent: string;

/** Instance of the epg browser window */
workerWindow: BrowserWindow;

Expand Down Expand Up @@ -61,18 +65,11 @@ export class Api {
event.sender.send('parse-response', { payload: playlistObject });
});

ipcMain.on('playlists-all', async (event) => {
const playlists = await db.find(
{ type: { $exists: false } },
{ count: 1, title: 1, _id: 1, url: 1, importDate: 1 }
);
event.sender.send('playlist-all-result', {
payload: playlists,
});
});
ipcMain.on('playlists-all', (event) => this.sendAllPlaylists(event));

ipcMain.on('playlist-by-id', async (event, args) => {
const playlist = await db.findOne({ _id: args.id });
this.setUserAgent(playlist.userAgent);
event.sender.send('parse-response', {
payload: playlist,
});
Expand Down Expand Up @@ -137,6 +134,51 @@ export class Api {
.on(EPG_ERROR, (event, arg) =>
this.mainWindow.webContents.send(EPG_ERROR, arg)
);

ipcMain.on(PLAYLIST_SAVE_DETAILS, async (event, args) => {
const updated = await db.update(
{ _id: args._id },
{ $set: { title: args.title, userAgent: args.userAgent } }
);
if (!updated.numAffected || updated.numAffected === 0) {
console.error('Error: Playlist details were not updated');
}
this.sendAllPlaylists(event);
});
}

/**
* Sends list with all playlists which are stored in the database
* @param event main event
*/
async sendAllPlaylists(event: Electron.IpcMainEvent): Promise<void> {
const playlists = await db.find(
{ type: { $exists: false } },
{
count: 1,
title: 1,
_id: 1,
url: 1,
importDate: 1,
userAgent: 1,
filename: 1,
}
);
event.sender.send('playlist-all-result', {
payload: playlists,
});
}

/**
* Sets the user agent header for all http requests
* @param userAgent user agent to use
*/
setUserAgent(userAgent: string): void {
if (userAgent === undefined || userAgent === null || userAgent === '') {
userAgent = this.defaultUserAgent;
}
this.mainWindow.webContents.setUserAgent(userAgent);
console.log(`Success: Set "${userAgent}" as user agent header`);
}

/**
Expand All @@ -145,6 +187,9 @@ export class Api {
*/
setEpgWorkerWindow(workerWindow: BrowserWindow): void {
this.workerWindow = workerWindow;

// store default user agent as fallback
this.defaultUserAgent = this.workerWindow.webContents.getUserAgent();
}

/**
Expand Down
4 changes: 4 additions & 0 deletions ipc-commands.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// EPG related commands
export const EPG_FETCH = 'EPG:FETCH';
export const EPG_FETCH_DONE = 'EPG:FETCH_DONE';
export const EPG_ERROR = 'EPG:ERROR';
export const EPG_GET_PROGRAM = 'EPG:GET_PROGRAM';
export const EPG_GET_PROGRAM_DONE = 'EPG:GET_PROGRAM_DONE';

// Playlist related commands
export const PLAYLIST_SAVE_DETAILS = 'PLAYLIST:SAVE_DETAILS';
5 changes: 4 additions & 1 deletion src/app/home/home.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { Playlist } from './playlist.interface';
import { ElectronService } from '../services/electron.service';

/** Type to describe meta data of a playlist */
export type PlaylistMeta = Pick<Playlist, 'count' | 'title' | 'filename' | '_id' | 'url' | 'importDate'>;
export type PlaylistMeta = Pick<
Playlist,
'count' | 'title' | 'filename' | '_id' | 'url' | 'importDate' | 'userAgent'
>;

@Component({
selector: 'app-home',
Expand Down
1 change: 1 addition & 0 deletions src/app/home/playlist.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export interface Playlist {
favorites: string[];
count: number;
url?: string;
userAgent?: string;
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,60 @@
<h2 mat-dialog-title>
{{ 'HOME.PLAYLISTS.INFO_DIALOG.PLAYLIST_DETAILS' | translate }}
</h2>
<mat-dialog-content class="mat-typography">
<mat-form-field class="full-width">
<mat-label>{{
'HOME.PLAYLISTS.INFO_DIALOG.TITLE' | translate
}}</mat-label>
<input matInput [value]="playlist.title" disabled="true" />
</mat-form-field>
<mat-form-field class="full-width" *ngIf="playlist.url">
<mat-label>{{
'HOME.PLAYLISTS.INFO_DIALOG.FROM_URL' | translate
}}</mat-label>
<input matInput [value]="playlist.url" disabled="true" />
</mat-form-field>
<mat-form-field class="full-width">
<mat-label>{{
'HOME.PLAYLISTS.INFO_DIALOG.IMPORT_DATE' | translate
}}</mat-label>
<input matInput [value]="playlist.importDate | date" disabled="true" />
</mat-form-field>
<mat-form-field class="full-width">
<mat-label>{{
'HOME.PLAYLISTS.INFO_DIALOG.CHANNELS' | translate
}}</mat-label>
<input matInput [value]="playlist.count" disabled="true" />
</mat-form-field>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button mat-dialog-close cdkFocusInitial color="accent">
{{ 'HOME.PLAYLISTS.INFO_DIALOG.CLOSE' | translate }}
</button>
</mat-dialog-actions>
<form
[formGroup]="playlistDetails"
(ngSubmit)="saveChanges(playlistDetails.value)"
>
<h2 mat-dialog-title>
{{ 'HOME.PLAYLISTS.INFO_DIALOG.PLAYLIST_DETAILS' | translate }}
</h2>
<mat-dialog-content class="mat-typography">
<mat-form-field class="full-width">
<mat-label>{{
'HOME.PLAYLISTS.INFO_DIALOG.TITLE' | translate
}}</mat-label>
<input formControlName="title" matInput />
</mat-form-field>
<mat-form-field class="full-width" *ngIf="playlist.url">
<mat-label>{{
'HOME.PLAYLISTS.INFO_DIALOG.FROM_URL' | translate
}}</mat-label>
<input matInput formControlName="url" />
</mat-form-field>
<mat-form-field class="full-width">
<mat-label>{{
'HOME.PLAYLISTS.INFO_DIALOG.ORIGINAL_FILENAME' | translate
}}</mat-label>
<input matInput formControlName="filename" />
</mat-form-field>
<mat-form-field class="full-width">
<mat-label>{{
'HOME.PLAYLISTS.INFO_DIALOG.IMPORT_DATE' | translate
}}</mat-label>
<input matInput formControlName="importDate" />
</mat-form-field>
<mat-form-field class="full-width">
<mat-label>{{
'HOME.PLAYLISTS.INFO_DIALOG.CHANNELS' | translate
}}</mat-label>
<input matInput formControlName="count" />
</mat-form-field>
<mat-form-field class="full-width">
<mat-label>{{
'HOME.PLAYLISTS.INFO_DIALOG.USER_AGENT' | translate
}}</mat-label>
<input formControlName="userAgent" matInput />
</mat-form-field>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button
mat-flat-button
mat-dialog-close
color="accent"
type="submit"
[disabled]="!playlistDetails.valid || playlistDetails.pristine"
>
{{ 'HOME.PLAYLISTS.INFO_DIALOG.SAVE' | translate }}
</button>
<button mat-button mat-dialog-close cdkFocusInitial color="accent">
{{ 'HOME.PLAYLISTS.INFO_DIALOG.CLOSE' | translate }}
</button>
</mat-dialog-actions>
</form>
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { ElectronServiceStub } from './../../home.component.spec';
import { ElectronService } from './../../../services/electron.service';
import { TranslatePipe } from '@ngx-translate/core';
import { MockModule, MockPipe } from 'ng-mocks';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';

import { PlaylistInfoComponent } from './playlist-info.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

describe('PlaylistInfoComponent', () => {
let component: PlaylistInfoComponent;
Expand All @@ -14,11 +17,16 @@ describe('PlaylistInfoComponent', () => {
waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
MockModule(FormsModule),
MockModule(MatDialogModule),
MockModule(MatFormFieldModule),
ReactiveFormsModule,
],
declarations: [PlaylistInfoComponent, MockPipe(TranslatePipe)],
providers: [{ provide: MAT_DIALOG_DATA, useValue: {} }],
providers: [
{ provide: MAT_DIALOG_DATA, useValue: {} },
{ provide: ElectronService, useClass: ElectronServiceStub },
],
}).compileComponents();
})
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,62 @@
/* eslint-disable @typescript-eslint/unbound-method */
import { DatePipe } from '@angular/common';
import { Component, Inject } from '@angular/core';
import {
FormBuilder,
FormControl,
FormGroup,
Validators,
} from '@angular/forms';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { PLAYLIST_SAVE_DETAILS } from '../../../../../ipc-commands';
import { ElectronService } from '../../../services/electron.service';
import { Playlist } from '../../playlist.interface';

@Component({
selector: 'app-playlist-info',
templateUrl: './playlist-info.component.html',
styleUrls: ['./playlist-info.component.scss'],
providers: [DatePipe],
})
export class PlaylistInfoComponent {
/** Playlist object */
playlist: Playlist;

playlistDetails: FormGroup;

/**
* Creates an instance of the component and injects the selected playlist from the parent component
* @param data playlist object to show
* @param playlist playlist object to show
*/
constructor(@Inject(MAT_DIALOG_DATA) playlist: Playlist) {
constructor(
@Inject(MAT_DIALOG_DATA) playlist: Playlist,
datePipe: DatePipe,
formBuilder: FormBuilder,
private electronService: ElectronService
) {
this.playlist = playlist;
this.playlistDetails = formBuilder.group({
_id: playlist._id,
title: new FormControl(playlist.title, Validators.required),
userAgent: playlist.userAgent || '',
filename: new FormControl({
value: playlist.filename || '',
disabled: true,
}),
count: new FormControl({ value: playlist.count, disabled: true }),
importDate: new FormControl({
value: datePipe.transform(playlist.importDate),
disabled: true,
}),
url: new FormControl({ value: playlist.url, disabled: true }),
});
}

/**
* Saves updated playlist information
* @param data updated form data
*/
saveChanges(data: Pick<Playlist, '_id' | 'title' | 'userAgent'>): void {
this.electronService.ipcRenderer.send(PLAYLIST_SAVE_DETAILS, data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
(click)="$event.stopPropagation(); openInfoDialog(item)"
[matTooltip]="'HOME.PLAYLISTS.SHOW_DETAILS' | translate"
>
<mat-icon>info</mat-icon>
<mat-icon>edit</mat-icon>
</button>
<button
mat-icon-button
Expand Down

0 comments on commit a8167c4

Please sign in to comment.