Display bus departures generated by script; get weather temperature from cloud
This commit is contained in:
parent
857ba29540
commit
f88501078f
2 changed files with 126 additions and 60 deletions
127
src/App.tsx
127
src/App.tsx
|
|
@ -5,11 +5,21 @@ import "./App.css";
|
||||||
import { TChildren, TRssItem, TRssRawItem, TDepartures } from "./types";
|
import { TChildren, TRssItem, TRssRawItem, TDepartures } from "./types";
|
||||||
import { convertXML } from "simple-xml-to-json";
|
import { convertXML } from "simple-xml-to-json";
|
||||||
|
|
||||||
|
const MAIN_URL = "http://10.0.0.30:3000/";
|
||||||
const MAIN_HEADER_FONT_SIZE = 50;
|
const MAIN_HEADER_FONT_SIZE = 50;
|
||||||
const DATA_FONT_SIZE = 42;
|
const DATA_FONT_SIZE = 42;
|
||||||
const TEMPERATURE_URL = "http://10.0.0.106:3000/gettemperature";
|
const TEMPERATURE_URL = `${MAIN_URL}gettemperature`;
|
||||||
const DEPARTURES_URL = "http://10.0.0.106:3000/getdepartures";
|
const DEPARTURES_URL = `${MAIN_URL}getdepartures`;
|
||||||
|
|
||||||
|
const GET_RSSFEED_FROM_FILE_URL = `${MAIN_URL}get_rssfeed_data`;
|
||||||
|
const SET_RSSFEED_TO_FILE_URL = `${MAIN_URL}set_rssfeed_data`;
|
||||||
const SOKOLOV_RSS_URL = "https://www.sokolov.cz/rss/";
|
const SOKOLOV_RSS_URL = "https://www.sokolov.cz/rss/";
|
||||||
|
const NUMBER_OF_RSSFEED_REQUESTS_BEFORE_LOADING_IT_FROM_FILE = 9;
|
||||||
|
let rssfeedRequestSuccessful = false;
|
||||||
|
let getRssFeedAttempts = 0;
|
||||||
|
const REPEAT_NORMAL_RSSFEED_REQUEST_TIME = 2; // After how long should I get RSS feed? In hours.
|
||||||
|
const REPEAT_RSS_REQUEST_TIME_AFTER_FAIL = 30 * 1000; //20 seconds
|
||||||
|
|
||||||
const DAYS_OF_WEEK = [
|
const DAYS_OF_WEEK = [
|
||||||
"Neděle",
|
"Neděle",
|
||||||
"Pondělí",
|
"Pondělí",
|
||||||
|
|
@ -19,8 +29,10 @@ const DAYS_OF_WEEK = [
|
||||||
"Pátek",
|
"Pátek",
|
||||||
"Sobota",
|
"Sobota",
|
||||||
];
|
];
|
||||||
|
|
||||||
const INACTIVITY_LIMIT = 300000;
|
const INACTIVITY_LIMIT = 300000;
|
||||||
const OPTIONS = { hour12: false };
|
const OPTIONS = { hour12: false };
|
||||||
|
|
||||||
// colors in sokolov website
|
// colors in sokolov website
|
||||||
const LOGO_COLOR = "#82c55b"; // green
|
const LOGO_COLOR = "#82c55b"; // green
|
||||||
const FONT_COLOR = "#00367b"; // blue
|
const FONT_COLOR = "#00367b"; // blue
|
||||||
|
|
@ -43,10 +55,10 @@ function onInactive(ms: number, cb: () => void) {
|
||||||
window.onkeydown =
|
window.onkeydown =
|
||||||
window.onkeyup =
|
window.onkeyup =
|
||||||
window.onfocus =
|
window.onfocus =
|
||||||
function () {
|
function() {
|
||||||
clearTimeout(wait);
|
clearTimeout(wait);
|
||||||
wait = setTimeout(cb, ms);
|
wait = setTimeout(cb, ms);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|
@ -57,7 +69,7 @@ function App() {
|
||||||
var [chosenArticle, setChosenArticle] = useState({ clicked: false, url: "" });
|
var [chosenArticle, setChosenArticle] = useState({ clicked: false, url: "" });
|
||||||
var [feedData, setFeedData] = useState<TRssItem[]>([
|
var [feedData, setFeedData] = useState<TRssItem[]>([
|
||||||
{
|
{
|
||||||
title: "Chyba stažení dat, kontaktujte prosím administrátora",
|
title: "",
|
||||||
description: "",
|
description: "",
|
||||||
link: "",
|
link: "",
|
||||||
pubDate: new Date(),
|
pubDate: new Date(),
|
||||||
|
|
@ -67,7 +79,7 @@ function App() {
|
||||||
|
|
||||||
// check, how long is user inactive, if reading an article. If more than 5 minutes, we load default screen
|
// check, how long is user inactive, if reading an article. If more than 5 minutes, we load default screen
|
||||||
function idle() {
|
function idle() {
|
||||||
onInactive(INACTIVITY_LIMIT, function () {
|
onInactive(INACTIVITY_LIMIT, function() {
|
||||||
window.onmousemove =
|
window.onmousemove =
|
||||||
window.onmousedown =
|
window.onmousedown =
|
||||||
window.onmousemove =
|
window.onmousemove =
|
||||||
|
|
@ -78,7 +90,7 @@ function App() {
|
||||||
window.onkeydown =
|
window.onkeydown =
|
||||||
window.onkeyup =
|
window.onkeyup =
|
||||||
window.onfocus =
|
window.onfocus =
|
||||||
null;
|
null;
|
||||||
setChosenArticle({ clicked: false, url: "" });
|
setChosenArticle({ clicked: false, url: "" });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -114,14 +126,14 @@ function App() {
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": "*",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then(response => {
|
||||||
let t = parseFloat(response.data);
|
let t = parseFloat(response.data);
|
||||||
//console.log(t);
|
//console.log(t);
|
||||||
if (isNaN(t)) return;
|
if (isNaN(t)) return;
|
||||||
|
|
||||||
setTemperature(t);
|
setTemperature(t);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch(error => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -132,11 +144,11 @@ function App() {
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": "*",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then(response => {
|
||||||
const departures: TDepartures = response.data;
|
const departures: TDepartures = response.data;
|
||||||
setDepartures(departures);
|
setDepartures(departures);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch(error => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +168,7 @@ function App() {
|
||||||
setDayOfWeek(DAYS_OF_WEEK[date.getDay()]);
|
setDayOfWeek(DAYS_OF_WEEK[date.getDay()]);
|
||||||
|
|
||||||
msToMidnight = milisecondsToMidnight();
|
msToMidnight = milisecondsToMidnight();
|
||||||
console.log("setDay called, ms to midnight", msToMidnight);
|
//console.log("setDay called, ms to midnight", msToMidnight);
|
||||||
updateDayOfWeek = setInterval(getDay, msToMidnight);
|
updateDayOfWeek = setInterval(getDay, msToMidnight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,13 +189,49 @@ function App() {
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
function getOrSetRssFeedWithFile(rssFeedData: TRssItem[]) {
|
||||||
|
if (rssFeedData.length === 0) {
|
||||||
|
axios(GET_RSSFEED_FROM_FILE_URL, {
|
||||||
|
headers: {
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
let rssFeedData: TRssItem[] = response.data;
|
||||||
|
console.log("rssfeed data loaded from file: ", rssFeedData);
|
||||||
|
rssFeedData = rssFeedData.map(item => {
|
||||||
|
return { ...item, pubDate: new Date(item.pubDate) };
|
||||||
|
})
|
||||||
|
setFeedData(rssFeedData);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
axios(SET_RSSFEED_TO_FILE_URL, {
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
},
|
||||||
|
data: rssFeedData
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
console.log("set rssfeed data response: ", response);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// rss feed to get articles from sokolov website
|
// rss feed to get articles from sokolov website
|
||||||
const getRssFeed = () => {
|
const getRssFeed = () => {
|
||||||
|
//console.log('volam get feed');
|
||||||
axios(SOKOLOV_RSS_URL)
|
axios(SOKOLOV_RSS_URL)
|
||||||
.then((response) => {
|
.then(response => {
|
||||||
const myJson = convertXML(response?.data);
|
const myJson = convertXML(response?.data);
|
||||||
|
|
||||||
console.log("--------", JSON.stringify(myJson));
|
//console.log("--------", JSON.stringify(myJson));
|
||||||
let data: TChildren = myJson?.rss?.children[0]?.channel?.children;
|
let data: TChildren = myJson?.rss?.children[0]?.channel?.children;
|
||||||
|
|
||||||
if (!Array.isArray(data)) return;
|
if (!Array.isArray(data)) return;
|
||||||
|
|
@ -204,35 +252,36 @@ function App() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(result);
|
rssfeedRequestSuccessful = true;
|
||||||
|
//console.log("rssfeed obtained");
|
||||||
|
//console.log(result);
|
||||||
|
//getOrSetRssFeedWithFile(result);
|
||||||
setFeedData(result);
|
setFeedData(result);
|
||||||
})
|
})
|
||||||
.catch((e) => console.log(e));
|
.catch(_ => {
|
||||||
|
//getRssFeedAttempts++;
|
||||||
|
//if (!rssfeedRequestSuccessful && (getRssFeedAttempts > NUMBER_OF_RSSFEED_REQUESTS_BEFORE_LOADING_IT_FROM_FILE && getRssFeedAttempts < NUMBER_OF_RSSFEED_REQUESTS_BEFORE_LOADING_IT_FROM_FILE + 2)) {
|
||||||
|
// getOrSetRssFeedWithFile([]);
|
||||||
|
//}
|
||||||
|
if (!rssfeedRequestSuccessful) {
|
||||||
|
//console.log('Error obtaining rssfeed, repeating ...');
|
||||||
|
setTimeout(getRssFeed, REPEAT_RSS_REQUEST_TIME_AFTER_FAIL);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getRssFeed();
|
getRssFeed();
|
||||||
var feed = setInterval(getRssFeed, 6 * 60 * 60 * 1000); //raz za 6 hodin
|
// ODKOMENTUJ NASLEDUJUCE RIADKY, AK CHCES, ABY SA RSS FEEDY NACITAVALI CASTEJSIE
|
||||||
|
var feed = setInterval(getRssFeed, REPEAT_NORMAL_RSSFEED_REQUEST_TIME * 60 * 60 * 1000); //raz za REPEAT_NORMAL_RSSFEED_REQUEST_TIME hodin
|
||||||
return function cleanup() {
|
return function cleanup() {
|
||||||
clearInterval(feed);
|
clearInterval(feed);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const buildFeedView = (): React.JSX.Element[] => {
|
const buildFeedView = (): React.JSX.Element[] => {
|
||||||
if (
|
if (feedData[0].title === "") {
|
||||||
feedData[0].title ===
|
return [];
|
||||||
"Chyba stažení dat, kontaktujte prosím administrátora"
|
|
||||||
) {
|
|
||||||
return [
|
|
||||||
<Box sx={{ padding: 2 }}>
|
|
||||||
<Typography sx={{ color: LOGO_COLOR }} variant="h6">
|
|
||||||
{feedData[0].title}
|
|
||||||
</Typography>
|
|
||||||
<Typography sx={{ color: FONT_COLOR }} variant="subtitle2">
|
|
||||||
{feedData[0].pubDate.toLocaleDateString("cs-Cz")}
|
|
||||||
</Typography>
|
|
||||||
</Box>,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return feedData.map((item, index) => {
|
return feedData.map((item, index) => {
|
||||||
|
|
@ -259,6 +308,7 @@ function App() {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
sokolovFeed = buildFeedView();
|
sokolovFeed = buildFeedView();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -297,7 +347,7 @@ function App() {
|
||||||
<td align="left">SMĚR</td>
|
<td align="left">SMĚR</td>
|
||||||
<td align="center">PŘÍJEZD</td>
|
<td align="center">PŘÍJEZD</td>
|
||||||
</tr>
|
</tr>
|
||||||
{departures.map(function (item, i) {
|
{departures.map(function(item, i) {
|
||||||
return (
|
return (
|
||||||
<tr key={i} style={{ fontSize: DATA_FONT_SIZE }}>
|
<tr key={i} style={{ fontSize: DATA_FONT_SIZE }}>
|
||||||
<td align="center">{item[0]}</td>
|
<td align="center">{item[0]}</td>
|
||||||
|
|
@ -357,6 +407,15 @@ const departures = [
|
||||||
["3", "08:10", "Závodu míru", ["X", "32"]],
|
["3", "08:10", "Závodu míru", ["X", "32"]],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// ziskavaju sa requestom na web sokolova
|
||||||
|
let departures_new = [
|
||||||
|
["6", "07:23", "Sídl.Michal škola", "X2"],
|
||||||
|
["3", "07:27", "Sídliště Michal", "X2"],
|
||||||
|
["2", "07:31", "Sídliště Michal", "X1"],
|
||||||
|
["3", "07:34", "Závodu míru", "X3"],
|
||||||
|
["4", "07:34", "Závodu míru", "X1"],
|
||||||
|
]
|
||||||
|
|
||||||
// pubDate is date object
|
// pubDate is date object
|
||||||
const dummyData = [
|
const dummyData = [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
59
src/types.d.ts
vendored
59
src/types.d.ts
vendored
|
|
@ -6,43 +6,50 @@ export type TRssItem = {
|
||||||
link: string;
|
link: string;
|
||||||
pubDate: Date;
|
pubDate: Date;
|
||||||
guid: string;
|
guid: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TContent = { content: string };
|
|
||||||
|
|
||||||
export type TRssRawItem = {
|
export type TContent = { content: string };
|
||||||
|
|
||||||
|
export type TRssRawItem = {
|
||||||
item: {
|
item: {
|
||||||
children: [
|
children: [
|
||||||
{ title: TContent },
|
{ title: TContent },
|
||||||
{ link: TContent },
|
{ link: TContent },
|
||||||
{ description: TContent },
|
{ description: TContent },
|
||||||
{ pubDate: { content: Date } },
|
{ pubDate: { content: Date } },
|
||||||
{ guid: TContent }
|
{ guid: TContent }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TChildren = {
|
export type TChildren = {
|
||||||
children: [
|
children: [
|
||||||
|{
|
| {
|
||||||
title: TContent;
|
title: TContent;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
link: TContent;
|
link: TContent;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
description: TContent;
|
description: TContent;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
ttl: TContent;
|
ttl: TContent;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
lastBuildDate: TContent;
|
lastBuildDate: TContent;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
item: RssRawItem;
|
item: RssRawItem;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDepartures = array<string, string, string, string[]>[];
|
export type TDepartures = array<number, string, string, string>[];
|
||||||
|
|
||||||
|
export type TSlackData = {
|
||||||
|
msg: string
|
||||||
|
bot_name: string
|
||||||
|
bot_icon: string
|
||||||
|
channel: string
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue