PuQI: Remove additional points for any images above 10 images

Close #6
This commit is contained in:
2025-07-07 15:44:41 +02:00
parent d8244e62e2
commit f4276818fe
2 changed files with 99 additions and 18 deletions

View File

@ -31,6 +31,7 @@ final class MDPuqi {
private const THRESHOLD_CC_OBJECT_DESC_QUITE_LONG = 5000; private const THRESHOLD_CC_OBJECT_DESC_QUITE_LONG = 5000;
public const THRESHOLD_TAGS_TOO_MANY = 10; public const THRESHOLD_TAGS_TOO_MANY = 10;
public const THRESHOLD_MANY_IMAGES = 10;
public const THRESHOLD_IMG_TOO_SMALL = 600; // px public const THRESHOLD_IMG_TOO_SMALL = 600; // px
public const THRESHOLD_IMG_SMALL = 800; // px public const THRESHOLD_IMG_SMALL = 800; // px
public const THRESHOLD_IMG_GOOD_SIZE_SHORTER = 1200; // px public const THRESHOLD_IMG_GOOD_SIZE_SHORTER = 1200; // px
@ -56,8 +57,8 @@ final class MDPuqi {
private const QI_REWARD_OBJ_IS_REF_MULTIPLIER = 5; private const QI_REWARD_OBJ_IS_REF_MULTIPLIER = 5;
private const QI_REWARD_OBJ_RECEPTION_MULTIPLIER = 1; private const QI_REWARD_OBJ_RECEPTION_MULTIPLIER = 1;
private const QI_REWARD_MARKINGS_MULTIPLIER = 3; private const QI_REWARD_MARKINGS_MULTIPLIER = 3;
private const QI_REWARD_IMGS_RESOURCES_MULTIPLIER = 3; public const QI_REWARD_IMGS_RESOURCES_MULTIPLIER = 3;
private const QI_REWARD_IMAGE_SIZE_LARGE = 1; public const QI_REWARD_IMAGE_SIZE_LARGE = 1;
private const QI_REWARD_IMAGE_LICENCE_OPEN_ACCESS = 2; private const QI_REWARD_IMAGE_LICENCE_OPEN_ACCESS = 2;
private const QI_REWARD_IMAGE_LICENCE_OPEN_ACCESS_ATTRIBUTION = 1; private const QI_REWARD_IMAGE_LICENCE_OPEN_ACCESS_ATTRIBUTION = 1;
private const QI_REWARD_METADATA_LICENCE_OPEN_ACCESS = 5; private const QI_REWARD_METADATA_LICENCE_OPEN_ACCESS = 5;
@ -87,8 +88,8 @@ final class MDPuqi {
public const QI_PENALTY_ONLY_TWO_TAG = -5; public const QI_PENALTY_ONLY_TWO_TAG = -5;
private const QI_PENALTY_IMAGE_FILE_MISSING = -5; private const QI_PENALTY_IMAGE_FILE_MISSING = -5;
private const QI_PENALTY_IMAGE_TOO_SMALL = -5; public const QI_PENALTY_IMAGE_TOO_SMALL = -5;
private const QI_PENALTY_IMAGE_SMALL = -2; public const QI_PENALTY_IMAGE_SMALL = -2;
private const QI_PENALTY_IMAGE_NO_OWNER_NO_LICENCE = -15; private const QI_PENALTY_IMAGE_NO_OWNER_NO_LICENCE = -15;
private const QI_PENALTY_IMAGE_NO_OWNER = -10; private const QI_PENALTY_IMAGE_NO_OWNER = -10;
private const QI_PENALTY_IMAGE_NO_LICENCE = -10; private const QI_PENALTY_IMAGE_NO_LICENCE = -10;
@ -780,7 +781,7 @@ final class MDPuqi {
MDPuqiCheckSection::imageCount, MDPuqiCheckSection::imageCount,
MDPuqiMessageStatus::praise, MDPuqiMessageStatus::praise,
$this->_tlLoader->tl("quality", "quality", "many_images"), $this->_tlLoader->tl("quality", "quality", "many_images"),
self::QI_REWARD_IMGS_RESOURCES_MULTIPLIER * (min(10, $count) - 1), self::QI_REWARD_IMGS_RESOURCES_MULTIPLIER * min(self::THRESHOLD_MANY_IMAGES, $count),
); );
break; break;
} }
@ -979,7 +980,7 @@ final class MDPuqi {
MDPuqiCheckSection::imageSizes, MDPuqiCheckSection::imageSizes,
MDPuqiMessageStatus::warning, MDPuqiMessageStatus::warning,
$this->_tlLoader->tl("quality", "quality", "image_too_small") . ' (' . $imgsTooSmall . ')', $this->_tlLoader->tl("quality", "quality", "image_too_small") . ' (' . $imgsTooSmall . ')',
self::QI_PENALTY_IMAGE_TOO_SMALL * $imgsTooSmall, self::QI_PENALTY_IMAGE_TOO_SMALL * min($imgsTooSmall, self::THRESHOLD_MANY_IMAGES),
); );
} }
@ -989,7 +990,7 @@ final class MDPuqi {
MDPuqiCheckSection::imageSizes, MDPuqiCheckSection::imageSizes,
MDPuqiMessageStatus::warning, MDPuqiMessageStatus::warning,
$this->_tlLoader->tl("quality", "quality", "image_quite_small") . ' (' . $imgsSmall . ')', $this->_tlLoader->tl("quality", "quality", "image_quite_small") . ' (' . $imgsSmall . ')',
self::QI_PENALTY_IMAGE_SMALL * $imgsSmall, self::QI_PENALTY_IMAGE_SMALL * min($imgsSmall, self::THRESHOLD_MANY_IMAGES),
); );
} }
@ -999,7 +1000,7 @@ final class MDPuqi {
MDPuqiCheckSection::imageSizes, MDPuqiCheckSection::imageSizes,
MDPuqiMessageStatus::praise, MDPuqiMessageStatus::praise,
$this->_tlLoader->tl("quality", "quality", "image_has_good_size") . ' (' . $imgsLarge . ')', $this->_tlLoader->tl("quality", "quality", "image_has_good_size") . ' (' . $imgsLarge . ')',
self::QI_REWARD_IMAGE_SIZE_LARGE * $imgsLarge, self::QI_REWARD_IMAGE_SIZE_LARGE * min($imgsLarge, self::THRESHOLD_MANY_IMAGES),
); );
} }
@ -1027,7 +1028,7 @@ final class MDPuqi {
if (empty($cur['rightsholder']) and empty($cur['license'])) { if (empty($cur['rightsholder']) and empty($cur['license'])) {
$no_license_or_rightsholder++; $no_license_or_rightsholder++;
} }
else if (empty($cur['rightsholder'])) { else if (empty($cur['rightsholder']) && $cur['license'] !== 'Public Domain Mark') {
$no_rightsholder++; $no_rightsholder++;
} }
else if (empty($cur['license'])) { else if (empty($cur['license'])) {
@ -1050,7 +1051,7 @@ final class MDPuqi {
MDPuqiCheckSection::imageLicenses, MDPuqiCheckSection::imageLicenses,
MDPuqiMessageStatus::praise, MDPuqiMessageStatus::praise,
$this->_tlLoader->tl("quality", "quality", "open_access_licence_used") . ' (' . $license_pd . ')', $this->_tlLoader->tl("quality", "quality", "open_access_licence_used") . ' (' . $license_pd . ')',
self::QI_REWARD_IMAGE_LICENCE_OPEN_ACCESS * $license_pd, self::QI_REWARD_IMAGE_LICENCE_OPEN_ACCESS * min($license_pd, self::THRESHOLD_MANY_IMAGES),
); );
} }
if ($no_license_or_rightsholder) { if ($no_license_or_rightsholder) {
@ -1058,7 +1059,7 @@ final class MDPuqi {
MDPuqiCheckSection::imageLicenses, MDPuqiCheckSection::imageLicenses,
MDPuqiMessageStatus::warning, MDPuqiMessageStatus::warning,
$this->_tlLoader->tl("quality", "quality", "no_rightsholder_no_rightsstatus") . ' (' . $no_license_or_rightsholder . ')', $this->_tlLoader->tl("quality", "quality", "no_rightsholder_no_rightsstatus") . ' (' . $no_license_or_rightsholder . ')',
self::QI_PENALTY_IMAGE_NO_OWNER_NO_LICENCE * $no_license_or_rightsholder, self::QI_PENALTY_IMAGE_NO_OWNER_NO_LICENCE * min($no_license_or_rightsholder, self::THRESHOLD_MANY_IMAGES),
); );
} }
if ($no_rightsholder) { if ($no_rightsholder) {
@ -1066,7 +1067,7 @@ final class MDPuqi {
MDPuqiCheckSection::imageLicenses, MDPuqiCheckSection::imageLicenses,
MDPuqiMessageStatus::warning, MDPuqiMessageStatus::warning,
$this->_tlLoader->tl("quality", "quality", "no_rightsholder") . ' (' . $no_rightsholder . ')', $this->_tlLoader->tl("quality", "quality", "no_rightsholder") . ' (' . $no_rightsholder . ')',
self::QI_PENALTY_IMAGE_NO_OWNER * $no_rightsholder, self::QI_PENALTY_IMAGE_NO_OWNER * $no_rightsholder, min(self::THRESHOLD_MANY_IMAGES),
); );
} }
if ($no_license) { if ($no_license) {
@ -1074,7 +1075,7 @@ final class MDPuqi {
MDPuqiCheckSection::imageLicenses, MDPuqiCheckSection::imageLicenses,
MDPuqiMessageStatus::warning, MDPuqiMessageStatus::warning,
$this->_tlLoader->tl("quality", "quality", "no_rightsstatus") . ' (' . $no_license . ')', $this->_tlLoader->tl("quality", "quality", "no_rightsstatus") . ' (' . $no_license . ')',
self::QI_PENALTY_IMAGE_NO_LICENCE * $no_license, self::QI_PENALTY_IMAGE_NO_LICENCE * min($no_license, self::THRESHOLD_MANY_IMAGES),
); );
} }
if ($license_open_access_attribution) { if ($license_open_access_attribution) {
@ -1082,7 +1083,7 @@ final class MDPuqi {
MDPuqiCheckSection::imageLicenses, MDPuqiCheckSection::imageLicenses,
MDPuqiMessageStatus::praise, MDPuqiMessageStatus::praise,
$this->_tlLoader->tl("quality", "quality", "open_access_licence_used") . ' (' . $license_open_access_attribution . ')', $this->_tlLoader->tl("quality", "quality", "open_access_licence_used") . ' (' . $license_open_access_attribution . ')',
self::QI_REWARD_IMAGE_LICENCE_OPEN_ACCESS_ATTRIBUTION * $license_open_access_attribution, self::QI_REWARD_IMAGE_LICENCE_OPEN_ACCESS_ATTRIBUTION * min($license_open_access_attribution, self::THRESHOLD_MANY_IMAGES),
); );
} }
if ($license_closed_access) { if ($license_closed_access) {
@ -1090,7 +1091,7 @@ final class MDPuqi {
MDPuqiCheckSection::imageLicenses, MDPuqiCheckSection::imageLicenses,
MDPuqiMessageStatus::warning, MDPuqiMessageStatus::warning,
$this->_tlLoader->tl("quality", "quality", "restrictive_licence_used") . ' (' . $license_closed_access . ')', $this->_tlLoader->tl("quality", "quality", "restrictive_licence_used") . ' (' . $license_closed_access . ')',
self::QI_PENALTY_IMAGE_LICENCE_CLOSED_ACCESS * $license_closed_access, self::QI_PENALTY_IMAGE_LICENCE_CLOSED_ACCESS * min($license_closed_access, self::THRESHOLD_MANY_IMAGES),
); );
} }

View File

@ -31,6 +31,23 @@ final class MDPuqiTest extends TestCase {
} }
/**
* Provider for image sizes. 0: width, 1: height, 2: expected status, 3: expected score.
*
* @return Generator<array{0: int, 1: int, 2: MDPuqiMessageStatus, 3:}>
*/
public static function imgSizesProvider():Generator {
yield 'Both too small' => [MDPuqi::THRESHOLD_IMG_TOO_SMALL - 1, MDPuqi::THRESHOLD_IMG_TOO_SMALL - 1, MDPuqiMessageStatus::warning, MDPuqi::QI_PENALTY_IMAGE_TOO_SMALL];
yield 'Width too small' => [MDPuqi::THRESHOLD_IMG_TOO_SMALL - 1, MDPuqi::THRESHOLD_IMG_TOO_SMALL, MDPuqiMessageStatus::warning, MDPuqi::QI_PENALTY_IMAGE_SMALL];
yield 'Height too small' => [MDPuqi::THRESHOLD_IMG_TOO_SMALL, MDPuqi::THRESHOLD_IMG_TOO_SMALL - 1, MDPuqiMessageStatus::warning, MDPuqi::QI_PENALTY_IMAGE_SMALL];
yield 'Both small' => [MDPuqi::THRESHOLD_IMG_SMALL - 1, MDPuqi::THRESHOLD_IMG_SMALL - 1, MDPuqiMessageStatus::warning, MDPuqi::QI_PENALTY_IMAGE_SMALL];
yield 'Both good sized' => [MDPuqi::THRESHOLD_IMG_GOOD_SIZE_SHORTER + 1, MDPuqi::THRESHOLD_IMG_GOOD_SIZE_LONGER + 1, MDPuqiMessageStatus::praise, MDPuqi::QI_REWARD_IMAGE_SIZE_LARGE];
}
/** /**
* Test for license. * Test for license.
* *
@ -69,8 +86,7 @@ final class MDPuqiTest extends TestCase {
#[DataProvider('licenseProvider')] #[DataProvider('licenseProvider')]
public function testImageLicensesResultInExpectedAccessment(string $input, MDPuqiMessageStatus $warningStatus, bool $positive):void { public function testImageLicensesResultInExpectedAccessment(string $input, MDPuqiMessageStatus $warningStatus, bool $positive):void {
$tlLoader = new MDTlLoader("abc", "en"); $puqi = new MDPuqi(new MDTlLoader("abc", "en"));
$puqi = new MDPuqi($tlLoader);
$puqi->checkImageLicenses([['license' => $input, 'rightsholder' => 'Somebody']]); $puqi->checkImageLicenses([['license' => $input, 'rightsholder' => 'Somebody']]);
$msgs = $puqi->getMessages(); $msgs = $puqi->getMessages();
@ -81,6 +97,71 @@ final class MDPuqiTest extends TestCase {
$score = $puqi->getScore(); $score = $puqi->getScore();
self::assertEquals($positive, $score > 0, "Expected score to be positive or negative, got the oppite result. Score is: " . $score); self::assertEquals($positive, $score > 0, "Expected score to be positive or negative, got the oppite result. Score is: " . $score);
// Get score. Having the same 100 times should not inflate the score.
$expectedMaxScore = $score * MDPuqi::THRESHOLD_MANY_IMAGES;
$puqi = new MDPuqi(new MDTlLoader("abc", "en"));
$inp = [];
for ($i = 0; $i < MDPuqi::THRESHOLD_MANY_IMAGES * 10; $i++) {
$inp[] = ['license' => $input, 'rightsholder' => 'Somebody'];
}
$puqi->checkImageLicenses($inp);
self::assertEquals($expectedMaxScore, $puqi->getScore(), "Expected max. score to be stopped from increasing by threshold. It was not.");
}
/**
* Test for image sizes.
*
* @param integer $width Width.
* @param integer $height Height.
* @param MDPuqiMessageStatus $expectedStatus Expected message status.
* @param integer $expectedScore Expected score.
*
* @return void
*/
#[DataProvider('imgSizesProvider')]
public function testImageSizesResultInExpectedAccessment(int $width, int $height, MDPuqiMessageStatus $expectedStatus, int $expectedScore):void {
$puqi = new MDPuqi(new MDTlLoader("abc", "en"));
$puqi->checkImageSizes([['width' => $width, 'height' => $height]]);
$msgs = $puqi->getMessages();
self::assertEquals(1, count($msgs));
$msg = $msgs[0];
self::assertEquals($expectedStatus, $msg->status);
self::assertEquals($expectedScore, $puqi->getScore());
// Get score. Having the same 100 times should not inflate the score.
$expectedMaxScore = $expectedScore * MDPuqi::THRESHOLD_MANY_IMAGES;
$puqi = new MDPuqi(new MDTlLoader("abc", "en"));
$inp = [];
for ($i = 0; $i < MDPuqi::THRESHOLD_MANY_IMAGES * 10; $i++) {
$inp[] = ['width' => $width, 'height' => $height];
}
$puqi->checkImageSizes($inp);
self::assertEquals($expectedMaxScore, $puqi->getScore(), "Expected max. score to be stopped from increasing by threshold. It was not.");
}
/**
* Test that more than ten images do not result in inflated score.
* Case: checkImageCount.
*
* @return void
*/
public function testManyImagesDoesNotInflateScoreByCount():void {
$puqi = new MDPuqi(new MDTlLoader("abc", "en"));
$puqi->checkImageCount(500);
$msgs = $puqi->getMessages();
$score = $puqi->getScore();
self::assertEquals(MDPuqi::THRESHOLD_MANY_IMAGES * MDPuqi::QI_REWARD_IMGS_RESOURCES_MULTIPLIER, $score, "Image count eval: Score differs from expected. Messages: " . var_export($puqi->getMessages(), true));
} }
/** /**
@ -113,7 +194,6 @@ final class MDPuqiTest extends TestCase {
$puqi = new MDPuqi(new MDTlLoader("abc", "en")); $puqi = new MDPuqi(new MDTlLoader("abc", "en"));
$puqi->checkEvents([], [], [], [], $noOfTags); $puqi->checkEvents([], [], [], [], $noOfTags);
$msgs = $puqi->getMessages();
$score = $puqi->getScore(); $score = $puqi->getScore();
self::assertEquals(MDPuqi::QI_PENALTY_NO_EVENTS + $expectedScore, $score, "Tag eval: Score differs from expected. Messages: " . var_export($puqi->getMessages(), true)); self::assertEquals(MDPuqi::QI_PENALTY_NO_EVENTS + $expectedScore, $score, "Tag eval: Score differs from expected. Messages: " . var_export($puqi->getMessages(), true));