diff --git a/assets/src/ContextProvider.js b/assets/src/ContextProvider.js
index 0564abd9..da5d09d7 100644
--- a/assets/src/ContextProvider.js
+++ b/assets/src/ContextProvider.js
@@ -1,163 +1,163 @@
/*
This is the Open Access Check Tool (OACT).
The publication of scientific articles as Open Access (OA), usually in the variants "Green OA" and "Gold OA", allows free access to scientific research results and their largely unhindered dissemination. Often, however, the multitude of available publication conditions makes the decision in favor of a particular journal difficult: requirements of the funding agencies and publication guidelines of the universities and colleges must be carefully compared with the offers of the publishing houses, and separately concluded publication agreements can also offer additional benefits. The "OA Compliance Check Tool" provides a comprehensive overview of the possible publication conditions for a large number of journals, especially for the Swiss university landscape, and thus supports the decision-making process.
© All rights reserved. ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, Scientific Information and Libraries, 2022
See LICENSE.TXT for more details.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see
.
*/
import React, { useCallback, useState, useEffect } from "react"
import { getListOfInstitution } from './services/requests/Institution'
import { getListOfJournal } from "./services/requests/Journal"
import { getListOfFunder } from "./services/requests/Funder"
const Context = React.createContext()
function ContextProvider({ children }) {
//call the custom hook for listing field with api
const [institList, setInstitList] = useState([]);
const [journalList, setJournalList] = useState([]);
const [funderList, setFunderList] = useState([]);
const [institId, setInstitId] = React.useState('');
const [institName, setInstitName] = React.useState('');
const [journalId, setJournalId] = React.useState('');
const [journalName, setJournalName] = React.useState('');
const [funderId, setFunderId] = React.useState('');
const [funderName, setFunderName] = React.useState('');
const [url, setUrl] = React.useState('');
const [refList, setRefList] = useState([]);
const getInstitListFromApi = useCallback(async () => {
try {
const response = await getListOfInstitution()
setInstitList(response.data)
} catch (error) {
console.log(`error 700 from Get Institution- ${error.message}`)
}
}, [])
const getJournalListFromApi = useCallback(async () => {
try {
const response = await getListOfJournal()
/* patch journal titles for inactive journals, to avoid confusions with continuing titles */
response.data.forEach(element => {
if (element.end_year != 9999) {
element.name += ' [' + element.starting_year.toString()+ '-' + element.end_year.toString() + ']'
}
});
setJournalList(response.data)
} catch (error) {
console.log(`error 700 from Get Journal- ${error.message}`)
}
}, [])
const getFunderListFromApi = useCallback(async () => {
try {
const response = await getListOfFunder()
setFunderList(response.data)
} catch (error) {
console.log(`error 700 from Get Funder- ${error.message}`)
}
}, [])
useEffect(() => {
getInstitListFromApi(),
getJournalListFromApi(),
getFunderListFromApi()
}, [])
//get the institution Id and update request array
function getSelectedInstitId(name) {
const updateArr = institList.map(item => {
if (item.name === name) {
console.log(item.ror, item.name)
const newItem = item.ror
const newItemName = item.name
setInstitId(newItem)
setInstitName(newItemName)
return newItem
}
// return
})
// return
}
//get the journal Id and update request array
function getSelectedJournalId(name) {
const updateArr = journalList.map(item => {
if (item.name === name) {
console.log(item.id, item.name)
- const newItem = item.id
+ const newItem = item.issn[0].issn
const newItemName = item.name
setJournalId(newItem)
setJournalName(newItemName)
return
}
return
})
return
}
//get the funder Id and update request array
function getSelectedFunderId(name) {
const updateArr = funderList.map(item => {
if (item.name === name) {
console.log(item.ror, item.name)
const newItem = item.ror
const newItemName = item.name
setFunderId(newItem)
setFunderName(newItemName)
return
}
return
})
return
}
return (
{children}
)
}
export { ContextProvider, Context }
\ No newline at end of file
diff --git a/assets/src/pages/SearchFilterFields.js b/assets/src/pages/SearchFilterFields.js
index 1407b17c..6b71a8ff 100644
--- a/assets/src/pages/SearchFilterFields.js
+++ b/assets/src/pages/SearchFilterFields.js
@@ -1,1309 +1,1309 @@
/*
This is the Open Access Check Tool (OACT).
The publication of scientific articles as Open Access (OA), usually in the variants "Green OA" and "Gold OA", allows free access to scientific research results and their largely unhindered dissemination. Often, however, the multitude of available publication conditions makes the decision in favor of a particular journal difficult: requirements of the funding agencies and publication guidelines of the universities and colleges must be carefully compared with the offers of the publishing houses, and separately concluded publication agreements can also offer additional benefits. The "OA Compliance Check Tool" provides a comprehensive overview of the possible publication conditions for a large number of journals, especially for the Swiss university landscape, and thus supports the decision-making process.
© All rights reserved. ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, Scientific Information and Libraries, 2022
See LICENSE.TXT for more details.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see
.
*/
import React, { useContext, useState, useEffect } from 'react';
import "./SearchFilterFields.css"
import Button from '@mui/material/Button';
import FormControl from '@mui/material/FormControl';
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';
import { searchCondi, searchorganizationonly, searchjournalonly, searchInstitFunder, searchCondi3 } from '../services/requests/Condition'
import { getJournal } from '../services/requests/Journal'
import { getFunder } from '../services/requests/Funder'
import { getInstitution } from '../services/requests/Institution'
import Accordion from '@mui/material/Accordion';
import AccordionSummary from '@mui/material/AccordionSummary';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import Typography from '@mui/material/Typography';
import AccordionDetails from '@mui/material/AccordionDetails';
import Grid from '@mui/material/Grid'
import Box from '@mui/material/Box'
import Container from '@mui/material/Container';
import { Context } from "../ContextProvider"
import ResultCard from "../components/ResultCard"
import DetailCard from "../components/DetailCard"
import CircularProgress from '@mui/material/CircularProgress'
import Fab from '@mui/material/Fab'
import ShareIcon from '@mui/icons-material/Share'
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
import Slide from '@mui/material/Slide';
import Welcome from './welcome';
import {
useNavigate,
useLocation
} from "react-router-dom";
import PropTypes from 'prop-types';
// import { FiFlag } from 'react-icons/fi';
import FlagOutlinedIcon from '@mui/icons-material/FlagOutlined';
import Tooltip from '@mui/material/Tooltip';
import { createTheme } from '@mui/material'
const { palette } = createTheme()
const theme = createTheme({
palette: {
// myWhite: palette.augmentColor({ color: white }),
// Use this code if you want to use an arbitrary color
// myAwesomeColor: palette.augmentColor({
// color: {
// main: "#00ff00"
// }
// })
myWhite: palette.augmentColor({
color: {
main: "#ffffff"
}
})
}
})
function useQuery() {
return new URLSearchParams(useLocation().search);
}
const Transition = React.forwardRef(function Transition(props, ref) {
return ;
});
// ID of condition type that must be excluded in some API requests
const j_only_id = 3
const o_only_id = 1
/*
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
chip: {
margin: 0.5,
},
}));
*/
/**
* Contain the main logic of OACT tools to filter and send the appropriate request.
* @version 1.0
* @author [Hugo Galuppo](https://github.com/hgpulse)
* @author [Alain Borel] (https://orcid.org/0000-0003-3268-3195)
*/
// Comparison function to sort details as instititution ' funder - journal'
// sort order on the is_funder field is True, False, undefined
function details_compare(a, b) {
console.log('Entering details_compare()')
if (a.is_funder == undefined) {
if (b.is_funder == undefined) {
// the 1st object is a journal, must come last
return 0;
} else {
return 1;
}
} else {
if (b.is_funder == undefined) {
return -1;
} else {
if (a.is_funder < b.is_funder) {
return -1;
} else {
return 1;
}
}
}
return 0;
}
export default function SearchFilterFields() {
/** Access to URL parameter */
const history = useLocation();
const navigate = useNavigate();
console.log(history)
let query = useQuery()
//state that allow to hide or show the share url button
const [open, setOpen] = React.useState(false)
// const classes = useStyles();
//call the custom hook to share the state between different level componant
const {
getSelectedInstitId,
getSelectedJournalId,
getSelectedFunderId,
institList,
journalList,
funderList,
institId,
journalId,
funderId,
setInstitId,
setJournalId,
setFunderId,
setUrl,
url
} = useContext(Context)
//responses
const [conditions, setConditions] = useState([]);
const [details, setDetails] = useState([]);
const [result, updateResult] = useState([]);
//Manage the loading state to hide or show the spinner in the search bar
const [loading, setLoading] = useState(false);
// const [url, setUrl] = useState(window.location.href);
useEffect(() => {
setDetails('null')
setUrl(window.location.href)
//handle Url param
console.log('history =')
console.log(history)
if (history.pathname === "/check") {
console.log("this an url to check")
setDetails('fromUrl')
//alert(query.get("institution"))
if (query.get("institution") && !query.get("funder") && !query.get("journal")) {
//get organizations conditions
//alert(`get api organization Condition only (1): ${institId}`)
//condtion type is not journal only = 1
// Get the user
const sendSearchInstitOnly =
async () => {
try {
const resp = await searchorganizationonly(query.get("institution"), j_only_id)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
console.log(details)
const sendGetrequest =
async () => {
try {
const resp = await getInstitution(query.get("institution"))
// console.log(`instit name from api: ${resp.data.name}`)
// setInstitName(resp.data.name)
updateResult(arr => [...arr, resp.data[0]])
// if (details === "null") {
// setDetails(resp.data)
// }
// else {
// setDetails(prevArray => [...prevArray, resp.data])
// }
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendSearchInstitOnly().then(
sendGetrequest()
)
navigate({ pathname: '/check', search: `institution=${query.get("institution")}` })
} else if (!query.get("institution") && !query.get("journal") && query.get("funder")) {
//get funder conditions
alert(`get api funder Condition only: ${funderId}`)
//condtion type is not journal only = 1
const sendSearchOrgaOnly =
async () => {
try {
const resp = await searchorganizationonly(query.get("funder"), j_only_id)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetrequest =
async () => {
try {
const resp = await getFunder(query.get("funder"))
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendSearchOrgaOnly().then(
sendGetrequest()
)
navigate({pathname: '/check', search: `funder=${query.get("funder")}` })
} else if (!query.get("funder") && !query.get("institution") && query.get("journal")) {
//get journals conditions
//alert(`get api journal Condition only: ${journalId}`)
//condtion type is not institution only = 2
//get journal detail
const sendSearchJournalOnly =
async () => {
try {
const resp = await searchjournalonly(query.get("journal"), o_only_id)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
// setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetrequest =
async () => {
try {
const resp = await getJournal(query.get("journal"))
console.log(resp.data)
- updateResult(arr => [...arr, resp.data])
+ updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendSearchJournalOnly().then(
sendGetrequest()
)
navigate({ pathname: '/check', search:`journal=${query.get("journal")}`})
} else if (query.get("institution") && query.get("funder") && !query.get("journal")) {
//alert(`get api Filter Conditions SET--> Journal: ${journalId} VS Institution: ${institId}`)
//condtion type journal/condition = 3
const sendSearchCondi =
async () => {
try {
const resp = await searchInstitFunder(query.get("institution"), query.get("funder"), j_only_id)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetInstit =
async () => {
try {
const resp = await getInstitution(query.get("institution"))
console.log(resp.data)
// detailArray.push(resp.data)
// setDetails(detailArray)
updateResult(arr => [...arr, resp.data[0]].sort(details_compare))
} catch (err) {
// Handle Error Here
console.error(err);
}
}
const sendGetFunder =
async () => {
try {
const resp = await getFunder(query.get("funder"))
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]].sort(details_compare))
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendSearchCondi().then(
sendGetInstit().then(sendGetFunder())
)
navigate({pathname: '/check', search: `institution=${query.get("institution")}&funder=${query.get("funder")}`})
} else if (query.get("institution") && query.get("journal") && !query.get("funder")) {
//alert(`get api Filter Conditions SET--> Journal: ${journalId} VS Institution: ${institId}`)
//condtion type journal/condition = 3
const sendSearchCondi =
async () => {
try {
const resp = await searchCondi(query.get("journal"), query.get("institution"))
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetInstit =
async () => {
try {
const resp = await getInstitution(query.get("institution"))
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]].sort(details_compare))
} catch (err) {
// Handle Error Here
console.error(err);
}
}
const sendGetJournal =
async () => {
try {
const resp = await getJournal(query.get("journal"))
console.log(resp.data)
// detailArray.push(resp.data)
// setDetails(detailArray)
- updateResult(arr => [...arr, resp.data].sort(details_compare))
+ updateResult(arr => [...arr, resp.data[0]].sort(details_compare))
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendSearchCondi().then(
sendGetInstit().then(sendGetJournal)
)
navigate({pathname: '/check', search: `institution=${query.get("institution")}&journal=${query.get("journal")}`})
} else if (!query.get("institution") && query.get("journal") && query.get("funder")) {
//alert(`get api Filter Conditions SET--> Journal: ${journalId} VS Institution: ${institId} VS Funder: ${funderId}`)
//condtion type journal/institution/funder conditions = 3
const sendGetCondi =
async () => {
try {
const resp = await searchCondi(query.get("journal"), query.get("funder"))
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetFunder =
async () => {
try {
const resp = await getFunder(query.get("funder"))
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]].sort(details_compare))
} catch (err) {
// Handle Error Here
console.error(err);
}
}
const sendGetJournal =
async () => {
try {
const resp = await getJournal(query.get("journal"))
console.log(resp.data)
- updateResult(arr => [...arr, resp.data].sort(details_compare))
+ updateResult(arr => [...arr, resp.data[0]].sort(details_compare))
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendGetCondi().then(
sendGetFunder().then(
sendGetJournal()
)
)
navigate({pathname: '/check', search: `funder=${query.get("funder")}&journal=${query.get("journal")}`})
} else if (query.get("institution") && query.get("journal") && query.get("funder")) {
//alert(`get api Filter Conditions SET--> Journal: ${journalId} VS Funder: ${funderId}`)
//condtion type journal/institution/funder conditions = 3
console.log("main check !")
//(institution + journal)
const detailArray = []
const sendGetCondi =
async () => {
try {
const resp = await searchCondi3(query.get("institution"), query.get("journal"), query.get("funder"))
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetInstit =
async () => {
try {
const resp = await getInstitution(query.get("institution"))
console.log(resp.data)
detailArray.push(resp.data)
updateResult(arr => [...arr, resp.data[0]].sort(details_compare))
console.log("sendGetInst completing")
} catch (err) {
// Handle Error Here
console.error(err);
}
return 0;
}
const sendGetFunder =
async () => {
try {
const resp = await getFunder(query.get("funder"))
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]].sort(details_compare))
console.log("sendGetFunder completing")
} catch (err) {
// Handle Error Here
console.error(err);
}
return 0;
}
const sendGetJournal =
async () => {
try {
const resp = await getJournal(query.get("journal"))
console.log(resp.data)
- updateResult(arr => [...arr, resp.data].sort(details_compare))
+ updateResult(arr => [...arr, resp.data[0]].sort(details_compare))
console.log("sendGetJournal completing")
} catch (err) {
// Handle Error Here
console.error(err);
}
return 0;
}
//order requests
sendGetCondi()
sendGetInstit().then(
sendGetFunder()
).then(
sendGetJournal()
)
navigate({pathname: '/check', search: `institution=${query.get("institution")}&funder=${query.get("funder")}&journal=${query.get("journal")}`})
}
}
}, [])
//useEffect on Url state change
React.useEffect(() => {
//condition to avoid infinite loop
if (history.pathname === "/") {
setConditions([])
setDetails('null')
updateResult([])
setUrl(window.location.href)
}
}, [url]);
function handleReport() {
// ## Create mail template to report a modification, contain the actual Url and the reference Term Card
window.open(`mailto:publishsupport@epfl.ch?subject= OACT Modification request for ${encodeURIComponent(url)} &body=Request Description:`)
}
//copy url to clipboard
function handlShare(e) {
setOpen(true)
navigator.clipboard.writeText(url)
}
const handleClose = () => {
setOpen(false);
};
function handleInstit(e, newInputValue) {
if (newInputValue) {
getSelectedInstitId(newInputValue)
return
}
// if (institName){
// getSelectedInstitId(institName)
// return
// }
setInstitId("")
}
function handleFunder(e, newInputValue) {
console.log(newInputValue)
if (newInputValue) {
getSelectedFunderId(newInputValue)
return
}
setFunderId("")
}
function handleJournal(e, newInputValue) {
if (newInputValue) {
getSelectedJournalId(newInputValue)
return
}
setJournalId("")
}
function handleSubmit(e) {
setLoading(true)
e.preventDefault()
//reset precedent results
setConditions([])
setDetails([])
updateResult([])
if (!institId && !journalId && !funderId) {
setLoading(false)
setDetails('null')
}
if (institId && !journalId && !funderId) {
//get organizations conditions
// alert(`get api organization Condition only (2): ${institId}`)
//condtion type is not journal only = 1
// Get the user
const sendSearchInstitOnly =
async () => {
try {
const resp = await searchorganizationonly(institId, j_only_id)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
console.log(details)
const sendGetrequest =
async () => {
try {
const resp = await getInstitution(institId)
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]])
// if (details === "null") {
// setDetails(resp.data)
// }
// else {
// setDetails(prevArray => [...prevArray, resp.data])
// }
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendSearchInstitOnly().then(
sendGetrequest()
)
navigate('/check?institution=' + institId.toString())
} else if (!institId && !journalId && funderId) {
//get funder conditions
// alert(`get api funder Condition only: ${funderId}`)
//condtion type is not journal only = 1
const sendSearchOrgaOnly =
async () => {
try {
const resp = await searchorganizationonly(funderId, j_only_id)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetrequest =
async () => {
try {
const resp = await getFunder(funderId)
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendSearchOrgaOnly().then(
sendGetrequest()
)
navigate('/check?funder=' + funderId.toString())
} else if (!funderId && !institId && journalId) {
//get journals conditions
//alert(`get api journal Condition only: ${journalId}`)
//condtion type is not institution only = 2
//get journal detail
const sendSearchJournalOnly =
async () => {
try {
const resp = await searchjournalonly(journalId, o_only_id)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
// setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetrequest =
async () => {
try {
const resp = await getJournal(journalId)
console.log(resp.data)
- updateResult(arr => [...arr, resp.data])
+ updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendSearchJournalOnly().then(
sendGetrequest()
)
navigate('/check?journal=' + journalId.toString())
} else if (institId && funderId && !journalId) {
//alert(`get api Filter Conditions SET--> Journal: ${journalId} VS Institution: ${institId}`)
//condtion type journal/condition = 3
const sendSearchCondi =
async () => {
try {
const resp = await searchInstitFunder(institId, funderId, j_only_id)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetInstit =
async () => {
try {
const resp = await getInstitution(institId)
console.log(resp.data)
//manage the order output
// detailArray.push(resp.data)
// setDetails(detailArray)
updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
const sendGetFunder =
async () => {
try {
const resp = await getFunder(funderId)
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendSearchCondi().then(
sendGetInstit().then(sendGetFunder())
)
navigate('/check?institution=' + institId.toString() + '&funder=' + funderId.toString())
} else if (institId && journalId && !funderId) {
//alert(`get api Filter Conditions SET--> Journal: ${journalId} VS Institution: ${institId}`)
//condtion type journal/condition = 3
const sendSearchCondi =
async () => {
try {
const resp = await searchCondi(journalId, institId)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetInstit =
async () => {
try {
const resp = await getInstitution(institId)
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
const sendGetJournal =
async () => {
try {
const resp = await getJournal(journalId)
console.log(resp.data)
// detailArray.push(resp.data)
// setDetails(detailArray)
- updateResult(arr => [...arr, resp.data])
+ updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendSearchCondi().then(
sendGetInstit().then(sendGetJournal)
)
navigate('/check?institution=' + institId.toString() + '&journal=' + journalId.toString())
} else if (!institId && journalId && funderId) {
//alert(`get api Filter Conditions SET--> Journal: ${journalId} VS Institution: ${funderId}`)
//condtion type journal/institution/funder conditions = 3
const sendGetCondi =
async () => {
try {
const resp = await searchCondi(journalId, funderId)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetFunder =
async () => {
try {
const resp = await getFunder(funderId)
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
const sendGetJournal =
async () => {
try {
const resp = await getJournal(journalId)
console.log(resp.data)
- updateResult(arr => [...arr, resp.data])
+ updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
sendGetCondi().then(
sendGetJournal().then(
sendGetFunder()
)
)
navigate('/check?funder=' + funderId.toString() + '&journal=' + journalId.toString())
} else if (institId && journalId && funderId) {
//alert(`get api Filter Conditions SET--> Journal: ${journalId} VS Institution: ${institId} VS Finder: ${funderId}`)
//condtion type journal/institution/funder conditions = 3
console.log("main check !")
//(institution + journal)
const detailArray = []
const sendGetCondi =
async () => {
try {
const resp = await searchCondi3(institId, journalId, funderId)
console.log(resp.data)
setConditions(arr => [...arr, resp.data])
} catch (err) {
// Handle Error Here
console.error(err);
}
setLoading(false)
}
const sendGetInstit =
async () => {
try {
const resp = await getInstitution(institId)
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
const sendGetFunder =
async () => {
try {
const resp = await getFunder(funderId)
console.log(resp.data)
updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
const sendGetJournal =
async () => {
try {
const resp = await getJournal(journalId)
console.log(resp.data)
- updateResult(arr => [...arr, resp.data])
+ updateResult(arr => [...arr, resp.data[0]])
} catch (err) {
// Handle Error Here
console.error(err);
}
}
//order the request
sendGetCondi()
sendGetInstit().then(
sendGetFunder()
).then(
sendGetJournal()
)
navigate('/check?institution=' + institId.toString() + '&funder=' + funderId.toString() + '&journal=' + journalId.toString())
}
}
//console.log(`all conditions SET: ${conditions}`)
//console.log(details)
console.log(`Selected Institution ID: ${institId} , Selected Funder: ${funderId}, Selected Journal ID: ${journalId}`)
function detailsResult() {
console.log(`details: ${details}`)
console.log(result)
if (details !== 'null') {
/* TODO check how Selected option(s) formatting is affected by removing classes.heading style*/
return (
}
aria-controls="panel1a-content"
id="panel1a-header"
>
Selected option(s)
{result?.map(i => (
))}
)
}
}
function conditionResults() {
return (
{conditions?.map(i=> (
))}
)
}
return (
{console.log(institList)}
Your input on OACT is welcome! Do not hesitate to contact
publishsupport@epfl.ch for comments or questions,
or use the "Modification request" buttons in the results for feedback regarding specific details.
{detailsResult()}
{conditionResults()}
{ history.pathname === "/" &&
}
{/* { history.location.pathname === "/" && */}
{/* } */}
{"Share your Result!"}
{url}
Copy to clipboard!
);
}
SearchFilterFields.propTypes = {
/** Store the selected option/field Result from API. */
details: PropTypes.object,
/** Store the individual response for each request. */
result: PropTypes.object,
/** Store at the same place the aggregation of all request result */
conditions: PropTypes.object,
/** Manage the loading wheels inside the check button. */
loading: PropTypes.bool
}
\ No newline at end of file
diff --git a/assets/src/services/requests/Condition.js b/assets/src/services/requests/Condition.js
index a7d30ad0..e81c9007 100644
--- a/assets/src/services/requests/Condition.js
+++ b/assets/src/services/requests/Condition.js
@@ -1,73 +1,73 @@
/*
This is the Open Access Check Tool (OACT).
The publication of scientific articles as Open Access (OA), usually in the variants "Green OA" and "Gold OA", allows free access to scientific research results and their largely unhindered dissemination. Often, however, the multitude of available publication conditions makes the decision in favor of a particular journal difficult: requirements of the funding agencies and publication guidelines of the universities and colleges must be carefully compared with the offers of the publishing houses, and separately concluded publication agreements can also offer additional benefits. The "OA Compliance Check Tool" provides a comprehensive overview of the possible publication conditions for a large number of journals, especially for the Swiss university landscape, and thus supports the decision-making process.
© All rights reserved. ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, Scientific Information and Libraries, 2022
See LICENSE.TXT for more details.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see
.
*/
import Api from '../Api'
let today = new Date().toISOString().slice(0, 10)
var date_filter = 'ge(journalcondition.valid_until,' + today +
'),le(journalcondition.valid_from,' + today +
'),ge(organizationcondition.valid_until,' + today +
'),le(organizationcondition.valid_from,' + today + ')'
// To stop filtering by validity dates, replace by a trivial filter such as
// var date_filter = 'ge(condition.id,0)'
export const getCondition = (id) => {
return Api.request({
url: `/conditionterm/${id}`,
method: 'GET',
})
}
export const getListOfCondition = () => {
return Api.request({
url: `/conditionterm/`,
method: 'GET',
})
}
export const searchCondi = (journalId,institId) => {
return Api.request({
- url: `/conditionset_light/?and(eq(journalcondition.journal.id,${journalId}),eq(organizationcondition.organization.ror,${institId}),${date_filter})`,
+ url: `/conditionset_light/?and(eq(journalcondition.journal.classIssn.issn,${journalId}),eq(organizationcondition.organization.ror,${institId}),${date_filter})`,
method: 'GET',
})
}
export const searchInstitFunder = (institId,funderId,condi) => {
return Api.request({
url: `/conditionset_light/?(eq(organizationcondition.organization.ror,${institId})|eq(organizationcondition.organization.ror,${funderId})),ne(condition_type.id,${condi}),and(${date_filter})`,
method: 'GET',
})
}
export const searchCondi3 = (institId,journalId,funderId) => {
return Api.request({
- url: `/conditionset_light/?(eq(organizationcondition.organization.ror,${institId})|eq(organizationcondition.organization.ror,${funderId})),eq(journalcondition.journal.id,${journalId}),and(${date_filter})`,
+ url: `/conditionset_light/?(eq(organizationcondition.organization.ror,${institId})|eq(organizationcondition.organization.ror,${funderId})),eq(journalcondition.journal.classIssn.issn,${journalId}),and(${date_filter})`,
method: 'GET',
})
}
export const searchorganizationonly = (institId,condi) => {
return Api.request({
url: `/conditionset_light/?and(eq(organizationcondition.organization.ror,${institId}),ne(condition_type.id,${condi}),${date_filter})`,
method: 'GET',
})
}
export const searchjournalonly = (id,condi) => {
return Api.request({
- url: `/conditionset_light/?and(eq(journalcondition.journal.id,${id}),ne(condition_type.id,${condi}),${date_filter})`,
+ url: `/conditionset_light/?and(eq(journalcondition.journal.classIssn.issn,${id}),ne(condition_type.id,${condi}),${date_filter})`,
method: 'GET',
})
}
\ No newline at end of file
diff --git a/assets/src/services/requests/Journal.js b/assets/src/services/requests/Journal.js
index a618e138..4a07902b 100644
--- a/assets/src/services/requests/Journal.js
+++ b/assets/src/services/requests/Journal.js
@@ -1,41 +1,41 @@
/*
This is the Open Access Check Tool (OACT).
The publication of scientific articles as Open Access (OA), usually in the variants "Green OA" and "Gold OA", allows free access to scientific research results and their largely unhindered dissemination. Often, however, the multitude of available publication conditions makes the decision in favor of a particular journal difficult: requirements of the funding agencies and publication guidelines of the universities and colleges must be carefully compared with the offers of the publishing houses, and separately concluded publication agreements can also offer additional benefits. The "OA Compliance Check Tool" provides a comprehensive overview of the possible publication conditions for a large number of journals, especially for the Swiss university landscape, and thus supports the decision-making process.
© All rights reserved. ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, Scientific Information and Libraries, 2022
See LICENSE.TXT for more details.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see
.
*/
import Api from '../Api'
export const getJournal = (id) => {
return Api.request({
- url: `/journal/${id}`,
+ url: `/journal/?classIssn.issn=${id}`,
method: 'GET',
})
}
export const searchListOfJournalCondi = (id,condi) => {
return Api.request({
url: `/journalcondition/?and(eq(journal.id,${id}),ne(condition_set.condition_type.id,${condi}))`,
method: 'GET',
})
}
export const getListOfJournal = () => {
return Api.request({
url: `/journal_light/`,
method: 'GET',
})
}
\ No newline at end of file
diff --git a/django_api/serializers.py b/django_api/serializers.py
index af7fe1e4..6c88754a 100644
--- a/django_api/serializers.py
+++ b/django_api/serializers.py
@@ -1,458 +1,461 @@
"""
This is the Open Access Check Tool (OACT).
The publication of scientific articles as Open Access (OA), usually in the variants "Green OA" and "Gold OA", allows free access to scientific research results and their largely unhindered dissemination. Often, however, the multitude of available publication conditions makes the decision in favor of a particular journal difficult: requirements of the funding agencies and publication guidelines of the universities and colleges must be carefully compared with the offers of the publishing houses, and separately concluded publication agreements can also offer additional benefits. The "OA Compliance Check Tool" provides a comprehensive overview of the possible publication conditions for a large number of journals, especially for the Swiss university landscape, and thus supports the decision-making process.
© All rights reserved. ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, Scientific Information and Libraries, 2022
See LICENSE.TXT for more details.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see
.
"""
""" REST API serializers
All serializers inherit from WritableNestedModelSerializer to allow writing nested objects
through the API as per https://github.com/beda-software/drf-writable-nested
and RQLMixin to support the Resource Query Language (RQL) https://django-rql.readthedocs.io/en/latest/
"""
from rest_framework import serializers
from dj_rql.drf.serializers import RQLMixin
from .models import *
from drf_writable_nested.serializers import WritableNestedModelSerializer
class CountrySerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for Countries
"""
id = serializers.IntegerField(required=False)
name = serializers.CharField(required=False)
iso_code = serializers.CharField(required=False)
class Meta:
model = Country
fields = '__all__'
depth = 4
class LanguageSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for Languages
"""
id = serializers.IntegerField(required=False)
name = serializers.CharField(required=False)
iso_code = serializers.CharField(required=False)
class Meta:
model = Language
fields = '__all__'
depth = 4
class PublisherSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for Publishers
"""
id = serializers.IntegerField(required=False)
country = CountrySerializer(required=False, many=True)
class Meta:
model = Publisher
fields = '__all__'
depth = 4
class OaSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for OA statuses
"""
id = serializers.IntegerField(required=False, allow_null=True)
description = serializers.CharField(required=False, allow_null=True)
subscription = serializers.BooleanField(required=False)
accepted_manuscript = serializers.BooleanField(required=False)
apc = serializers.BooleanField(required=False)
final_version = serializers.BooleanField(required=False)
class Meta:
model = Oa
fields = '__all__'
depth = 4
class IssnSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for ISSNs
"""
id = serializers.IntegerField(required=False)
+ journal = serializers.PrimaryKeyRelatedField(queryset=Journal.objects.all())
class Meta:
model = Issn
fields = '__all__'
depth = 1
class JournalSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for Journals
"""
id = serializers.IntegerField(required=False)
issn = IssnSerializer(required=False, source='classIssn', many=True)
publisher = PublisherSerializer(required=False, many=True)
language = LanguageSerializer(required=False, many=True)
# allow update via post request --> "oa_status": {2},
# oa_status = serializers.PrimaryKeyRelatedField(queryset=Oa.objects.all())
oa_status = OaSerializer(required=False,allow_null=True)
class Meta:
model = Journal
fields = '__all__'
depth = 4
class LicenceSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for Licences
"""
id = serializers.IntegerField(required=False)
name_or_abbrev = serializers.CharField()
website = serializers.URLField(allow_null=True, required=False)
class Meta:
model = Licence
fields = '__all__'
depth = 4
class Cost_factor_typeSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for cost factor types
"""
id = serializers.IntegerField(required=False)
name = serializers.CharField()
class Meta:
model = Cost_factor_type
fields = '__all__'
depth = 4
class VersionSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for article versions
"""
id = serializers.IntegerField(required=False)
description = models.CharField()
class Meta:
model = Version
fields = '__all__'
depth = 4
class OrgaSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for organizations
"""
id = serializers.IntegerField(required=False)
country = CountrySerializer(required=False, many=True)
class Meta:
model = Organization
fields = '__all__'
depth = 4
class Cost_factorSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for cost factors
"""
id = serializers.IntegerField(required=False)
cost_factor_type = Cost_factor_typeSerializer(required=False, allow_null=True)
amount = serializers.IntegerField()
symbol = serializers.CharField()
comment = serializers.CharField(required=False)
class Meta:
model = Cost_factor
fields = '__all__'
depth = 4
class Cost_factorLightSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for cost factors
"""
id = serializers.IntegerField(required=False)
cost_factor_type = serializers.PrimaryKeyRelatedField(queryset=Cost_factor_type.objects.all())
amount = serializers.IntegerField()
symbol = serializers.CharField()
comment = serializers.CharField(required=False)
class Meta:
model = Cost_factor
fields = '__all__'
depth = 4
class TermSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for terms
"""
id = serializers.IntegerField(required=False)
version = VersionSerializer(required=False, many=True)
cost_factor = Cost_factorSerializer(required=False, many=True)
licence = LicenceSerializer(required=False, many=True)
class Meta:
model = Term
fields = '__all__'
depth = 4
class TermLightSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for terms in writing mode, using IDs for relationships
"""
id = serializers.IntegerField(required=False)
version = serializers.PrimaryKeyRelatedField(queryset=Version.objects.all(), many=True)
cost_factor = serializers.PrimaryKeyRelatedField(queryset=Cost_factor.objects.all(), many=True)
licence = serializers.PrimaryKeyRelatedField(queryset=Licence.objects.all(), many=True)
embargo_months = serializers.IntegerField(required=False)
ir_archiving = serializers.BooleanField(required=False)
comment = serializers.CharField(required=False, allow_null=True)
class Meta:
model = Term
fields = '__all__'
depth = 4
class ConditionTypeSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for condition types
"""
id = serializers.IntegerField(required=False)
condition_issuer = serializers.CharField()
class Meta:
model = ConditionType
fields = '__all__'
depth = 4
class ConditionSubTypeSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for condition subtypes
"""
id = serializers.IntegerField(required=False)
label = serializers.CharField()
class Meta:
model = ConditionSubType
fields = '__all__'
depth = 4
class ConditionSetSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for condition sets
"""
id = serializers.IntegerField(required=False)
term = TermSerializer(many=True, read_only=False)
condition_type = ConditionTypeSerializer(read_only=False)
subtype = ConditionSubTypeSerializer(read_only=False)
organization = OrgaSerializer(many=True, read_only=False)
journal = JournalSerializer(many=True, read_only=False)
comment = serializers.CharField(read_only=False)
source = serializers.URLField(read_only=False, allow_blank=True, allow_null=True, required=False)
class Meta:
model = ConditionSet
# pre filter for rql
# fields = ['id','condition_type','term','journal','organization']
# add for informations purpose
fields = '__all__'
depth = 4
class JournalIdSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API light-weight serializer for journals, using only the ID.
Used by the frontend when building the query
"""
id = serializers.IntegerField(required=False, read_only=False)
# allow update via post request --> "oa_status": {2},
class Meta:
model = Journal
fields = ['id']
class OrganizationIdSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API light-weight serializer for organizations, using only the ID.
For use in other serializers
"""
id = serializers.IntegerField(required=False, read_only=False)
# allow update via post request --> "oa_status": {2},
class Meta:
model = Organization
fields = ['id']
class ConditionSetIdSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API light-weight serializer for condition sets, using only the ID.
For use in other serializers
"""
id = serializers.IntegerField(required=False, read_only=False)
# allow update via post request --> "oa_status": {2},
class Meta:
model = ConditionSet
fields = ['id']
class ConditionSetLightSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for condition sets, providing only the information
needed in the frontend to improve performance
"""
id = serializers.IntegerField(required=False)
term = TermSerializer(many=True, read_only=False)
condition_type = ConditionTypeSerializer(read_only=False)
subtype = ConditionSubTypeSerializer(read_only=False)
organization = OrgaSerializer(many=True, read_only=False)
# No journals in this one.
journal = JournalIdSerializer(many=True, read_only=False)
comment = serializers.CharField(read_only=False)
source = serializers.URLField(read_only=False, allow_blank=True, allow_null=True, required=False)
class Meta:
model = ConditionSet
# pre filter for rql
# fields = ['id','condition_type','term','journal','organization']
# add for informations purpose
fields = ['id', 'condition_type', 'subtype', 'term', 'organization', 'journal', 'comment', 'source']
depth = 4
class ConditionSetLightNewSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for condition sets, providing only the information
needed in the frontend to improve performance
"""
id = serializers.IntegerField(required=False)
term = TermSerializer(many=True, read_only=False)
condition_type = ConditionTypeSerializer(read_only=False)
subtype = ConditionSubTypeSerializer(read_only=False)
- organization = OrgaSerializer(many=True, read_only=False)
+ # organization = OrgaSerializer(many=True, read_only=False)
+ organization = serializers.PrimaryKeyRelatedField(queryset=Organization.objects.all(), many=True)
# No journals in this one.
journal = serializers.PrimaryKeyRelatedField(queryset=Journal.objects.all(), many=True)
comment = serializers.CharField(read_only=False)
source = serializers.URLField(read_only=False, allow_blank=True, allow_null=True, required=False)
class Meta:
model = ConditionSet
# pre filter for rql
# fields = ['id','condition_type','term','journal','organization']
# add for informations purpose
fields = ['id', 'condition_type', 'subtype', 'term', 'organization', 'journal', 'comment', 'source']
depth = 4
class ConditionSetMiniSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializer for condition sets, providing only the information
needed in the frontend to improve performance
"""
id = serializers.IntegerField(required=False)
term = serializers.PrimaryKeyRelatedField(queryset=Term.objects.all(), many=True)
condition_type = serializers.PrimaryKeyRelatedField(queryset=ConditionType.objects.all())
subtype = serializers.PrimaryKeyRelatedField(queryset=ConditionSubType.objects.all())
organization = serializers.PrimaryKeyRelatedField(queryset=Organization.objects.all(), many=True)
# No journals in this one.
journal = serializers.PrimaryKeyRelatedField(queryset=Journal.objects.all(), many=True)
comment = serializers.CharField(read_only=False)
source = serializers.URLField(read_only=False, allow_blank=True, allow_null=True, required=False)
class Meta:
model = ConditionSet
# pre filter for rql
# fields = ['id','condition_type','term','journal','organization']
# add for informations purpose
fields = ['id', 'condition_type', 'subtype', 'term', 'organization', 'journal', 'comment', 'source']
depth = 4
class JournalLightSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API lighter serializer for journals
"""
id = serializers.IntegerField(required=False)
# allow update via post request --> "oa_status": {2},
oa_status = serializers.PrimaryKeyRelatedField(queryset=Oa.objects.all())
language = serializers.PrimaryKeyRelatedField(queryset=Language.objects.all(), many=True)
publisher = serializers.PrimaryKeyRelatedField(queryset=Publisher.objects.all(), many=True)
starting_year = serializers.IntegerField(required=False)
end_year = serializers.IntegerField(required=False)
+ issn = IssnSerializer(required=False, source='classIssn', many=True)
class Meta:
model = Journal
- fields = ['id', 'name', 'oa_status', 'language', 'publisher', 'starting_year', 'end_year']
+ fields = ['id', 'name', 'oa_status', 'language', 'publisher', 'starting_year', 'end_year', 'issn']
depth = 1
class OaSerializer(WritableNestedModelSerializer,RQLMixin):
""" REST API serializers for OA statuses
"""
id = serializers.IntegerField(required=False)
status = serializers.CharField(allow_null=True)
description = serializers.CharField(allow_null=True)
subscription = serializers.BooleanField(required=False)
accepted_manuscript = serializers.BooleanField(required=False)
apc = serializers.BooleanField(required=False)
final_version = serializers.BooleanField(required=False)
class Meta:
model = Oa
fields = '__all__'
depth = 4
class OrganizationConditionSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializers for Organisation-condition connections
"""
id = serializers.IntegerField(required=False)
organization = OrgaSerializer(required=False)
condition_set = ConditionSetSerializer(required=False)
class Meta:
model = OrganizationCondition
fields = '__all__'
depth = 4
class OrganizationConditionBasicSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializers for Organisation-condition connections
"""
id = serializers.IntegerField(required=False, read_only=False)
organization = serializers.PrimaryKeyRelatedField(queryset=Organization.objects.all(), read_only=False)
condition_set = serializers.PrimaryKeyRelatedField(queryset=ConditionSet.objects.all(), read_only=False)
valid_from = serializers.DateField(required=False, read_only=False)
valid_until = serializers.DateField(required=False, read_only=False)
class Meta:
model = OrganizationCondition
fields = '__all__'
depth = 1
class JournalConditionSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializers for Journal-condition connections
"""
id = serializers.IntegerField(required=False)
journal = JournalSerializer(required=False)
condition_set = ConditionSetSerializer(required=False)
class Meta:
model = JournalCondition
fields = '__all__'
depth = 4
class JournalConditionBasicSerializer(WritableNestedModelSerializer, RQLMixin):
""" REST API serializers for minimal Journal-condition connections
"""
id = serializers.IntegerField(required=False, read_only=False)
journal = serializers.PrimaryKeyRelatedField(queryset=Journal.objects.all(), read_only=False)
condition_set = serializers.PrimaryKeyRelatedField(queryset=ConditionSet.objects.all(), read_only=False)
valid_from = serializers.DateField(required=False, read_only=False)
valid_until = serializers.DateField(required=False, read_only=False)
class Meta:
model = JournalCondition
fields = '__all__'
depth = 1
diff --git a/django_api/views.py b/django_api/views.py
index 3992c08e..4cb486ec 100644
--- a/django_api/views.py
+++ b/django_api/views.py
@@ -1,485 +1,485 @@
"""
This is the Open Access Check Tool (OACT).
The publication of scientific articles as Open Access (OA), usually in the variants "Green OA" and "Gold OA", allows free access to scientific research results and their largely unhindered dissemination. Often, however, the multitude of available publication conditions makes the decision in favor of a particular journal difficult: requirements of the funding agencies and publication guidelines of the universities and colleges must be carefully compared with the offers of the publishing houses, and separately concluded publication agreements can also offer additional benefits. The "OA Compliance Check Tool" provides a comprehensive overview of the possible publication conditions for a large number of journals, especially for the Swiss university landscape, and thus supports the decision-making process.
© All rights reserved. ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, Scientific Information and Libraries, 2022
See LICENSE.TXT for more details.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see
.
"""
from django.contrib.auth.models import AbstractUser
from django.shortcuts import render
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect, Http404, JsonResponse
from .models import *
from .serializers import *
from rest_framework import viewsets, filters, generics
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework_tracking.mixins import LoggingMixin
from itertools import chain
from django.db.models import Count, Max
from dj_rql.filter_cls import RQLFilterClass, AutoRQLFilterClass
from dj_rql.qs import NPR, NSR
from urllib.parse import unquote
from datetime import date
import ipaddress
class JournalFilters(RQLFilterClass):
# TODO accept ISSN values as filter fields
MODEL = Journal
DISTINCT = True
FILTERS = (
'id',
'name',
{"namespace": "classIssn",
"filters": [
{
"filter": "id",
"ordering": True,
"search": False
},
{
"filter": "issn",
"ordering": True,
"search": True
},
{
"filter": "issn_type",
"ordering": True,
"search": True
}
],
"qs": NPR('classIssn')
}
)
class JournalViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
rql_filter_class = JournalFilters
queryset = Journal.objects.all()
serializer_class = JournalSerializer
class JournalLightViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
#search_fields = ['name']
rql_filter_class = JournalFilters
queryset = Journal.objects.all().prefetch_related('publisher', 'language', 'oa_status')
serializer_class = JournalLightSerializer
@method_decorator(cache_page(4 * 60 * 60))
def dispatch(self, request, *args, **kwargs):
# print('dispatch() called')
return super().dispatch(request, *args, **kwargs)
@method_decorator(cache_page(4 * 60 * 60))
def list(self, request):
# print('list() called')
serializer = self.serializer_class(self.queryset, many=True)
return Response(serializer.data)
class OrganizationFilters(RQLFilterClass):
MODEL = Organization
DISTINCT = True
FILTERS = (
'id',
'ror'
)
class OrgaViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = OrgaSerializer
queryset = Organization.objects.filter(
is_funder=False
)
search_fields = ['id', 'ror']
rql_filter_class = OrganizationFilters
class ConditionSetFilters(RQLFilterClass):
""" API filters for the essential query on ConditionSets
Arguments can include a journal id, zero to two organization ids,
validity dates and a condition type.
Request examples:
http://127.0.0.1:8000/api/conditionset/?and(eq(journalcondition.journal.id,3),eq(organizationcondition.organization.id,11),eq(condition_type.id,1))
http://127.0.0.1:8000/api/conditionset/?and(eq(journalcondition.journal.id,14),ne(condition_type.id,2),ge(journalcondition.valid_until,2021-08-20),le(journalcondition.valid_from,2021-08-20),ge(organizationcondition.valid_until,2021-08-20),le(organizationcondition.valid_from,2021-08-20))
"""
MODEL = ConditionSet
DISTINCT = True
FILTERS = (
'id',
{
'namespace': 'journalcondition',
'filters': ['id', 'valid_from', 'valid_until',
{
'namespace': 'journal',
'filters': ['id',
{"namespace": "classIssn",
"filters": [
{
"filter": "id",
"ordering": True,
"search": False
},
{
"filter": "issn",
"ordering": True,
"search": True
},
{
"filter": "issn_type",
"ordering": True,
"search": True
}
],
"qs": NPR('classIssn')}
],
}
],
},
{
'namespace': 'organizationcondition',
'filters': ['id', 'valid_from', 'valid_until',
{
'namespace': 'organization',
'filters': ['id', 'ror']
}
],
},
{
'namespace': 'condition_type',
'filters': ['id', ],
},
)
class JournalConditionFilters(RQLFilterClass):
MODEL = JournalCondition
FILTERS = (
'id',
{
'namespace': 'condition_set',
'filters': ['id', ],
},
{
'namespace': 'journal',
'filters': ['id', ],
},
)
class OrganizationConditionFilters(RQLFilterClass):
MODEL = OrganizationCondition
FILTERS = (
'id',
{
'namespace': 'condition_set',
'filters': ['id', ],
},
{
'namespace': 'organization',
'filters': ['id', ],
},
)
class MyLoggingMixin(LoggingMixin):
"""
Supercharge drf_tracking.LoggingMixin to get the real IP address in the OpenShift infrastructure
"""
def _get_ip_address(self, request):
"""Get the remote ip address the request was generated from."""
# print(request.META)
ipaddr = request.META.get("X-Real-IP", None)
if ipaddr:
ipaddr = ipaddr.split(",")[0]
else:
ipaddr = request.META.get("HTTP_X_FORWARDED_FOR", None)
if ipaddr:
ipaddr = ipaddr.split(",")[0]
else:
ipaddr = request.META.get("REMOTE_ADDR", "").split(",")[0]
# Account for IPv4 and IPv6 addresses, each possibly with port appended. Possibilities are:
#
#
# :port
# []:port
# Note that ipv6 addresses are colon separated hex numbers
possibles = (ipaddr.lstrip("[").split("]")[0], ipaddr.split(":")[0])
for addr in possibles:
try:
return str(ipaddress.ip_address(addr))
except ValueError:
pass
return ipaddr
class ConditionSetViewSet(MyLoggingMixin, viewsets.ModelViewSet):
""" ViewSet for ConditionSets
The QuerySet obtained from the database is annotated to obtain the desired sorting order,
i.e. by condition_type, then subtype, then a calculated score so that institutions receive
more attention than funders within a given type/subtype
"""
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
queryset = ConditionSet.objects.all().annotate(include_funder=Max('organization__is_funder')).order_by('condition_type','subtype', 'include_funder','comment')
# queryset = ConditionSet.objects.values('term__version__description')
serializer_class = ConditionSetSerializer
# serializer_class = ConditionGroupedSerializer
rql_filter_class = ConditionSetFilters
#.objects.values('term__version.description')
class ConditionSetLightViewSet(MyLoggingMixin, viewsets.ModelViewSet):
""" Light-weight ViewSet for ConditionSets
The QuerySet obtained from the database is annotated to obtain the desired sorting order,
i.e. by condition_type, then subtype, then a calculated score so that institutions receive
more attention than funders within a given type/subtype
"""
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
- queryset = ConditionSet.objects.all().annotate(include_funder=Max('organization__is_funder')).order_by('condition_type','subtype','include_funder','comment')
+ queryset = ConditionSet.objects.all().prefetch_related('journal').annotate(include_funder=Max('organization__is_funder')).order_by('condition_type','subtype','include_funder','comment')
serializer_class = ConditionSetLightNewSerializer
rql_filter_class = ConditionSetFilters
class ConditionSetMiniViewSet(MyLoggingMixin, viewsets.ModelViewSet):
""" Light-weight ViewSet for ConditionSets
The QuerySet obtained from the database is annotated to obtain the desired sorting order,
i.e. by condition_type, then subtype, then a calculated score so that institutions receive
more attention than funders within a given type/subtype
"""
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
queryset = ConditionSet.objects.all()
serializer_class = ConditionSetMiniSerializer
rql_filter_class = ConditionSetFilters
class FunderViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = OrgaSerializer
queryset = Organization.objects.filter(
is_funder=True
)
rql_filter_class = OrganizationFilters
class TermFilters(RQLFilterClass):
MODEL = Term
FILTERS = (
'id',
)
class TermViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = TermSerializer
queryset = Term.objects.all()
rql_filter_class = TermFilters
class TermLightViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = TermLightSerializer
queryset = Term.objects.all()
rql_filter_class = TermFilters
class CountryViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = CountrySerializer
queryset = Country.objects.all()
class LanguageViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = LanguageSerializer
queryset = Language.objects.all()
class IssnViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = IssnSerializer
queryset = Issn.objects.all()
class OaViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = OaSerializer
queryset = Oa.objects.all()
class PublisherViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = PublisherSerializer
queryset = Publisher.objects.all()
class VersionViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = VersionSerializer
queryset = Version.objects.all()
class LicenceViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = LicenceSerializer
queryset = Licence.objects.all()
class Cost_factor_typeViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = Cost_factor_typeSerializer
queryset = Cost_factor_type.objects.all()
class Cost_factorViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = Cost_factorSerializer
queryset = Cost_factor.objects.all()
class Cost_factorLightViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = Cost_factorLightSerializer
queryset = Cost_factor.objects.all()
class ConditionTypeViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = ConditionTypeSerializer
queryset = ConditionType.objects.all()
class OrganizationConditionViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = OrganizationConditionSerializer
queryset = OrganizationCondition.objects.all()
class JournalConditionViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = JournalConditionSerializer
queryset = JournalCondition.objects.all()
class OrganizationConditionViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = OrganizationConditionSerializer
queryset = OrganizationCondition.objects.all()
class JournalConditionBasicViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = JournalConditionBasicSerializer
rql_filter_class = JournalConditionFilters
queryset = JournalCondition.objects.all()
def create(self, request, *args, **kwargs):
many = True if isinstance(request.data, list) else False
serializer = self.get_serializer(data=request.data, many=many)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class OrganizationConditionBasicViewSet(viewsets.ModelViewSet):
authentification_classes = (BasicAuthentication,)
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = OrganizationConditionBasicSerializer
rql_filter_class = OrganizationConditionFilters
queryset = OrganizationCondition.objects.all()
def create(self, request, *args, **kwargs):
many = True if isinstance(request.data, list) else False
serializer = self.get_serializer(data=request.data, many=many)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
# Count number of different version
# OrganizationCondition.objects.annotate(version_count=Count('condition_set__term__version'))
# OrganizationCondition.objects
# .values('condition_set__term__version') #what to group by
# .annotate(version_count=Count('condition_set__term__version')) # what to aggregate
# group by version and count
# OrganizationCondition.objects.values('condition_set__term__version').annotate(version_count=Count('condition_set__term__version'))
# source https://hakibenita.com/django-group-by-sql
# https://docs.djangoproject.com/en/3.2/topics/db/aggregation/
# OrganizationCondition.objects.values('condition_set__term__version').filter(organization_id=1).annotate(version_count=Count('condition_set__term__version'))
\ No newline at end of file