mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-20 17:15:51 +02:00
Moved OEMSecrets config to new settings system
This commit is contained in:
parent
97aed847b6
commit
3d4e91fc69
6 changed files with 281 additions and 109 deletions
|
@ -216,16 +216,6 @@ services:
|
|||
$onlyAuthorizedSellers: '%env(bool:PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS)%'
|
||||
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\OEMSecretsProvider:
|
||||
arguments:
|
||||
$api_key: '%env(string:PROVIDER_OEMSECRETS_KEY)%'
|
||||
$country_code: '%env(string:PROVIDER_OEMSECRETS_COUNTRY_CODE)%'
|
||||
$currency: '%env(PROVIDER_OEMSECRETS_CURRENCY)%'
|
||||
$zero_price: '%env(PROVIDER_OEMSECRETS_ZERO_PRICE)%'
|
||||
$set_param: '%env(PROVIDER_OEMSECRETS_SET_PARAM)%'
|
||||
$sort_criteria: '%env(PROVIDER_OEMSECRETS_SORT_CRITERIA)%'
|
||||
|
||||
|
||||
####################################################################################################################
|
||||
# API system
|
||||
####################################################################################################################
|
||||
|
|
|
@ -88,6 +88,8 @@ use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
|||
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
||||
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
||||
use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
|
||||
use App\Settings\InfoProviderSystem\OEMSecretsSettings;
|
||||
use App\Settings\InfoProviderSystem\OEMSecretsSortMode;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
|
||||
|
@ -99,12 +101,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
|
||||
public function __construct(
|
||||
private readonly HttpClientInterface $oemsecretsClient,
|
||||
private readonly string $api_key,
|
||||
private readonly string $country_code,
|
||||
private readonly string $currency,
|
||||
private readonly string $zero_price,
|
||||
private readonly string $set_param,
|
||||
private readonly string $sort_criteria,
|
||||
private readonly OEMSecretsSettings $settings,
|
||||
private readonly CacheItemPoolInterface $partInfoCache
|
||||
)
|
||||
{
|
||||
|
@ -268,7 +265,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
*/
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->api_key !== '';
|
||||
return $this->settings->apiKey !== '';
|
||||
}
|
||||
|
||||
|
||||
|
@ -324,9 +321,9 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
$response = $this->oemsecretsClient->request('GET', self::ENDPOINT_URL, [
|
||||
'query' => [
|
||||
'searchTerm' => $keyword,
|
||||
'apiKey' => $this->api_key,
|
||||
'currency' => $this->currency,
|
||||
'countryCode' => $this->country_code,
|
||||
'apiKey' => $this->settings->apiKey,
|
||||
'currency' => $this->settings->currency,
|
||||
'countryCode' => $this->settings->country,
|
||||
],
|
||||
]);
|
||||
|
||||
|
@ -533,7 +530,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
|
||||
// Extract prices
|
||||
$priceDTOs = $this->getPrices($product);
|
||||
if (empty($priceDTOs) && (int)$this->zero_price === 0) {
|
||||
if (empty($priceDTOs) && !$this->settings->keepZeroPrices) {
|
||||
return null; // Skip products without valid prices
|
||||
}
|
||||
|
||||
|
@ -557,7 +554,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
}
|
||||
|
||||
$imagesResults[$provider_id] = $this->getImages($product, $imagesResults[$provider_id] ?? []);
|
||||
if ($this->set_param == 1) {
|
||||
if ($this->settings->parseParams) {
|
||||
$parametersResults[$provider_id] = $this->getParameters($product, $parametersResults[$provider_id] ?? []);
|
||||
} else {
|
||||
$parametersResults[$provider_id] = [];
|
||||
|
@ -582,7 +579,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
$regionB = $this->countryCodeToRegionMap[$countryCodeB] ?? '';
|
||||
|
||||
// If the map is empty or doesn't contain the key for $this->country_code, assign a placeholder region.
|
||||
$regionForEnvCountry = $this->countryCodeToRegionMap[$this->country_code] ?? '';
|
||||
$regionForEnvCountry = $this->countryCodeToRegionMap[$this->settings->country] ?? '';
|
||||
|
||||
// Convert to string before comparison to avoid mixed types
|
||||
$countryCodeA = (string) $countryCodeA;
|
||||
|
@ -599,9 +596,9 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
}
|
||||
|
||||
// Step 1: country_code from the environment
|
||||
if ($countryCodeA === $this->country_code && $countryCodeB !== $this->country_code) {
|
||||
if ($countryCodeA === $this->settings->country && $countryCodeB !== $this->settings->country) {
|
||||
return -1;
|
||||
} elseif ($countryCodeA !== $this->country_code && $countryCodeB === $this->country_code) {
|
||||
} elseif ($countryCodeA !== $this->settings->country && $countryCodeB === $this->settings->country) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -681,8 +678,8 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
|
||||
if (is_array($prices)) {
|
||||
// Step 1: Check if prices exist in the preferred currency
|
||||
if (isset($prices[$this->currency]) && is_array($prices[$this->currency])) {
|
||||
$priceDetails = $prices[$this->currency];
|
||||
if (isset($prices[$this->settings->currency]) && is_array($prices[$this->settings->currency])) {
|
||||
$priceDetails = $prices[$this->$this->settings->currency];
|
||||
foreach ($priceDetails as $priceDetail) {
|
||||
if (
|
||||
is_array($priceDetail) &&
|
||||
|
@ -694,7 +691,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
$priceDTOs[] = new PriceDTO(
|
||||
minimum_discount_amount: (float)$priceDetail['unit_break'],
|
||||
price: (string)$priceDetail['unit_price'],
|
||||
currency_iso_code: $this->currency,
|
||||
currency_iso_code: $this->settings->currency,
|
||||
includes_tax: false,
|
||||
price_related_quantity: 1.0
|
||||
);
|
||||
|
@ -1293,7 +1290,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
private function sortResultsData(array &$resultsData, string $searchKeyword): void
|
||||
{
|
||||
// If the SORT_CRITERIA is not 'C' or 'M', do not sort
|
||||
if ($this->sort_criteria !== 'C' && $this->sort_criteria !== 'M') {
|
||||
if ($this->settings->sortMode !== OEMSecretsSortMode::COMPLETENESS && $this->settings->sortMode !== OEMSecretsSortMode::MANUFACTURER) {
|
||||
return;
|
||||
}
|
||||
usort($resultsData, function ($a, $b) use ($searchKeyword) {
|
||||
|
@ -1332,9 +1329,9 @@ class OEMSecretsProvider implements InfoProviderInterface
|
|||
}
|
||||
|
||||
// Final sorting: by completeness or manufacturer, if necessary
|
||||
if ($this->sort_criteria === 'C') {
|
||||
if ($this->settings->sortMode === OEMSecretsSortMode::COMPLETENESS) {
|
||||
return $this->compareByCompleteness($a, $b);
|
||||
} elseif ($this->sort_criteria === 'M') {
|
||||
} elseif ($this->settings->sortMode === OEMSecretsSortMode::MANUFACTURER) {
|
||||
return strcasecmp($a->manufacturer, $b->manufacturer);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,4 +43,7 @@ class InfoProviderSettings
|
|||
|
||||
#[EmbeddedSettings]
|
||||
public ?LCSCSettings $lcsc = null;
|
||||
|
||||
#[EmbeddedSettings]
|
||||
public ?OEMSecretsSettings $oemsecrets = null;
|
||||
}
|
82
src/Settings/InfoProviderSystem/OEMSecretsSettings.php
Normal file
82
src/Settings/InfoProviderSystem/OEMSecretsSettings.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CountryType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||
|
||||
#[Settings(label: new TM("settings.ips.oemsecrets"))]
|
||||
#[SettingsIcon("fa-plug")]
|
||||
class OEMSecretsSettings
|
||||
{
|
||||
use SettingsTrait;
|
||||
|
||||
public const SUPPORTED_CURRENCIES = ["AUD", "CAD", "CHF", "CNY", "DKK", "EUR", "GBP", "HKD", "ILS", "INR", "JPY", "KRW", "NOK",
|
||||
"NZD", "RUB", "SEK", "SGD", "TWD", "USD"];
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.element14.apiKey"), envVar: "PROVIDER_OEMSECRETS_KEY")]
|
||||
public ?string $apiKey = null;
|
||||
|
||||
#[Assert\Country]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR", "US"]], envVar: "PROVIDER_OEMSECRETS_COUNTRY_CODE")]
|
||||
public ?string $country = "DE";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => self::SUPPORTED_CURRENCIES], envVar: "PROVIDER_OEMSECRETS_CURRENCY")]
|
||||
#[Assert\Choice(choices: self::SUPPORTED_CURRENCIES)]
|
||||
public string $currency = "EUR";
|
||||
|
||||
/**
|
||||
* @var bool If this is enabled, distributors with zero prices
|
||||
* will be discarded from the creation of a new part
|
||||
*/
|
||||
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.keepZeroPrices"), description: new TM("settings.ips.oemsecrets.keepZeroPrices.help"), envVar: "bool:PROVIDER_OEMSECRETS_ZERO_PRICE")]
|
||||
public bool $keepZeroPrices = false;
|
||||
|
||||
/**
|
||||
* @var bool If set to 1 the parameters for the part are generated
|
||||
* # from the description transforming unstructured descriptions into structured parameters;
|
||||
* # each parameter in description should have the form: "...;name1:value1;name2:value2"
|
||||
*/
|
||||
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.parseParams"), description: new TM("settings.ips.oemsecrets.parseParams.help"), envVar: "bool:PROVIDER_OEMSECRETS_SET_PARAM")]
|
||||
public bool $parseParams = true;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.sortMode"), envVar: "PROVIDER_OEMSECRETS_SORT_CRITERIA", envVarMapper: [self::class, "mapSortModeEnvVar"])]
|
||||
public OEMSecretsSortMode $sortMode = OEMSecretsSortMode::COMPLETENESS;
|
||||
|
||||
|
||||
public static function mapSortModeEnvVar(?string $value): OEMSecretsSortMode
|
||||
{
|
||||
if (!$value) {
|
||||
return OEMSecretsSortMode::NONE;
|
||||
}
|
||||
|
||||
return OEMSecretsSortMode::tryFrom($value) ?? OEMSecretsSortMode::NONE;
|
||||
}
|
||||
}
|
46
src/Settings/InfoProviderSystem/OEMSecretsSortMode.php
Normal file
46
src/Settings/InfoProviderSystem/OEMSecretsSortMode.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use Symfony\Contracts\Translation\TranslatableInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* This environment variable determines the sorting criteria for product results.
|
||||
* The sorting process first arranges items based on the provided keyword.
|
||||
* Then, if set to 'C', it further sorts by completeness (prioritizing items with the most
|
||||
* detailed information). If set to 'M', it further sorts by manufacturer name.
|
||||
* If unset or set to any other value, no sorting is performed.
|
||||
*/
|
||||
enum OEMSecretsSortMode : string implements TranslatableInterface
|
||||
{
|
||||
case NONE = "N";
|
||||
case COMPLETENESS = "C";
|
||||
case MANUFACTURER = "M";
|
||||
|
||||
public function trans(TranslatorInterface $translator, ?string $locale = null): string
|
||||
{
|
||||
return $translator->trans('settings.ips.oemsecrets.sortMode.' . $this->value, locale: $locale);
|
||||
}
|
||||
}
|
|
@ -12323,474 +12323,528 @@ Please note, that you can not impersonate a disabled user. If you try you will g
|
|||
<target>Profile saved!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="XbdePfV" name="settings.ips.element14">
|
||||
<unit id="XUlcyOb" name="settings.ips.element14">
|
||||
<segment>
|
||||
<source>settings.ips.element14</source>
|
||||
<target>Element 14 / Farnell</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="uTQxPoA" name="settings.ips.element14.apiKey">
|
||||
<unit id="1N9Wp0_" name="settings.ips.element14.apiKey">
|
||||
<segment>
|
||||
<source>settings.ips.element14.apiKey</source>
|
||||
<target>API Key</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="AfkWDFj" name="settings.ips.element14.apiKey.help">
|
||||
<unit id="p7LGAIX" name="settings.ips.element14.apiKey.help">
|
||||
<segment>
|
||||
<source>settings.ips.element14.apiKey.help</source>
|
||||
<target><![CDATA[You can register for an API key on <a href="https://partner.element14.com/">https://partner.element14.com/</a>.]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="JTgaXDQ" name="settings.ips.element14.storeId">
|
||||
<unit id="ZdUHpZc" name="settings.ips.element14.storeId">
|
||||
<segment>
|
||||
<source>settings.ips.element14.storeId</source>
|
||||
<target>Store Domain</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="jqquqry" name="settings.ips.element14.storeId.help">
|
||||
<unit id="XXGUxF6" name="settings.ips.element14.storeId.help">
|
||||
<segment>
|
||||
<source>settings.ips.element14.storeId.help</source>
|
||||
<target><![CDATA[The store domain to retrieve the data from. This decides the language and currency of results. See <a href="https://partner.element14.com/docs/Product_Search_API_REST__Description">here</a> for a list of valid domains.]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="bH5CYTg" name="settings.ips.tme">
|
||||
<unit id="WKWZIm2" name="settings.ips.tme">
|
||||
<segment>
|
||||
<source>settings.ips.tme</source>
|
||||
<target>TME</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="6UYUDN3" name="settings.ips.tme.token">
|
||||
<unit id="KgK78ks" name="settings.ips.tme.token">
|
||||
<segment>
|
||||
<source>settings.ips.tme.token</source>
|
||||
<target>API Token</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="mypcOlT" name="settings.ips.tme.token.help">
|
||||
<unit id="_pYLrPT" name="settings.ips.tme.token.help">
|
||||
<segment>
|
||||
<source>settings.ips.tme.token.help</source>
|
||||
<target><![CDATA[You can get an API token and secret on <a href="https://developers.tme.eu/en/">https://developers.tme.eu/en/</a>.]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="z0SUBe_" name="settings.ips.tme.secret">
|
||||
<unit id="yswx4bq" name="settings.ips.tme.secret">
|
||||
<segment>
|
||||
<source>settings.ips.tme.secret</source>
|
||||
<target>API Secret</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="PkHcoox" name="settings.ips.tme.currency">
|
||||
<unit id="edYZA5y" name="settings.ips.tme.currency">
|
||||
<segment>
|
||||
<source>settings.ips.tme.currency</source>
|
||||
<target>Currency</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="kNgH0wC" name="settings.ips.tme.language">
|
||||
<unit id="EsVqpUJ" name="settings.ips.tme.language">
|
||||
<segment>
|
||||
<source>settings.ips.tme.language</source>
|
||||
<target>Language</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="lk1nxD4" name="settings.ips.tme.country">
|
||||
<unit id="qFwUGJJ" name="settings.ips.tme.country">
|
||||
<segment>
|
||||
<source>settings.ips.tme.country</source>
|
||||
<target>Country</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="xenQ44N" name="settings.ips.tme.grossPrices">
|
||||
<unit id="Mf2WKob" name="settings.ips.tme.grossPrices">
|
||||
<segment>
|
||||
<source>settings.ips.tme.grossPrices</source>
|
||||
<target>Get gross prices (including tax)</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="9X6OdNl" name="settings.ips.mouser">
|
||||
<unit id="A.x1dyH" name="settings.ips.mouser">
|
||||
<segment>
|
||||
<source>settings.ips.mouser</source>
|
||||
<target>Mouser</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="_Xkz3kO" name="settings.ips.mouser.apiKey">
|
||||
<unit id="5ZxvqyY" name="settings.ips.mouser.apiKey">
|
||||
<segment>
|
||||
<source>settings.ips.mouser.apiKey</source>
|
||||
<target>API key</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="esOuUCF" name="settings.ips.mouser.apiKey.help">
|
||||
<unit id="gu.JlpT" name="settings.ips.mouser.apiKey.help">
|
||||
<segment>
|
||||
<source>settings.ips.mouser.apiKey.help</source>
|
||||
<target><![CDATA[You can register for an API key on <a href="https://eu.mouser.com/api-hub/">https://eu.mouser.com/api-hub/</a>.]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="4sXRBxC" name="settings.ips.mouser.searchLimit">
|
||||
<unit id="Q66CNjw" name="settings.ips.mouser.searchLimit">
|
||||
<segment>
|
||||
<source>settings.ips.mouser.searchLimit</source>
|
||||
<target>Search limit</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="hvMNT_j" name="settings.ips.mouser.searchLimit.help">
|
||||
<unit id="aj5nhIi" name="settings.ips.mouser.searchLimit.help">
|
||||
<segment>
|
||||
<source>settings.ips.mouser.searchLimit.help</source>
|
||||
<target>The maximum amount of results for a single search. Can not be higher than 50.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="UohE1XG" name="settings.ips.mouser.searchOptions">
|
||||
<unit id="q8.Wpbu" name="settings.ips.mouser.searchOptions">
|
||||
<segment>
|
||||
<source>settings.ips.mouser.searchOptions</source>
|
||||
<target>Search filters</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="f3HLNQ8" name="settings.ips.mouser.searchOptions.help">
|
||||
<unit id="7ERXoOf" name="settings.ips.mouser.searchOptions.help">
|
||||
<segment>
|
||||
<source>settings.ips.mouser.searchOptions.help</source>
|
||||
<target>This allows you to only show parts with a certain availability and/or compliance.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Oh3PKLd" name="settings.ips.mouser.searchOptions.none">
|
||||
<unit id="2_fx.rT" name="settings.ips.mouser.searchOptions.none">
|
||||
<segment>
|
||||
<source>settings.ips.mouser.searchOptions.none</source>
|
||||
<target>No filter</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Mn2Oo0x" name="settings.ips.mouser.searchOptions.rohs">
|
||||
<unit id=".PbDhl9" name="settings.ips.mouser.searchOptions.rohs">
|
||||
<segment>
|
||||
<source>settings.ips.mouser.searchOptions.rohs</source>
|
||||
<target>Only RoHS compliant parts</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="JeB.wTt" name="settings.ips.mouser.searchOptions.inStock">
|
||||
<unit id="4SPypVz" name="settings.ips.mouser.searchOptions.inStock">
|
||||
<segment>
|
||||
<source>settings.ips.mouser.searchOptions.inStock</source>
|
||||
<target>Only in stock parts</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="qhL9J3R" name="settings.ips.mouser.searchOptions.rohsAndInStock">
|
||||
<unit id="xU8_Qw." name="settings.ips.mouser.searchOptions.rohsAndInStock">
|
||||
<segment>
|
||||
<source>settings.ips.mouser.searchOptions.rohsAndInStock</source>
|
||||
<target>Only in stock, RoHS compliant parts</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Dxwlvms" name="settings.ips.lcsc">
|
||||
<unit id="fQYt0Om" name="settings.ips.lcsc">
|
||||
<segment>
|
||||
<source>settings.ips.lcsc</source>
|
||||
<target>LCSC</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="CQ92v3n" name="settings.ips.lcsc.help">
|
||||
<unit id="iD6HBym" name="settings.ips.lcsc.help">
|
||||
<segment>
|
||||
<source>settings.ips.lcsc.help</source>
|
||||
<target>Warning: LCSC does not provide an official API. This provider utilizes the webshop API. LCSC did not intend the use of this API, and it could break any time, so use it on your own risk.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="H1E7HkZ" name="settings.ips.lcsc.enabled">
|
||||
<unit id="v7inGbo" name="settings.ips.lcsc.enabled">
|
||||
<segment>
|
||||
<source>settings.ips.lcsc.enabled</source>
|
||||
<target>Enable</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="3iiwues" name="settings.ips.lcsc.currency">
|
||||
<unit id="3KcMouQ" name="settings.ips.lcsc.currency">
|
||||
<segment>
|
||||
<source>settings.ips.lcsc.currency</source>
|
||||
<target>Currency</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="g0AgaAf" name="settings.system.attachments">
|
||||
<unit id="kKv0J3." name="settings.system.attachments">
|
||||
<segment>
|
||||
<source>settings.system.attachments</source>
|
||||
<target><![CDATA[Attachments & Files]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="1wsDvqz" name="settings.system.attachments.maxFileSize">
|
||||
<unit id="dsRff8T" name="settings.system.attachments.maxFileSize">
|
||||
<segment>
|
||||
<source>settings.system.attachments.maxFileSize</source>
|
||||
<target>Maximum file size</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Gn0P1Bv" name="settings.system.attachments.maxFileSize.help">
|
||||
<unit id="uI1XsbJ" name="settings.system.attachments.maxFileSize.help">
|
||||
<segment>
|
||||
<source>settings.system.attachments.maxFileSize.help</source>
|
||||
<target>The maximum size of files that can be uploaded. Please note that this is also limited by PHP configuration.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="DyIfVYH" name="settings.system.attachments.allowDownloads">
|
||||
<unit id="sIt9Ovp" name="settings.system.attachments.allowDownloads">
|
||||
<segment>
|
||||
<source>settings.system.attachments.allowDownloads</source>
|
||||
<target>Allow downloading of external files</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="jD.pgZL" name="settings.system.attachments.allowDownloads.help">
|
||||
<unit id="T.PBu5P" name="settings.system.attachments.allowDownloads.help">
|
||||
<segment>
|
||||
<source>settings.system.attachments.allowDownloads.help</source>
|
||||
<target><![CDATA[With this option users can download external files into Part-DB by providing an URL. <b>Attention: This can be a security issue, as it might allow users to access intranet ressources via Part-DB!</b>]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="HRxjf.u" name="settings.system.attachments.downloadByDefault">
|
||||
<unit id=".OyihML" name="settings.system.attachments.downloadByDefault">
|
||||
<segment>
|
||||
<source>settings.system.attachments.downloadByDefault</source>
|
||||
<target>Download new attachment URLs by default</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="O84puRa" name="settings.system.customization">
|
||||
<unit id="UuDCaUI" name="settings.system.customization">
|
||||
<segment>
|
||||
<source>settings.system.customization</source>
|
||||
<target>Customization</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="poWBszc" name="settings.system.customization.instanceName">
|
||||
<unit id="VYMqQr5" name="settings.system.customization.instanceName">
|
||||
<segment>
|
||||
<source>settings.system.customization.instanceName</source>
|
||||
<target>Instance name</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="4FCCA4p" name="settings.system.customization.instanceName.help">
|
||||
<unit id="0YFxSHZ" name="settings.system.customization.instanceName.help">
|
||||
<segment>
|
||||
<source>settings.system.customization.instanceName.help</source>
|
||||
<target>Name of this Part-DB installation. The value is shown in nav bar and titles.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="oXG7h6X" name="settings.system.customization.banner">
|
||||
<unit id="28n6rA7" name="settings.system.customization.banner">
|
||||
<segment>
|
||||
<source>settings.system.customization.banner</source>
|
||||
<target>Homepage banner</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="6RRRPKg" name="settings.system.history">
|
||||
<unit id="cdwJbbA" name="settings.system.history">
|
||||
<segment>
|
||||
<source>settings.system.history</source>
|
||||
<target>History log</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="hsfPL4R" name="settings.system.history.saveChangedFields">
|
||||
<unit id="6TrsK5U" name="settings.system.history.saveChangedFields">
|
||||
<segment>
|
||||
<source>settings.system.history.saveChangedFields</source>
|
||||
<target>Save which fields of an element were changed in log entries</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="jaT3DJ3" name="settings.system.history.saveOldData">
|
||||
<unit id="IVP9YL8" name="settings.system.history.saveOldData">
|
||||
<segment>
|
||||
<source>settings.system.history.saveOldData</source>
|
||||
<target>Save the old data in log entries on element changes</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="058VALj" name="settings.system.history.saveNewData">
|
||||
<unit id="clqgFOW" name="settings.system.history.saveNewData">
|
||||
<segment>
|
||||
<source>settings.system.history.saveNewData</source>
|
||||
<target>Save the new data in log entries on element change/creation</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="jEvc3t." name="settings.system.history.saveRemovedData">
|
||||
<unit id="MITi2KP" name="settings.system.history.saveRemovedData">
|
||||
<segment>
|
||||
<source>settings.system.history.saveRemovedData</source>
|
||||
<target>Save removed data in log entries on element deletion</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="8665ItM" name="settings.system.customization.theme">
|
||||
<unit id="pinyqu2" name="settings.system.customization.theme">
|
||||
<segment>
|
||||
<source>settings.system.customization.theme</source>
|
||||
<target>Global theme</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="4hNoijr" name="settings.system.history.enforceComments">
|
||||
<unit id="Aky9nXE" name="settings.system.history.enforceComments">
|
||||
<segment>
|
||||
<source>settings.system.history.enforceComments</source>
|
||||
<target>Enforce comments for action types</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="zeiSg.P" name="settings.system.history.enforceComments.description">
|
||||
<unit id="axivgKB" name="settings.system.history.enforceComments.description">
|
||||
<segment>
|
||||
<source>settings.system.history.enforceComments.description</source>
|
||||
<target>With this option, you can specify for which actions, users are enforced to give a reason, which will be logged in history.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="iEq8463" name="settings.system.history.enforceComments.type.part_edit">
|
||||
<unit id="eqQKTzQ" name="settings.system.history.enforceComments.type.part_edit">
|
||||
<segment>
|
||||
<source>settings.system.history.enforceComments.type.part_edit</source>
|
||||
<target>Part edit</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ns_O1ZC" name="settings.system.history.enforceComments.type.part_create">
|
||||
<unit id="Ip_kAO3" name="settings.system.history.enforceComments.type.part_create">
|
||||
<segment>
|
||||
<source>settings.system.history.enforceComments.type.part_create</source>
|
||||
<target>Part creation</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="bkYgIFK" name="settings.system.history.enforceComments.type.part_delete">
|
||||
<unit id="qEa.03L" name="settings.system.history.enforceComments.type.part_delete">
|
||||
<segment>
|
||||
<source>settings.system.history.enforceComments.type.part_delete</source>
|
||||
<target>Part deletion</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="SKOeTBp" name="settings.system.history.enforceComments.type.part_stock_operation">
|
||||
<unit id="zjITvo2" name="settings.system.history.enforceComments.type.part_stock_operation">
|
||||
<segment>
|
||||
<source>settings.system.history.enforceComments.type.part_stock_operation</source>
|
||||
<target>Part stock operation</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="SvD2GFR" name="settings.system.history.enforceComments.type.datastructure_edit">
|
||||
<unit id="hPbibkF" name="settings.system.history.enforceComments.type.datastructure_edit">
|
||||
<segment>
|
||||
<source>settings.system.history.enforceComments.type.datastructure_edit</source>
|
||||
<target>Data structure edit</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="YGcoYaK" name="settings.system.history.enforceComments.type.datastructure_create">
|
||||
<unit id="7mB_fP3" name="settings.system.history.enforceComments.type.datastructure_create">
|
||||
<segment>
|
||||
<source>settings.system.history.enforceComments.type.datastructure_create</source>
|
||||
<target>Data structure creation</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Xt6S9iR" name="settings.system.history.enforceComments.type.datastructure_delete">
|
||||
<unit id="nt8eToz" name="settings.system.history.enforceComments.type.datastructure_delete">
|
||||
<segment>
|
||||
<source>settings.system.history.enforceComments.type.datastructure_delete</source>
|
||||
<target>Data structure deletion</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Zq5CzmY" name="settings.system.privacy.useGravatar">
|
||||
<unit id="zQ8vq5N" name="settings.system.privacy.useGravatar">
|
||||
<segment>
|
||||
<source>settings.system.privacy.useGravatar</source>
|
||||
<target>Use Gravatar avatars</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="sEoU2wK" name="settings.system.privacy.useGravatar.description">
|
||||
<unit id="8IszKgp" name="settings.system.privacy.useGravatar.description">
|
||||
<segment>
|
||||
<source>settings.system.privacy.useGravatar.description</source>
|
||||
<target>If a user does not have an avatar image specified, use the avatar from Gravatar based on the user email. This causes the browser to load pictures from a third-party!</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="BDvK0bP" name="settings.system.privacy.checkForUpdates">
|
||||
<unit id="rxHBzbv" name="settings.system.privacy.checkForUpdates">
|
||||
<segment>
|
||||
<source>settings.system.privacy.checkForUpdates</source>
|
||||
<target>Check for Part-DB updates</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="lAbjHIw" name="settings.system.privacy.checkForUpdates.description">
|
||||
<unit id="LrAcb0O" name="settings.system.privacy.checkForUpdates.description">
|
||||
<segment>
|
||||
<source>settings.system.privacy.checkForUpdates.description</source>
|
||||
<target>Part-DB regularly checks if a new version is available on GitHub. Disable this here, if you do not want this or if your server can not connect to the internet.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="_wYDoEy" name="settings.system.localization.locale">
|
||||
<unit id="nMhHcYc" name="settings.system.localization.locale">
|
||||
<segment>
|
||||
<source>settings.system.localization.locale</source>
|
||||
<target>Default language / locale</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="K8mVEEQ" name="settings.system.localization">
|
||||
<unit id="vWBNX1b" name="settings.system.localization">
|
||||
<segment>
|
||||
<source>settings.system.localization</source>
|
||||
<target>Localization</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="fLOdzsf" name="settings.system.localization.timezone">
|
||||
<unit id="7_M.HcK" name="settings.system.localization.timezone">
|
||||
<segment>
|
||||
<source>settings.system.localization.timezone</source>
|
||||
<target>Default timezone</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="gdx8h1U" name="settings.system.localization.base_currency">
|
||||
<unit id="CCMOzX7" name="settings.system.localization.base_currency">
|
||||
<segment>
|
||||
<source>settings.system.localization.base_currency</source>
|
||||
<target>Base currency</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="DhNnWlg" name="settings.system.localization.base_currency_description">
|
||||
<unit id="0GRlEe5" name="settings.system.localization.base_currency_description">
|
||||
<segment>
|
||||
<source>settings.system.localization.base_currency_description</source>
|
||||
<target><![CDATA[The currency that is used to store price information and exchange rates in. This currency is assumed, when no currency is set for a price information.
|
||||
<b>Please note that the currencies are not converted, when changing this value. So changing the default currency after you already added price information, will result in wrong prices!</b>]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="7BwmKFC" name="settings.system.privacy">
|
||||
<unit id="cvpTUeY" name="settings.system.privacy">
|
||||
<segment>
|
||||
<source>settings.system.privacy</source>
|
||||
<target>Privacy</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="W.225Bj" name="settings.title">
|
||||
<unit id="TVAVZUl" name="settings.title">
|
||||
<segment>
|
||||
<source>settings.title</source>
|
||||
<target>Server settings</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="5WsYY.a" name="settings.misc.kicad_eda">
|
||||
<unit id="xtw_ol7" name="settings.misc.kicad_eda">
|
||||
<segment>
|
||||
<source>settings.misc.kicad_eda</source>
|
||||
<target>KiCAD integration</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="U83kTE5" name="settings.misc.kicad_eda.category_depth">
|
||||
<unit id="8u9_KDD" name="settings.misc.kicad_eda.category_depth">
|
||||
<segment>
|
||||
<source>settings.misc.kicad_eda.category_depth</source>
|
||||
<target>Category depth</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="GudCzRb" name="settings.misc.kicad_eda.category_depth.help">
|
||||
<unit id="w07P3Dt" name="settings.misc.kicad_eda.category_depth.help">
|
||||
<segment>
|
||||
<source>settings.misc.kicad_eda.category_depth.help</source>
|
||||
<target><![CDATA[This value determines the depth of the category tree, that is visible inside KiCad. 0 means that only the top level categories are visible. Set to a value > 0 to show more levels. Set to -1, to show all parts of Part-DB inside a sigle cnategory in KiCad.]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dEEqctR" name="settings.behavior.sidebar">
|
||||
<unit id="VwvmcWE" name="settings.behavior.sidebar">
|
||||
<segment>
|
||||
<source>settings.behavior.sidebar</source>
|
||||
<target>Sidebar</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="UIyQNrT" name="settings.behavior.sidebar.items">
|
||||
<unit id="FIneGzR" name="settings.behavior.sidebar.items">
|
||||
<segment>
|
||||
<source>settings.behavior.sidebar.items</source>
|
||||
<target>Sidebar items</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="EGUFIOg" name="settings.behavior.sidebar.items.help">
|
||||
<unit id="jc0JTvL" name="settings.behavior.sidebar.items.help">
|
||||
<segment>
|
||||
<source>settings.behavior.sidebar.items.help</source>
|
||||
<target><![CDATA[The menus which appear at the sidebar by default. Order of items can be changed via drag & drop.]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="uH3qE5u" name="settings.behavior.sidebar.rootNodeEnabled">
|
||||
<unit id="gVSWDkE" name="settings.behavior.sidebar.rootNodeEnabled">
|
||||
<segment>
|
||||
<source>settings.behavior.sidebar.rootNodeEnabled</source>
|
||||
<target>Use root node</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsOoG62" name="settings.behavior.sidebar.rootNodeEnabled.help">
|
||||
<unit id="uk0yKdg" name="settings.behavior.sidebar.rootNodeEnabled.help">
|
||||
<segment>
|
||||
<source>settings.behavior.sidebar.rootNodeEnabled.help</source>
|
||||
<target>If this is enabled, all top-level categories, footprints, etc. will be put under a single root node. If disabled, the top-level categories will be put directly into the menu.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="VF.wf7O" name="settings.behavior.sidebar.rootNodeExpanded">
|
||||
<unit id="brCNh0M" name="settings.behavior.sidebar.rootNodeExpanded">
|
||||
<segment>
|
||||
<source>settings.behavior.sidebar.rootNodeExpanded</source>
|
||||
<target>Expand root node by default</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="5BAiTbM" name="settings.behavior.table">
|
||||
<unit id="NkW8ELV" name="settings.behavior.table">
|
||||
<segment>
|
||||
<source>settings.behavior.table</source>
|
||||
<target>Tables</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a6D6BgV" name="settings.behavior.table.default_page_size">
|
||||
<unit id="1Zrv2eZ" name="settings.behavior.table.default_page_size">
|
||||
<segment>
|
||||
<source>settings.behavior.table.default_page_size</source>
|
||||
<target>Default page size</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="glHJBvM" name="settings.behavior.table.default_page_size.help">
|
||||
<unit id="lbx.zdp" name="settings.behavior.table.default_page_size.help">
|
||||
<segment>
|
||||
<source>settings.behavior.table.default_page_size.help</source>
|
||||
<target>The default page size on full page tables. Set to -1 to show all items by default without pagination.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="N0VA7gG" name="settings.behavior.table.parts_default_columns">
|
||||
<unit id="G1N8QW3" name="settings.behavior.table.parts_default_columns">
|
||||
<segment>
|
||||
<source>settings.behavior.table.parts_default_columns</source>
|
||||
<target>Default columns for part tables</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="AkXwf2W" name="settings.behavior.table.parts_default_columns.help">
|
||||
<unit id="SUD8H3b" name="settings.behavior.table.parts_default_columns.help">
|
||||
<segment>
|
||||
<source>settings.behavior.table.parts_default_columns.help</source>
|
||||
<target><![CDATA[The columns to show by default in part tables. Order of items can be changed via drag & drop.]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="hazr_g5" name="settings.ips.oemsecrets">
|
||||
<segment>
|
||||
<source>settings.ips.oemsecrets</source>
|
||||
<target>OEMSecrets</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ljRPsNX" name="settings.ips.oemsecrets.keepZeroPrices">
|
||||
<segment>
|
||||
<source>settings.ips.oemsecrets.keepZeroPrices</source>
|
||||
<target>Keep distributors with zero prices</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="c7YTKEY" name="settings.ips.oemsecrets.keepZeroPrices.help">
|
||||
<segment>
|
||||
<source>settings.ips.oemsecrets.keepZeroPrices.help</source>
|
||||
<target>If this is not set, distributors where the prices are 0 will be discarded as invalid</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ym9EcxF" name="settings.ips.oemsecrets.parseParams">
|
||||
<segment>
|
||||
<source>settings.ips.oemsecrets.parseParams</source>
|
||||
<target>Extract parameters from description</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="U4aFfJ3" name="settings.ips.oemsecrets.parseParams.help">
|
||||
<segment>
|
||||
<source>settings.ips.oemsecrets.parseParams.help</source>
|
||||
<target>If enabled, the provider tries to convert the unstructured descriptions of OEMSecrets into structured parameters. Each parameter in the description should have the form "...;name1:value1;name2:value2"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="YMpgQPU" name="settings.ips.oemsecrets.sortMode">
|
||||
<segment>
|
||||
<source>settings.ips.oemsecrets.sortMode</source>
|
||||
<target>Result sort mode</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="3VDLyjD" name="settings.ips.oemsecrets.sortMode.N">
|
||||
<segment>
|
||||
<source>settings.ips.oemsecrets.sortMode.N</source>
|
||||
<target>None</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Oz.6cJY" name="settings.ips.oemsecrets.sortMode.C">
|
||||
<segment>
|
||||
<source>settings.ips.oemsecrets.sortMode.C</source>
|
||||
<target>Completeness (prioritize items with detailed information)</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="KLJYfJ0" name="settings.ips.oemsecrets.sortMode.M">
|
||||
<segment>
|
||||
<source>settings.ips.oemsecrets.sortMode.M</source>
|
||||
<target><![CDATA[Completeness & Manufacturer name]]></target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue