Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 79x 79x 79x 79x 79x 53x 53x 53x 53x 53x 53x 53x 53x 53x | import { HttpClient, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { autorun } from 'mobx';
import { catchError, map, Observable, of, throwError } from 'rxjs';
import { mapRef, Ref } from '../../model/ref';
import { Resource } from '../../model/resource';
import { catchAll } from '../../mods/sync/scrape';
import { Store } from '../../store/store';
import { params, sanitizePath } from '../../util/http';
import { ConfigService } from '../config.service';
import { LoginService } from '../login.service';
import { RefService } from './ref.service';
@Injectable({
providedIn: 'root',
})
export class ProxyService {
private cacheList = new Set<string>();
private scraping: Ref[] = [];
constructor(
private http: HttpClient,
private config: ConfigService,
private store: Store,
private refs: RefService,
private login: LoginService,
) {
autorun(() => {
Iif (store.eventBus.event === '_plugin/cache:clear-cache') {
this.clearDeleted(store.account.origin).subscribe();
}
});
}
private get base() {
return this.config.api + '/api/v1/proxy';
}
prefetch(url: string, origin = '', filename = 'file') {
if (url.startsWith('data:')) return;
if (this.cacheList.has(origin + url)) return;
this.cacheList.add(origin + url);
const s = () => {
this.http.get(`${this.base}/prefetch/${sanitizePath(this.scraping[0]?.title?.trim() || this.scraping[0].url)}`, {
params: params({ url: this.scraping[0].url, origin: this.scraping[0].origin }),
}).pipe(
catchError(() => of(null)),
).subscribe(() => {
this.scraping.shift();
if (this.scraping.length) s();
});
};
this.scraping.push({ url, origin, title: filename });
if (this.scraping.length === 1) s();
}
fetch(url: string, origin = '', filename = 'file', thumbnail?: boolean): Observable<Resource> {
this.cacheList.add(origin + url);
return this.http.get(`${this.base}/${sanitizePath(filename)}`, {
params: params({ url, origin, thumbnail }),
observe: 'response',
responseType: 'arraybuffer',
}).pipe(
map(req => ({
url: this.getFetch(url, origin, filename, thumbnail),
mimeType: req.headers.get('Content-Type'),
data: req.body
})),
catchError(err => this.login.handleHttpError(err)),
);
}
save(file: File, origin = ''): Observable<HttpEvent<Ref>> {
return this.http.post(`${this.base}`, file, {
params: params({ title: file.name, mime: file.type, origin }),
reportProgress: true,
observe: 'events',
}).pipe(
map(res => res as HttpEvent<Ref>),
map(res => {
// @ts-ignore
if ('body' in res && res.body) res.body = mapRef(res.body);
return res;
}),
catchError(err => this.login.handleHttpError(err)),
);
}
getFetch(url: string, origin = '', filename = 'file', thumbnail = false) {
if (!url) return '';
if (url.startsWith('data:')) return url;
if (this.config.prefetch && this.store.account.user) this.prefetch(url, origin, filename);
if (thumbnail) return `${this.base}/${sanitizePath(filename.trim())}?thumbnail=true&url=${encodeURIComponent(url)}&origin=${origin}`;
return `${this.base}/${sanitizePath(filename.trim())}?url=${encodeURIComponent(url)}&origin=${origin}`;
}
isProxied(url?: string) {
return url && url.startsWith(this.base);
}
defaults(): Observable<any> {
return this.refs.update(catchAll);
}
clearDeleted(origin: string) {
return this.http.delete(this.base, {
params: { origin },
}).pipe(
catchError(err => this.login.handleHttpError(err)),
catchError(err => {
// TODO: Better error message
alert(err.message);
return throwError(() => err);
}),
);
}
}
|