1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-11-16 02:04:54 +01:00
market/src/utils/metadata.ts

244 lines
5.8 KiB
TypeScript

import axios from 'axios'
import { toast } from 'react-toastify'
import isUrl from 'is-url-superb'
import {
MetadataMarket,
MetadataPublishFormDataset,
MetadataPublishFormAlgorithm
} from '../@types/MetaData'
import { toStringNoMS } from '.'
import AssetModel from '../models/Asset'
import slugify from '@sindresorhus/slugify'
import { DDO, MetadataAlgorithm, Logger } from '@oceanprotocol/lib'
export function transformTags(value: string): string[] {
const originalTags = value?.split(',')
const transformedTags = originalTags?.map((tag) => slugify(tag).toLowerCase())
return transformedTags
}
export function mapTimeoutStringToSeconds(timeout: string): number {
switch (timeout) {
case 'Forever':
return 0
case '1 day':
return 86400
case '1 week':
return 604800
case '1 month':
return 2630000
case '1 year':
return 31556952
default:
return 0
}
}
function numberEnding(number: number): string {
return number > 1 ? 's' : ''
}
export function secondsToString(numberOfSeconds: number): string {
if (numberOfSeconds === 0) return 'Forever'
const years = Math.floor(numberOfSeconds / 31536000)
const months = Math.floor((numberOfSeconds %= 31536000) / 2630000)
const weeks = Math.floor((numberOfSeconds %= 31536000) / 604800)
const days = Math.floor((numberOfSeconds %= 604800) / 86400)
const hours = Math.floor((numberOfSeconds %= 86400) / 3600)
const minutes = Math.floor((numberOfSeconds %= 3600) / 60)
const seconds = numberOfSeconds % 60
return years
? `${years} year${numberEnding(years)}`
: months
? `${months} month${numberEnding(months)}`
: weeks
? `${weeks} week${numberEnding(weeks)}`
: days
? `${days} day${numberEnding(days)}`
: hours
? `${hours} hour${numberEnding(hours)}`
: minutes
? `${minutes} minute${numberEnding(minutes)}`
: seconds
? `${seconds} second${numberEnding(seconds)}`
: 'less than a second'
}
export function checkIfTimeoutInPredefinedValues(
timeout: string,
timeoutOptions: string[]
): boolean {
if (timeoutOptions.indexOf(timeout) > -1) {
return true
}
return false
}
function getAlgorithmComponent(
image: string,
containerTag: string,
entrypoint: string,
algorithmLanguace: string
): MetadataAlgorithm {
return {
language: algorithmLanguace,
format: 'docker-image',
version: '0.1',
container: {
entrypoint: entrypoint,
image: image,
tag: containerTag
}
}
}
function getAlgorithmFileExtension(fileUrl: string): string {
const splitedFileUrl = fileUrl.split('.')
return splitedFileUrl[splitedFileUrl.length - 1]
}
export function transformPublishFormToMetadata(
{
name,
author,
description,
tags,
links,
termsAndConditions,
files
}: Partial<MetadataPublishFormDataset>,
ddo?: DDO
): MetadataMarket {
const currentTime = toStringNoMS(new Date())
const metadata: MetadataMarket = {
main: {
...AssetModel.main,
name,
author,
dateCreated: ddo ? ddo.created : currentTime,
datePublished: '',
files: typeof files !== 'string' && files,
license: 'https://market.oceanprotocol.com/terms'
},
additionalInformation: {
...AssetModel.additionalInformation,
description,
tags: transformTags(tags),
links: typeof links !== 'string' ? links : [],
termsAndConditions
}
}
return metadata
}
async function isDockerHubImageValid(
image: string,
tag: string
): Promise<boolean> {
try {
const response = await axios.post(
`https://dockerhub-proxy.oceanprotocol.com`,
{
image,
tag
}
)
if (
!response ||
response.status !== 200 ||
response.data.status !== 'success'
) {
toast.error(
'Could not fetch docker hub image info. Please check image name and tag and try again'
)
return false
}
return true
} catch (error) {
Logger.error(error.message)
toast.error(
'Could not fetch docker hub image info. Please check image name and tag and try again'
)
return false
}
}
async function is3rdPartyImageValid(imageURL: string): Promise<boolean> {
try {
const response = await axios.head(imageURL)
if (!response || response.status !== 200) {
toast.error(
'Could not fetch docker image info. Please check URL and try again'
)
return false
}
return true
} catch (error) {
Logger.error(error.message)
toast.error(
'Could not fetch docker image info. Please check URL and try again'
)
return false
}
}
export async function validateDockerImage(
dockerImage: string,
tag: string
): Promise<boolean> {
const isValid = isUrl(dockerImage)
? await is3rdPartyImageValid(dockerImage)
: await isDockerHubImageValid(dockerImage, tag)
return isValid
}
export function transformPublishAlgorithmFormToMetadata(
{
name,
author,
description,
tags,
image,
containerTag,
entrypoint,
termsAndConditions,
files
}: Partial<MetadataPublishFormAlgorithm>,
ddo?: DDO
): MetadataMarket {
const currentTime = toStringNoMS(new Date())
const fileUrl = typeof files !== 'string' && files[0].url
const algorithmLanguage = getAlgorithmFileExtension(fileUrl)
const algorithm = getAlgorithmComponent(
image,
containerTag,
entrypoint,
algorithmLanguage
)
const metadata: MetadataMarket = {
main: {
...AssetModel.main,
name,
type: 'algorithm',
author,
dateCreated: ddo ? ddo.created : currentTime,
files: typeof files !== 'string' && files,
license: 'https://market.oceanprotocol.com/terms',
algorithm
},
additionalInformation: {
...AssetModel.additionalInformation,
description,
tags: transformTags(tags),
termsAndConditions
}
}
return metadata
}