diff --git a/README.md b/README.md index 8f7c22e795..e70cc515ee 100644 --- a/README.md +++ b/README.md @@ -9,17 +9,19 @@ These instructions will get you a copy of the project up and running on your loc ### Prerequisites -* [Redhat Linux 8](https://www.redhat.com/) - Redhat Linux or compatible -* [ClamAV](https://www.clamav.net) - ClamAV® open source antivirus engine -* [PHP 8.1+](http://php.net/docs.php) - General-purpose scripting language -* [PostgreSQL 13+](https://www.postgresql.org) - ORDBMS +* [Redhat Linux 8+](https://www.redhat.com/) - Redhat Linux or compatible +* [PHP 8.2+](http://php.net/docs.php) - General-purpose scripting language +* [Composer 2.8.2+](https://getcomposer.org/) - Dependency Manager for PHP +* [Yarn 1.22.22+](https://yarnpkg.com/en/) - Package Manager +* [PostgreSQL 14+](https://www.postgresql.org) - ORDBMS +* [PostGIS 3.4.3](https://www.postgis.net/) - Geographic Information Systems Extensions to PostgreSQL * [Elasticsearch 7.17+](https://www.elastic.co/products/elasticsearch) - ElasticSearch Document Indexer -* [Composer 2.5.1+](https://getcomposer.org/) - Dependency Manager for PHP -* [Yarn 1.22.19+](https://yarnpkg.com/en/) - Package Manager +* [Wkhtmltox 0.12.6.1+](https://wkhtmltopdf.org/) - PDF generation utility +* [ClamAV](https://www.clamav.net) - ClamAV® open source antivirus engine ### Installation -Pelagos is a [Symfony 5.4+](https://symfony.com) project, please follow the normal configuration regarding setting up your webserver for a Symfony project. +Pelagos is a [Symfony 6.4+](https://symfony.com) project, please follow the normal configuration regarding setting up your webserver for a Symfony project. To install fullfill prerequisites then run: * `composer install` diff --git a/assets/static/js/geoviz.js b/assets/static/js/geoviz.js index 57897ac57a..f0a306a6ac 100644 --- a/assets/static/js/geoviz.js +++ b/assets/static/js/geoviz.js @@ -922,7 +922,7 @@ function GeoViz() } else { - pointList = pointList.split(" "); + pointList = pointList.trim().split(" "); var points = ""; for (var i=0;i";errMsg=undefined;}; + if (typeof errMsg != "undefined") { message += "

Reason: "+errMsg+"

";errMsg=undefined;}; $("
"+message+"
").dialog({ height: "auto", width: "auto", diff --git a/composer.json b/composer.json index 1b7e82b4e2..3100097ae4 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "homepage": "https://github.com/griidc/pelagos/", "license": "BSD-2-Clause", "require": { - "php": "^8.1", + "php": "^8.2", "ext-ctype": "*", "ext-curl": "*", "ext-fileinfo": "*", diff --git a/composer.lock b/composer.lock index 2e8a82e8aa..9b18f46b5c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "34ce98ca7da8a58022fa842c25cee11f", + "content-hash": "0a496dc471c8e089a701a6fa0165b6be", "packages": [ { "name": "brick/math", @@ -6313,36 +6313,36 @@ }, { "name": "symfony/http-foundation", - "version": "v6.4.12", + "version": "v7.1.7", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "133ac043875f59c26c55e79cf074562127cce4d2" + "reference": "5183b61657807099d98f3367bcccb850238b17a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/133ac043875f59c26c55e79cf074562127cce4d2", - "reference": "133ac043875f59c26c55e79cf074562127cce4d2", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5183b61657807099d98f3367bcccb850238b17a9", + "reference": "5183b61657807099d98f3367bcccb850238b17a9", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.1", "symfony/polyfill-php83": "^1.27" }, "conflict": { - "symfony/cache": "<6.3" + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4" }, "require-dev": { - "doctrine/dbal": "^2.13.1|^3|^4", + "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.3|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", - "symfony/mime": "^5.4|^6.0|^7.0", - "symfony/rate-limiter": "^5.4|^6.0|^7.0" + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6370,7 +6370,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.12" + "source": "https://github.com/symfony/http-foundation/tree/v7.1.7" }, "funding": [ { @@ -6386,7 +6386,7 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:18:25+00:00" + "time": "2024-11-06T09:02:46+00:00" }, { "name": "symfony/http-kernel", @@ -8164,20 +8164,20 @@ }, { "name": "symfony/process", - "version": "v6.4.12", + "version": "v7.1.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "3f94e5f13ff58df371a7ead461b6e8068900fbb3" + "reference": "9b8a40b7289767aa7117e957573c2a535efe6585" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/3f94e5f13ff58df371a7ead461b6e8068900fbb3", - "reference": "3f94e5f13ff58df371a7ead461b6e8068900fbb3", + "url": "https://api.github.com/repos/symfony/process/zipball/9b8a40b7289767aa7117e957573c2a535efe6585", + "reference": "9b8a40b7289767aa7117e957573c2a535efe6585", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "type": "library", "autoload": { @@ -8205,7 +8205,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.12" + "source": "https://github.com/symfony/process/tree/v7.1.7" }, "funding": [ { @@ -8221,7 +8221,7 @@ "type": "tidelift" } ], - "time": "2024-09-17T12:47:12+00:00" + "time": "2024-11-06T09:25:12+00:00" }, { "name": "symfony/property-access", @@ -8468,16 +8468,16 @@ }, { "name": "symfony/runtime", - "version": "v6.4.12", + "version": "v6.4.14", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "bfe32a1adf41da4dd7f6b939a039779d7af5497f" + "reference": "4facd4174f45cd37c65860403412b67c7381136a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/bfe32a1adf41da4dd7f6b939a039779d7af5497f", - "reference": "bfe32a1adf41da4dd7f6b939a039779d7af5497f", + "url": "https://api.github.com/repos/symfony/runtime/zipball/4facd4174f45cd37c65860403412b67c7381136a", + "reference": "4facd4174f45cd37c65860403412b67c7381136a", "shasum": "" }, "require": { @@ -8527,7 +8527,7 @@ "runtime" ], "support": { - "source": "https://github.com/symfony/runtime/tree/v6.4.12" + "source": "https://github.com/symfony/runtime/tree/v6.4.14" }, "funding": [ { @@ -8543,7 +8543,7 @@ "type": "tidelift" } ], - "time": "2024-09-19T13:29:10+00:00" + "time": "2024-11-05T16:39:55+00:00" }, { "name": "symfony/security-bundle", @@ -10213,16 +10213,16 @@ }, { "name": "twig/twig", - "version": "v3.14.0", + "version": "v3.14.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72" + "reference": "f405356d20fb43603bcadc8b09bfb676cb04a379" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/126b2c97818dbff0cdf3fbfc881aedb3d40aae72", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/f405356d20fb43603bcadc8b09bfb676cb04a379", + "reference": "f405356d20fb43603bcadc8b09bfb676cb04a379", "shasum": "" }, "require": { @@ -10276,7 +10276,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.14.0" + "source": "https://github.com/twigphp/Twig/tree/v3.14.1" }, "funding": [ { @@ -10288,7 +10288,7 @@ "type": "tidelift" } ], - "time": "2024-09-09T17:55:12+00:00" + "time": "2024-11-06T18:17:38+00:00" }, { "name": "willdurand/jsonp-callback-validator", @@ -13325,7 +13325,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^8.1", + "php": "^8.2", "ext-ctype": "*", "ext-curl": "*", "ext-fileinfo": "*", diff --git a/src/Command/GetGoMRIStatisticsCommand.php b/src/Command/GetGoMRIStatisticsCommand.php index 9739d283be..8b797fb84d 100644 --- a/src/Command/GetGoMRIStatisticsCommand.php +++ b/src/Command/GetGoMRIStatisticsCommand.php @@ -117,21 +117,32 @@ protected function execute(InputInterface $input, OutputInterface $output): int $io->writeln("\nGoMRI Downloads:\n"); $downloadSizeByYearAndQuarter = []; - $downloadCountByYearAndQuarter = []; + $anonymousDownloadCountByYearAndQuarter = []; + $loggedInDownloadCountByYearAndQuarter = []; + foreach ($this->getDownloads() as $datasetDownload) { $id = $datasetDownload[0]; $timestamp = $datasetDownload[1]; + $loginType = $datasetDownload[2]; $yearQuarter = $this->determineQuarter($timestamp); $year = $yearQuarter['year']; $quarter = $yearQuarter['quarter']; - if (!array_key_exists($year, $downloadCountByYearAndQuarter)) { - $downloadCountByYearAndQuarter[$year][0] = 0; - $downloadCountByYearAndQuarter[$year][1] = 0; - $downloadCountByYearAndQuarter[$year][2] = 0; - $downloadCountByYearAndQuarter[$year][3] = 0; - $downloadCountByYearAndQuarter[$year][4] = 0; + if (!array_key_exists($year, $anonymousDownloadCountByYearAndQuarter)) { + $anonymousDownloadCountByYearAndQuarter[$year][0] = 0; + $anonymousDownloadCountByYearAndQuarter[$year][1] = 0; + $anonymousDownloadCountByYearAndQuarter[$year][2] = 0; + $anonymousDownloadCountByYearAndQuarter[$year][3] = 0; + $anonymousDownloadCountByYearAndQuarter[$year][4] = 0; + } + + if (!array_key_exists($year, $loggedInDownloadCountByYearAndQuarter)) { + $loggedInDownloadCountByYearAndQuarter[$year][0] = 0; + $loggedInDownloadCountByYearAndQuarter[$year][1] = 0; + $loggedInDownloadCountByYearAndQuarter[$year][2] = 0; + $loggedInDownloadCountByYearAndQuarter[$year][3] = 0; + $loggedInDownloadCountByYearAndQuarter[$year][4] = 0; } if (!array_key_exists($year, $downloadSizeByYearAndQuarter)) { @@ -152,16 +163,20 @@ protected function execute(InputInterface $input, OutputInterface $output): int $skipCount++; } - $downloadCountByYearAndQuarter[$year][$quarter]++; + if ($loginType === 'anonymous') { + $anonymousDownloadCountByYearAndQuarter[$year][$quarter]++; + } else { + $loggedInDownloadCountByYearAndQuarter[$year][$quarter]++; + } $downloadSizeByYearAndQuarter[$year][$quarter] += $size / 1000000000; } // array_keys still onlys dump first level, years, for $array[year][quarter]. - $firstYear = min(array_keys($downloadCountByYearAndQuarter)); - $lastYear = max(array_keys($downloadCountByYearAndQuarter)); + $firstYear = min(array_keys($anonymousDownloadCountByYearAndQuarter)); + $lastYear = max(array_keys($anonymousDownloadCountByYearAndQuarter)); - // Deal with the data harvest of 2019Q2. - $downloadCountByYearAndQuarter[2019][2] -= self::HARVEST2019COUNT; + // Deal with the data harvest of 2019Q2. (were not logged-in) + $anonymousDownloadCountByYearAndQuarter[2019][2] -= self::HARVEST2019COUNT; $downloadSizeByYearAndQuarter[2019][2] -= self::HARVEST2019DATA; $totalDownloads = 0; @@ -171,12 +186,26 @@ protected function execute(InputInterface $input, OutputInterface $output): int $yearSizeTotal = 0; for ($quarter = 1; $quarter <= 4; $quarter++) { $popularDownloads = $this->getTopDatasetsDownloadedByYearAndQuarter(self::NUMBEROFTOPDOWNLOADSTOSHOW, $year, $quarter); - $io->writeln($year . '/Q' . $quarter . ' Download Count: ' . $downloadCountByYearAndQuarter[$year][$quarter] - . ', ' . 'Total Size (GB): ' . round($downloadSizeByYearAndQuarter[$year][$quarter])); - $yearCountTotal += $downloadCountByYearAndQuarter[$year][$quarter]; - $totalDownloads += $downloadCountByYearAndQuarter[$year][$quarter]; + $io->writeln( + $year + . '/Q' + . $quarter + . ' Logged-in Download Count: ' + . $loggedInDownloadCountByYearAndQuarter[$year][$quarter] + . ' Anonymous DL Count: ' + . $anonymousDownloadCountByYearAndQuarter[$year][$quarter] + . ', ' . 'Total Size (GB): ' + . round($downloadSizeByYearAndQuarter[$year][$quarter]) + ); + + $yearCountTotal += $loggedInDownloadCountByYearAndQuarter[$year][$quarter]; + $yearCountTotal += $anonymousDownloadCountByYearAndQuarter[$year][$quarter]; + $totalDownloads += $loggedInDownloadCountByYearAndQuarter[$year][$quarter]; + $totalDownloads += $anonymousDownloadCountByYearAndQuarter[$year][$quarter]; + $yearSizeTotal += $downloadSizeByYearAndQuarter[$year][$quarter]; $totalDownloadSize += $downloadSizeByYearAndQuarter[$year][$quarter]; + $popular = "Top: "; foreach ($popularDownloads as $udi => $count) { $popular .= "$udi:$count, "; @@ -349,8 +378,9 @@ public function getTopDatasetsDownloadedByYearAndQuarter(int $count, int $year = */ public function getDownloads(): array { + $qb = $this->entityManager->getRepository(LogActionItem::class)->createQueryBuilder('log') - ->select('log.creationTimeStamp, log.subjectEntityId') + ->select('log.creationTimeStamp, log.subjectEntityId, log.payLoad') ->where('log.subjectEntityName = :entityName') ->andWhere('log.actionName = :actionName') ->orderBy('log.subjectEntityId', 'ASC') @@ -382,8 +412,16 @@ public function getDownloads(): array if (($displayTime === '2014-09-27') or $key === array_key_first($downloads) or ($epochTime - $currentTimeStamp) > 30 or $currentId != $id) { $currentTimeStamp = $epochTime; - $downloadArray[] = array($id, $dateTime); + + if (($timeStamp['payLoad']['userId'] ?? 'anonymous') === 'anonymous') { + $user = 'anonymous'; + } else { + $user = 'logged-in'; + } + + $downloadArray[] = array($id, $dateTime, $user); } + $currentId = $id; } return $downloadArray; diff --git a/src/Command/PelagosGetFiletypesCommand.php b/src/Command/PelagosGetFiletypesCommand.php new file mode 100644 index 0000000000..3ceb20d0ab --- /dev/null +++ b/src/Command/PelagosGetFiletypesCommand.php @@ -0,0 +1,76 @@ +entityManager->getRepository(Dataset::class)->findAll(); + foreach ($datasets as $dataset) { + $udi = $dataset->getUdi(); + $fileTypes = $this->getFileTypes($dataset); + print "$udi,$fileTypes\n"; + } + + $io->success('List Complete'); + + return Command::SUCCESS; + } + + /** + * Get list of filetypes used per UDI. + */ + private function getFileTypes(Dataset $dataset): ?string + { + $datasetSubmission = $dataset->getDatasetSubmission(); + if ($datasetSubmission instanceof DatasetSubmission) { + $fileSet = $datasetSubmission->getFileset(); + if ($fileSet instanceof Fileset) { + $fileTypes = []; + foreach ($fileSet->getAllFiles() as $file) { + $type = pathinfo($file->getFilePathName(), PATHINFO_EXTENSION); + if (array_key_exists($type, $fileTypes)) { + $fileTypes[$type]++; + } else { + $fileTypes[$type] = 1; + } + } + $fileList = ''; + foreach ($fileTypes as $key => $value) { + $fileList .= $key . ',' . $value . ','; + } + $fileList = rtrim($fileList, ','); + return $fileList; + } + } + return null; + } +} diff --git a/templates/Dataland/metadata.markup.twig b/templates/Dataland/metadata.markup.twig index 840ee02fe3..ff4a3cd0b7 100644 --- a/templates/Dataland/metadata.markup.twig +++ b/templates/Dataland/metadata.markup.twig @@ -2,6 +2,14 @@ { "name" : "{{dataset.title}}", "alternateName" : "{{dataset.datasetSubmission.shortTitle}}", + "creator:[ + { + "@type": "Person", + "name": "{{dataset.datasetSubmission.datasetContacts[0].person.lastName}}, {{dataset.datasetSubmission.datasetContacts[0].person.firstName}}", + "givenName": "{{dataset.datasetSubmission.datasetContacts[0].person.firstName}}", + "familyName": "{{dataset.datasetSubmission.datasetContacts[0].person.lastName}}" + } + ], "description" : "{{dataset.abstract}}", "identifier" : "{{dataset.doi}}", "keywords" : "{{dataset.datasetSubmission.themeKeywords | join(',')}}", diff --git a/yarn.lock b/yarn.lock index fd12d174b2..2943a32811 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4235,9 +4235,9 @@ http-parser-js@>=0.5.1: integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + version "2.0.7" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz#915f236d92ae98ef48278a95dedf17e991936ec6" + integrity sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1"