Skip to content

Commit

Permalink
Fetching past the last 15 images for the uploading of last image (#477)
Browse files Browse the repository at this point in the history
  • Loading branch information
Thibault authored and GitHub committed Aug 5, 2025
1 parent f97e0bd commit 4ddd6c5
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 85 deletions.
44 changes: 36 additions & 8 deletions backend/src/api/slack/controllers/slack.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,46 @@
const fetchImagesFromSlack = require("../services/slack");
const fetch = require("node-fetch");

let cachedImage = null;
let cacheTimestamp = null;

module.exports = {
fetchImages: async (ctx) => {
const CACHE_DURATION = 60 * 1000; // 1 minute
const now = Date.now();

if (
cachedImage &&
cacheTimestamp &&
now - cacheTimestamp < CACHE_DURATION
) {
ctx.body = cachedImage;
return;
}
try {
const images = await strapi
.service("api::slack.slack")
.fetchImagesFromSlack();
return ctx.send(images);
const { satName } = ctx.request.body;

const message = await fetchImagesFromSlack.fetchImagesFromSlack(satName);
cachedImage = {
success: true,
message: {
id: message.files[0].id,
name: message.files[0].name,
permalink_public: message.files[0].permalink_public,
},
};
cacheTimestamp = now;
if (message) {
ctx.body = cachedImage;
} else {
ctx.body = {
success: false,
error: "No message found",
};
}
} catch (error) {
return ctx.throw(
500,
"Error fetching images from Slack: " + error.message
);
ctx.status = 500;
ctx.body = { error: error.message };
}
},
getSharedURL: async (ctx) => {
Expand Down
2 changes: 1 addition & 1 deletion backend/src/api/slack/routes/slack.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
module.exports = {
routes: [
{
method: "GET",
method: "POST",
path: "/slack-images",
handler: "slack.fetchImages",
config: {
Expand Down
60 changes: 31 additions & 29 deletions backend/src/api/slack/services/slack.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,39 @@ const slack = new WebClient(process.env.SLACK_BOT_TOKEN);
* slack service
*/

let cachedImages = null;
let cacheTimestamp = null;

module.exports = {
fetchImagesFromSlack: async () => {
const CACHE_DURATION = 60 * 1000; // 1 minute
const now = Date.now();

if (
cachedImages &&
cacheTimestamp &&
now - cacheTimestamp < CACHE_DURATION
) {
console.log("Returning cached images");
return cachedImages;
}

fetchImagesFromSlack: async (satellite) => {
try {
const result = await slack.conversations.history({
channel: process.env.SLACK_CHANNEL_ID,
limit: 15,
});
console.log("Fetched images from Slack:", result.messages.length);
cachedImages = result.messages.filter(
(msg) =>
msg.bot_profile?.name === "hypso1bot" &&
msg.files &&
msg.files.some((file) => file.mimetype.startsWith("image/"))
);
cacheTimestamp = now;
return cachedImages;
let cursor = null;
let hasMore = true;
let image = null;
while (hasMore) {
const result = await slack.conversations.history({
channel: process.env.SLACK_CHANNEL_ID,
limit: 15,
cursor: cursor,
oldest: "0",
inclusive: true,
});
if (!result.messages || result.messages.length === 0) {
console.log("No messages found in the channel.");
return null;
}
for (const message of result.messages) {
if (message.text && message.text.includes(satellite)) {
if (!image) {
image = message;
break;
}
}
}
hasMore = result.has_more;
cursor = result.response_metadata
? result.response_metadata.next_cursor
: null;
if (image) break;
}
return image;
} catch (error) {
console.error("Error fetching images from Slack:", error);
throw error;
Expand Down
68 changes: 33 additions & 35 deletions frontend/src/app/satellites/[satelliteSlug]/_infoSat/satImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,54 +63,52 @@ export default function SatImage({
[],
);

const getMesasgeBySatellite = useCallback(
async (satName: string) => {
const requestDetails = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
satName: satName,
}),
};

const response = await fetch(
STRAPI_URL + "/api/slack-images",
requestDetails,
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json();
return data.message;
},
[STRAPI_URL],
);

useEffect(() => {
async function fetchSlackImages() {
try {
setLoading(true);
const response = await fetch(STRAPI_URL + "/api/slack-images");
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json();
const satName = satNumToEntry[noradID as SatelliteNumber]?.name;
interface SlackFile {
id: number;
name: string;
permalink_public: string;
}

interface SlackMessage {
text: string;
files: SlackFile[];
}

const rightMessage: SlackMessage | undefined = (
data as SlackMessage[]
).find((message: SlackMessage) => {
if (noradID !== undefined) {
const satName: string | undefined =
satNumToEntry[noradID as SatelliteNumber]?.name;
if (satName && message.text.includes(satName)) {
return true;
}
}
return false;
});
if (!rightMessage) {
console.warn("No matching satellite image found.");
setError(
"No matching satellite image found. Try again later when a new image is uploaded.",
);
return;
}
const rightFile: SlackFile | undefined = rightMessage?.files[0];
makeTheImagePublic(rightFile?.id as number).catch((err) => {
const message = (await getMesasgeBySatellite(
satName as string,
)) as SlackFile;
makeTheImagePublic(message?.id as number).catch((err) => {
console.error("Error making image public:", err);
setError("Failed to make image public.");
});
const imageUrl = createImageUrl(
rightFile?.permalink_public as string,
rightFile?.name as string,
message?.permalink_public as string,
message?.name as string,
);
setSatImage(imageUrl ?? null);
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export default function SatTelemetry({

const chartConfigs = [
{
title: "Battery Voltage",
title: "EPS Battery Voltage",
yAxisTitle: "Voltage (V)",
series: [
{
Expand All @@ -185,28 +185,28 @@ export default function SatTelemetry({
valueSuffix: " V",
},
{
title: "Battery Current",
title: "EPS Battery Current",
yAxisTitle: "Current (A)",
series: chartDataIBatt,
valueSuffix: " A",
},
{
title: "Panel Temperatures",
title: "EPS Panel Temperatures",
yAxisTitle: "Temperature (°C)",
series: tempPanelChart,
valueSuffix: " °C",
},

{
title: "Solar Panel Temperatures",
title: "EPS Solar Panel Temperatures",
yAxisTitle: "Temperature (°C)",
series: solarPanelChartData,
valueSuffix: " °C",
description:
"There is that much difference in temperature between some solar panels because those panels point more or less towards the sun.",
},
{
title: "Uptime",
title: "EPS Uptime",
yAxisTitle: "Uptime (weeks)",
series: [
{ name: "Uptime", data: chartDataUptime, color: "orange" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@ const OrbitDataGraph: React.FC<OrbitDataProps> = ({ orbitalData }) => {
data.semiMajorAxis,
]);

console.log(
"Filtered orbital data:",
filteredData.map((data: ChartData) => [
data.epoch.getTime(),
parseFloat(data.inclination),
]),
);
const optChart = createStockChartBaseConfig({
title: "Orbital Graph Data",
yAxisArray: [
Expand Down

0 comments on commit 4ddd6c5

Please sign in to comment.