Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Backend Logic to interactions with ZenodoAPI #50

Merged
merged 5 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,21 @@ jobs:
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Set image tags
id: set-tags
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:dev" >> $GITHUB_ENV
else
echo "tags=${{ steps.meta.outputs.tags }}" >> $GITHUB_ENV
fi
- name: Build and push Docker image
id: push
uses: docker/[email protected]
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
tags: ${{ env.tags }}
labels: ${{ steps.meta.outputs.labels }}

# This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see "[AUTOTITLE](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds)."
Expand Down
43 changes: 31 additions & 12 deletions src/API/API_functions.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { requestAPI } from './handler';
import { UploadPayload } from '../components/type';

export async function getEnvVariable(varName: string) {
try {
Expand All @@ -17,24 +18,38 @@ export async function setEnvVariable(key: string, value: string) {
method: 'POST',
body: JSON.stringify({ key, value })
});
//console.log(data);
} catch (error) {
console.error(`Error setting ${key}:`, error);
}
}

export async function testZenodoConnection() {
try {
const data = await requestAPI('zenodo-jupyterlab/test-connection', {
/* const data = await requestAPI('zenodo-jupyterlab/test-connection', {
method: 'GET'
});
//console.log(data);
}); */
const data = await requestAPI('zenodo-jupyterlab/zenodo-api', {
method: 'POST',
body: JSON.stringify({action: 'check-connection'}),
})
return data;
} catch (error) {
console.error(`Error testing connection:`, error);
}
}

export async function depositUpload(payload: UploadPayload) {
try {
const data = await requestAPI('zenodo-jupyterlab/zenodo-api', {
method: 'POST',
body: JSON.stringify(payload),
});
return data;
} catch (error) {
console.error('Error uploading info:', error);
}
}

export async function searchRecords(search_field: string, page: number, kwargs: Record<string, any> = {}) {
try {
let url = `zenodo-jupyterlab/search-records?search_field=${encodeURIComponent(search_field)}&page=${encodeURIComponent(page)}`;
Expand Down Expand Up @@ -84,14 +99,18 @@ export async function getServerRootDir() {
}
}

/* export async function runPythonCode(code: string) {
export async function fetchSandboxStatus() {
try {
const data = await requestAPI('zenodo-jupyterlab/code', {
method: 'POST',
body: JSON.stringify({ code: code })
});
console.log(data);
let response = await fetch('zenodo-jupyterlab/env?env_var=ZENODO_SANDBOX');
if (response.ok) {
let data = await response.json();
return data.ZENODO_SANDBOX;
} else {
console.error('Failed to fetch sandbox status');
return null;
}
} catch (error) {
console.error('Error running code:', error);
console.error('Error fetching sandbox status:', error);
return null;
}
} */
}
2 changes: 0 additions & 2 deletions src/components/FileBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,7 @@ const FileBrowser: React.FC<FileBrowserProps> = ({ onSelectFile }) => {
};

const handleBreadcrumbClick = (path: string) => {
console.log('Breadcrumb clicked, path:', path);
if (path !== currentPath) {
//console.log('Updating currentPath from', currentPath, 'to', path);
setCurrentPath(path);
}
};
Expand Down
56 changes: 33 additions & 23 deletions src/components/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,21 @@ const useStyles = createUseStyles({
'&:hover': {
backgroundColor: '#45a049',
},
}
},
checkboxContainer: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: '10px',
flexDirection: 'row',
},
checkboxLabel: {
display: 'flex',
alignItems: 'center',
},
checkboxInput: {
marginRight: '5px',
},
});

const Login: React.FC = () => {
Expand All @@ -50,12 +64,13 @@ const Login: React.FC = () => {
const[outputData, setOutputData] = useState<string | null>(null);
const [connectionStatus, setConnectionStatus] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [isSandbox, setIsSandbox] = useState(false);

const handleLogin = useCallback(async () => {
try {
await setEnvVariable('ZENODO_SANDBOX', String(isSandbox));
if (APIKey != '') {
await setEnvVariable('ZENODO_API_KEY', APIKey);
//console.log(await getEnvVariable('ZENODO_API_KEY'));
setOutputData("Zenodo Token Successfully Stored in Environment.");
testAPIConnection();
} else {
Expand All @@ -70,13 +85,16 @@ const Login: React.FC = () => {
} catch (error) {
console.error(error);
}
}, [APIKey]);
}, [APIKey, isSandbox]);

const handleCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setIsSandbox(event.target.checked);
};

const testAPIConnection = async () => {
setIsLoading(true);
try {
var response = await testZenodoConnection();
//console.log(response['status']);
if (Number(response['status']) == 200) {
setConnectionStatus("API Connection Successful")
} else {
Expand All @@ -89,25 +107,6 @@ const Login: React.FC = () => {
}
}

/* const handleLogin = () => {
try {
var code = `
import os
`;
if (APIKey != '') {
code += `
os.environ['TESTVAR'] = '${APIKey}'
`;
}
code += `
os.environ['TESTVAR']
`;
console.log(code);
} catch (error) {
alert('Invalid Zenodo API Token');
}
} */

return (
<div className={classes.root}>
<div className={classes.loginContainer}>
Expand All @@ -116,6 +115,17 @@ os.environ['TESTVAR']
<input className={classes.input} type="text" id="APIKey" name="APIKey" placeholder="API Key" value={APIKey} onChange={(e) => setAPIKey(e.target.value)} required />
</div>
<div className={classes.formGroup}>
<div className={classes.checkboxContainer}>
<label className={classes.checkboxLabel}>
<input
type="checkbox"
checked={isSandbox}
onChange={handleCheckboxChange}
className={classes.checkboxInput}
/>
Use Sandbox
</label>
</div>
<button className={classes.button} type="submit" onClick={handleLogin}>Login</button>
{outputData ? (
<div>
Expand Down
18 changes: 17 additions & 1 deletion src/components/type.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,20 @@ export interface FileEntry {
size?: number; // Size in bytes
}

export type OnSelectFile = (filePath: string) => void;
export type OnSelectFile = (filePath: string) => void;

export interface Creator {
name: string;
affiliation?: string;
}

export interface UploadPayload {
title: string;
resourceType: string;
creators: Creator[];
doi: string;
description: string;
filePaths: string[];
isSandbox: boolean;
action: string;
}
79 changes: 38 additions & 41 deletions src/components/upload.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { createUseStyles } from 'react-jss';
import FileBrowser from './FileBrowser';
import Confirmation from './confirmation';
import { depositUpload } from '../API/API_functions';
import { UploadPayload } from './type';

const useStyles = createUseStyles({
container: {
Expand Down Expand Up @@ -235,15 +237,19 @@ const Upload: React.FC = () => {
const [description, setDescription] = useState('');
const [expandedFile, setExpandedFile] = useState<string | null>(null);

/* const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const fileList = event.target.files;
if (fileList) {
const newPaths = Array.from(fileList).map(file => file.name);
setSelectedFilePaths(prevPaths => [
...new Set([...prevPaths, ...newPaths]) // Add new paths, avoiding duplicates
]);
useEffect(() => {
async function fetchSandboxStatus() {
try {
const response = await fetch('zenodo-jupyterlab/env?env_var=ZENODO_SANDBOX');
const data = await response.json();
setIsSandbox(data.ZENODO_SANDBOX === 'true');
} catch (error) {
console.error('Error fetching sandbox status:', error);
}
}
}; */

fetchSandboxStatus();
}, []);

const handleFileClick = (filePath: string) => {
setExpandedFile(prev => (prev === filePath ? null : filePath));
Expand All @@ -259,16 +265,10 @@ const Upload: React.FC = () => {
]);
};



const handleTitleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setTitle(event.target.value);
};

const handleSandboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setIsSandbox(event.target.checked);
};

const handleResourceTypeChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
setResourceType(event.target.value);
};
Expand All @@ -295,45 +295,42 @@ const Upload: React.FC = () => {
return;
}
setIsConfirmationVisible(true);
};

const handleEdit = () => {
setIsConfirmationVisible(false);
};

const handleConfirm = async () => {
const formData = new FormData();
selectedFilePaths.forEach(filePath => formData.append('filePaths', filePath));
formData.append('title', title);
formData.append('resourceType', resourceType);
formData.append('creators', JSON.stringify(creators));
formData.append('doi', doi);
formData.append('description', description);
formData.append('action', 'upload');

const payload: UploadPayload = {
title,
resourceType,
creators,
doi,
description,
filePaths: selectedFilePaths,
isSandbox,
action: 'upload'
};

// Example: logging form data
for (let [key, value] of formData.entries()) {
console.log(`${key}: ${value}`);
}

/* // Make an API call here, e.g., using fetch
fetch('your-api-endpoint', {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
}); */
};

const handleEdit = () => {
setIsConfirmationVisible(false);
};

const handleConfirm = () => {
// Make an API call or handle form submission here
console.log('Form submitted with:', { title, resourceType, creators, doi, selectedFilePaths });
// Reset the form or navigate as needed
console.log(JSON.stringify(payload));
const response = await depositUpload(payload);
console.log(response['status']);
};

const fileName = (filePath: string) => {
console.log(filePath);
const segments = filePath.split('/');
return segments.pop();
}
Expand Down Expand Up @@ -368,7 +365,7 @@ const Upload: React.FC = () => {
//onChange={() => handleCheckboxChange('communities')}
className={classes.checkboxInput}
checked={isSandbox}
onChange={handleSandboxChange}
readOnly
/>
Sandbox
</label>
Expand Down
4 changes: 2 additions & 2 deletions zenodo_jupyterlab/server/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ def _load_jupyter_server_extension(server_app):
try:
setup_handlers(web_app)
server_app.log.info("Registered zenodo_jupyterlab server extension")
except Exception as e:
server_app.log.error(f"Failed to register zenodo_jupyterlab server extension: {e}")
except:
server_app.log.error(f"Failed to register zenodo_jupyterlab server extension")
raise
Loading
Loading