Skip to content

Commit

Permalink
Refactor, refresh image
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhiming Zhang committed Nov 9, 2023
1 parent 3081664 commit 5d7bee0
Showing 1 changed file with 115 additions and 79 deletions.
194 changes: 115 additions & 79 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,120 @@ interface APODResponse {
url: string;
};

class APODWidget extends Widget {
/**
* Construct a new APOD widget.
*/
constructor() {
super();

this.addClass('my-apodWidget');

// Add an image element to the panel
this.img = document.createElement('img');
this.node.appendChild(this.img);

// Add a summary element to the panel
this.summary = document.createElement('p');
this.node.appendChild(this.summary);
}

/**
* The image element associated with the widget.
*/
readonly img: HTMLImageElement;

/**
* The summary text element associated with the widget.
*/
readonly summary: HTMLParagraphElement;

/**
* Handle update requests for the widget.
*/
async updateAPODImage(): Promise<void> {

const response = await fetch(`https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=${this.randomDate()}`);

if (!response.ok) {
const data = await response.json();
if (data.error) {
this.summary.innerText = data.error.message;
} else {
this.summary.innerText = response.statusText;
}
return;
}

const data = await response.json() as APODResponse;

if (data.media_type === 'image') {
// Populate the image
this.img.src = data.url;
this.img.title = data.title;
this.summary.innerText = data.title;
if (data.copyright) {
this.summary.innerText += ` (Copyright ${data.copyright})`;
}
} else {
this.summary.innerText = 'Random APOD fetched was not an image.';
}
}

/**
* Get a random date string in YYYY-MM-DD format.
*/
randomDate(): string {
const start = new Date(2010, 1, 1);
const end = new Date();
const randomDate = new Date(start.getTime() + Math.random()*(end.getTime() - start.getTime()));
return randomDate.toISOString().slice(0, 10);
}
}

/**
* Activate the APOD widget extension.
*/
function activate(app: JupyterFrontEnd, palette: ICommandPalette) {
console.log('JupyterLab extension jupyterlab_apod is activated!');

// Define a widget creator function
const newWidget = () => {
const content = new APODWidget();
const widget = new MainAreaWidget({content});
widget.id = 'apod-jupyterlab';
widget.title.label = 'Astronomy Picture';
widget.title.closable = true;
return widget;
}

// Create a single widget
let widget = newWidget();

// Add an application command
const command: string = 'apod:open';
app.commands.addCommand(command, {
label: 'Random Astronomy Picture',
execute: () => {
// Regenerate the widget if disposed
if (widget.isDisposed) {
widget = newWidget();
}
if (!widget.isAttached) {
// Attach the widget to the main work area if it's not there
app.shell.add(widget, 'main');
}
// Refresh the picture in the widget
widget.content.updateAPODImage();
// Activate the widget
app.shell.activateById(widget.id);
}
});

// Add the command to the palette.
palette.addItem({ command, category: 'Tutorial' });
}

/**
* Initialization data for the jupyterlab_apod extension.
*/
Expand All @@ -23,85 +137,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
description: 'A JupyterLab extension.',
autoStart: true,
requires: [ICommandPalette],
activate: async (app: JupyterFrontEnd, palette: ICommandPalette) => {
console.log('JupyterLab extension jupyterlab_apod is activated!');

// Define a widget creator function,
// then call it to make a new widget
const newWidget = async () => {
// Create a blank content widget inside of a MainAreaWidget
const content = new Widget();
content.addClass('my-apodWidget');
const widget = new MainAreaWidget({ content });
widget.id = 'apod-jupyterlab';
widget.title.label = 'Astronomy Picture';
widget.title.closable = true;

// Add an image element to the content
let img = document.createElement('img');
content.node.appendChild(img);

let summary = document.createElement('p');
content.node.appendChild(summary);

// Get a random date string in YYYY-MM-DD format
function randomDate() {
const start = new Date(2010, 1, 1);
const end = new Date();
const randomDate = new Date(start.getTime() + Math.random()*(end.getTime() - start.getTime()));
return randomDate.toISOString().slice(0, 10);
}

// Fetch info about a random picture
const response = await fetch(`https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=${randomDate()}`);
if (!response.ok) {
const data = await response.json();
if (data.error) {
summary.innerText = data.error.message;
} else {
summary.innerText = response.statusText;
}
} else {
const data = await response.json() as APODResponse;

if (data.media_type === 'image') {
// Populate the image
img.src = data.url;
img.title = data.title;
summary.innerText = data.title;
if (data.copyright) {
summary.innerText += ` (Copyright ${data.copyright})`;
}
} else {
summary.innerText = 'Random APOD fetched was not an image.';
}
}

return widget;
}
let widget = await newWidget();

// Add an application command
const command: string = 'apod:open';
app.commands.addCommand(command, {
label: 'Random Astronomy Picture',
execute: async () => {
// Regenerate the widget if disposed
if (widget.isDisposed) {
widget = await newWidget();
}
if (!widget.isAttached) {
// Attach the widget to the main work area if it's not there
app.shell.add(widget, 'main');
}
// Activate the widget
app.shell.activateById(widget.id);
}
});

// Add the command to the palette.
palette.addItem({ command, category: 'Tutorial' });
}
activate: activate
};

export default plugin;

0 comments on commit 5d7bee0

Please sign in to comment.