rentgen/components/report-window/screenshot-generator.tsx

261 lines
11 KiB
TypeScript
Raw Permalink Normal View History

2022-05-21 14:42:15 +02:00
import React, { Fragment } from 'react';
import { RequestCluster } from '../../request-cluster';
import './screenshot-generator.scss';
2022-07-15 14:14:26 +02:00
const SS_URL = 'https://screenshot-service.internet-czas-dzialac.pl';
2022-06-17 11:47:51 +02:00
2022-05-22 16:49:24 +02:00
enum taskState {
WAITING = 'waiting',
RUNNING = 'running',
FINISHED = 'finished',
}
2022-06-17 11:47:51 +02:00
type Screenshot = {
url: string;
thumb_url: string;
2022-06-17 11:47:51 +02:00
domain: string;
2022-07-08 22:41:58 +02:00
filename: string;
2022-06-17 11:47:51 +02:00
found_headers: string[];
};
2022-05-22 16:49:24 +02:00
interface screenshotTask {
domains: string[];
2022-07-08 22:41:58 +02:00
elapsed_time_s: number;
current_action: string;
2022-07-08 22:41:58 +02:00
finished_time: number;
2022-05-22 16:49:24 +02:00
id: string;
2022-06-17 11:47:51 +02:00
images: Screenshot[];
2022-07-08 22:41:58 +02:00
jobs_ahead: number;
output: string;
processing_took: number;
request_time: number;
started_time: number;
status: taskState;
url: string;
waiting_took: number;
zip_url: string;
2022-07-15 10:25:20 +02:00
preview: string;
2022-05-22 16:49:24 +02:00
}
2022-05-21 14:42:15 +02:00
function createTaskEndpoint(visited_url: string, domains: string[]) {
2022-06-17 11:47:51 +02:00
return `${SS_URL}/api/requests?url=${visited_url}${domains.reduce(
2022-05-21 14:42:15 +02:00
(prev: string, curr: string) => prev + '&domains[]=' + curr,
''
)}`;
}
function createTask(visited_url: string, domains: string[]) {
return fetch(createTaskEndpoint(visited_url, domains), { method: 'POST' });
}
2022-05-22 16:49:24 +02:00
function pollTask(path: string): Promise<Response> {
return fetch(path, { method: 'GET' });
2022-05-21 14:42:15 +02:00
}
export default function ScreenshotGenerator({
visited_url,
clusters,
2022-05-22 16:49:24 +02:00
setReportWindowMode,
2022-07-08 22:41:58 +02:00
setRequestPath,
downloadFiles,
user_role,
2022-05-21 14:42:15 +02:00
}: {
visited_url: string;
clusters: Record<string, RequestCluster>;
2022-05-22 16:49:24 +02:00
setReportWindowMode: Function;
2022-07-08 22:41:58 +02:00
setRequestPath: Function;
downloadFiles: Function;
user_role: string;
2022-05-21 14:42:15 +02:00
}) {
2022-05-22 16:49:24 +02:00
const [mode, setMode] = React.useState<string>('idle');
2022-06-17 11:47:51 +02:00
const [images, setImages] = React.useState<Screenshot[]>([]);
2022-07-09 15:28:37 +02:00
const [taskId, setTaskId] = React.useState<string | null>(null);
2022-07-08 22:41:58 +02:00
const [output, setOutput] = React.useState<any>({});
const [currentAction, setCurrentAction] = React.useState<string>('');
2022-07-15 10:25:20 +02:00
const [preview, setPreview] = React.useState<string>('');
const [lastPreview, setLastPreview] = React.useState<string>('');
2022-05-22 16:49:24 +02:00
async function subscribeTask(path: string): Promise<screenshotTask> {
let response = { status: taskState.WAITING };
let last_preview = '';
2022-05-22 16:49:24 +02:00
while (response.status === taskState.WAITING || response.status === taskState.RUNNING) {
await new Promise((resolve) => setTimeout(resolve, 1000));
response = await (await pollTask(path)).json();
2022-06-17 11:47:51 +02:00
setImages((response as screenshotTask)?.images);
setCurrentAction((response as screenshotTask)?.current_action);
setLastPreview(last_preview);
2022-07-15 10:25:20 +02:00
setPreview((response as screenshotTask)?.preview);
last_preview = (response as screenshotTask)?.preview;
2022-07-09 15:28:37 +02:00
document.querySelector('.images')?.scrollTo({
top: document.querySelector('.images')?.scrollHeight,
behavior: 'smooth',
});
2022-05-22 16:49:24 +02:00
}
if (response.status === taskState.FINISHED) {
setMode('finished');
}
return response as screenshotTask;
}
2022-05-21 14:42:15 +02:00
return (
<div className="generator-container">
2022-05-22 16:49:24 +02:00
{mode === 'idle' ? (
2022-05-21 14:42:15 +02:00
<Fragment>
<h1>Przygotowanie zrzutów ekranów</h1>
2022-05-22 18:16:14 +02:00
<div className="container">
<h2>Notka informacyjna</h2>
2022-07-14 22:43:33 +02:00
<img
src="/assets/doctor_welcome.png"
2022-07-14 23:05:45 +02:00
style={{
width: '100%',
maxWidth: '360px',
float: 'right',
position: 'relative',
top: '-10px',
}}
2022-07-14 22:43:33 +02:00
/>
<Fragment>
<p>
2022-07-14 22:43:33 +02:00
W celu udokumentowania procesów przetwarzania danych, jakie wykryła
nasza wtyczka na tej stronie, warto wykonać zrzuty ekranu, na
których widać przeglądarkę z otwartymi narzędziami deweloperskimi,
ukazując wybrane elementy ruchu sieciowego generowanego przez
stronę.
</p>
2022-07-14 22:43:33 +02:00
<p>Jeżeli chcesz, wtyczka Rentgen może wygenerować je za Ciebie.</p>
<p>
Uwaga: aby to zrobić, adres aktualnie odwiedzonej podstrony
analizowanej witryny będzie wysłany na nasz serwer, aby na nim
odwiedzić podstronę i wykonać zrzuty ekranu.
</p>
<p>
Serwer, na którym jest wykonywana analiza należy do inicjatywy{' '}
<a href="https://www.internet-czas-dzialac.pl/contact/">
2022-07-14 23:05:45 +02:00
<i>Internet. Czas działać!</i>
2022-07-14 22:43:33 +02:00
</a>
. Zebrane dane nie wysyłane do żadnych podmiotów trzecich i
usuwane z serwera po 24 godzinach. Wysłanie na serwer informacji o
adresie przeglądanej strony jest konieczne, aby wykonać te zrzuty
ekranu w sposób automatyczny. Jeżeli nie chcesz korzystać z opcji
automatycznej, zachęcamy do wykonania zrzutów ekranu samodzielnie.
</p>
</Fragment>
2022-05-22 18:16:14 +02:00
</div>
2022-05-21 14:42:15 +02:00
2022-05-22 18:16:14 +02:00
<div className="buttons-container">
<button
className="sv_prev_btn"
onClick={() => {
setReportWindowMode('preview');
2022-07-08 22:41:58 +02:00
setRequestPath(null);
2022-05-22 18:16:14 +02:00
}}
>
Pomiń
</button>
<button
className="sv_next_btn"
onClick={async () => {
setMode('in_progress');
const task = await createTask(
visited_url,
Object.values(clusters)
.filter((cluster) => cluster.hasMarks())
.map((cluster) => cluster.id)
);
2022-05-22 18:16:14 +02:00
const urlArr = task.url.split('/');
setTaskId(urlArr[urlArr.length - 1]);
const response = await subscribeTask(task.url);
2022-06-17 11:47:51 +02:00
setImages(response.images);
setLastPreview(preview);
2022-07-15 10:25:20 +02:00
setPreview(response.preview);
2022-07-08 22:41:58 +02:00
setOutput(response);
setRequestPath(response.zip_url);
2022-05-22 18:16:14 +02:00
}}
>
Wygeneruj
</button>
</div>
2022-05-21 14:42:15 +02:00
</Fragment>
2022-05-22 16:49:24 +02:00
) : null}
{mode === 'in_progress' || mode === 'finished' ? (
2022-05-21 14:42:15 +02:00
<Fragment>
2022-07-03 19:35:36 +02:00
<h1>Przygotowanie zrzutów ekranów</h1>
2022-05-22 18:16:14 +02:00
<div className="container">
2022-07-03 19:35:36 +02:00
{mode === 'in_progress' ? (
<Fragment>
<h2>To może chwilkę zająć...</h2>
<p>
Nasz serwer właśnie odwiedza wskazaną przez Ciebie stronę
i przygotowuje zrzuty ekranów narzędzi deweloperskich.
</p>
<div>{currentAction}</div>
2022-07-03 19:35:36 +02:00
</Fragment>
) : null}
{mode === 'finished' ? (
<Fragment>
<h2>Gotowe!</h2>
<p>Zrzuty ekranów narzędzi deweloperskich gotowe do pobrania.</p>
</Fragment>
) : null}
2022-05-21 14:42:15 +02:00
2022-05-22 18:16:14 +02:00
<div className="images">
{mode === 'in_progress' ? (
<div
className="browser"
style={{
backgroundImage: `url(${SS_URL}${preview})${
lastPreview ? `, url(${SS_URL}${lastPreview})` : ''
}`,
}}
>
<div className="browser__header browser__header--in_progress">
<div className="browser__header--address-bar"></div>
<div className="browser__header--controls">···</div>
</div>
<div className="browser__content"></div>
</div>
) : null}
2022-06-17 11:47:51 +02:00
{images.map((screenshot) => {
2022-05-22 18:16:14 +02:00
return (
<div
2022-06-17 11:47:51 +02:00
key={`${taskId}_${screenshot.url}`}
2022-05-22 18:16:14 +02:00
className="browser browser--filled"
style={{
backgroundImage: `url(${SS_URL}${screenshot.thumb_url})`,
2022-05-22 18:16:14 +02:00
}}
>
<div className="browser__header">
<div className="browser__header--address-bar">
🕸 {screenshot.domain}
2022-05-22 18:16:14 +02:00
</div>
<div className="browser__header--controls">···</div>
2022-05-22 16:49:24 +02:00
</div>
2022-05-22 18:16:14 +02:00
<div className="browser__content"></div>
</div>
);
})}
</div>
</div>
<div className="buttons-container">
{mode === 'finished' ? (
2022-07-03 19:35:36 +02:00
<Fragment>
2022-07-08 22:41:58 +02:00
<button
className="sv_next_btn"
onClick={() => {
downloadFiles(`${SS_URL}${output.zip_url}`);
setReportWindowMode('preview');
}}
>
2022-07-03 19:35:36 +02:00
Pobierz zrzuty ekranów i przejdź dalej
</button>
</Fragment>
2022-05-22 16:49:24 +02:00
) : null}
</div>
2022-05-21 14:42:15 +02:00
</Fragment>
2022-05-22 16:49:24 +02:00
) : null}
2022-05-21 14:42:15 +02:00
</div>
);
}