Compare commits

...

20 Commits

Author SHA1 Message Date
Imran
a56069e881 Merge pull request #2537 from ImranR98/dev
Fix versionCode issue (#2505) + Flutter upgrades
2025-09-12 15:16:01 -04:00
Imran Remtulla
a34e45363b Fix versionCode issue (#2505) + Flutter upgrades 2025-09-12 15:13:20 -04:00
Imran
e1a89f5f67 Merge pull request #2531 from ar-lex/feature/3rd-party-fdroid-per-app-author
Add per-application author parsing for third-party F-Droid repos (#2527)
2025-09-12 14:44:10 -04:00
Imran
f7f6e0cde7 Merge pull request #2532 from ar-lex/feature/3rd-party-fdroid-changelog
Support changelog field for third-party F-Droid repos (#2528)
2025-09-12 14:44:04 -04:00
Alexey Arutyunov
5a58522bf6 Support changelog field for third-party F-Droid repos (#2528) 2025-09-12 20:39:23 +02:00
Alexey Arutyunov
9347af2090 Add per-application author parsing for third-party F-Droid repos (#2527) 2025-09-12 20:33:49 +02:00
Imran
b294e57367 Merge pull request #2530 from ar-lex/feature/3rd-party-fdroid-suggested-version
Implement suggested version code for third-party F-Droid repos (#2524)
2025-09-12 14:23:30 -04:00
Imran
4234e16432 Merge pull request #2533 from solokot/main
Translation: update ru.json
2025-09-12 14:21:10 -04:00
Imran
a64f2e1af7 Merge pull request #2522 from bluefly000/japanese-translation
Update ja.json
2025-09-12 14:20:50 -04:00
solokot
926462407c Translation: update ru.json
Fix machine translation
2025-09-12 09:57:50 +03:00
Alexey Arutyunov
1b499700fd Implement suggested version code for third-party F-Droid repos (#2524)
Enable it by default for both official and third-party F-Droid sources.

Reuse trySelectingSuggestedVersionCode label from official F-Droid repository source.
2025-09-11 23:34:28 +02:00
bluefly000
930a4b411e Update ja.json 2025-09-06 18:54:11 +09:00
Imran
b9931e00e7 Merge pull request #2508 from summoner001/main
Translation: Update hu.json
2025-08-31 21:38:05 -04:00
summoner
2337e04ee1 Translation: Update hu.json
Translate new string.
Fix sentence.
2025-08-31 12:40:02 +02:00
Imran
2fc8dafc9e Merge pull request #2503 from ImranR98/dev
- Added LiteAPKs as a source (#1799)
- Remove unnecessary permission (#2467)
2025-08-31 00:49:01 -04:00
Imran Remtulla
0603c6a1d3 Translation updates 2025-08-31 00:47:15 -04:00
Imran Remtulla
555284d2cb Update Flutter + packages, increment version 2025-08-31 00:08:08 -04:00
Imran
357e2b8a89 Merge pull request #2497 from UlyssesZh/match-links-outside-a-tags
feat: add option to match links outside <a> tags even if links in <a> tags are found
2025-08-31 00:00:20 -04:00
Imran Remtulla
5b147b82e0 Added LiteAPKs as a source (#1799) 2025-08-30 23:59:21 -04:00
Ulysses Zhan
87ef762eec feat: add option to match links outside <a> tags even if links in <a> tags are found 2025-08-27 00:59:48 -07:00
38 changed files with 241 additions and 86 deletions

View File

@@ -1,6 +1,7 @@
import java.io.FileInputStream
import java.util.Properties
import com.android.build.api.variant.FilterConfiguration.FilterType.*
import com.android.build.gradle.internal.api.ApkVariantOutputImpl
plugins {
id("com.android.application")
@@ -86,18 +87,17 @@ android {
val abiCodes = mapOf("x86_64" to 1, "armeabi-v7a" to 2, "arm64-v8a" to 3)
androidComponents {
onVariants { variant ->
variant.outputs.forEach { output ->
val name = output.filters.find { it.filterType == ABI }?.identifier
val baseAbiCode = abiCodes[name] ?: 0
if (baseAbiCode != null) {
output.versionCode.set(baseAbiCode + ((output.versionCode.get() ?: 0) * 10))
}
android.applicationVariants.configureEach {
val variant = this
variant.outputs.forEach { output ->
val abiVersionCode = abiCodes[output.filters.find { it.filterType == "ABI" }?.identifier]
if (abiVersionCode != null) {
(output as ApkVariantOutputImpl).versionCodeOverride = variant.versionCode * 10 + abiVersionCode
}
}
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")
}

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "التحقق من علامة 'الأحدث'",
"intermediateLinkRegex": "تصفية للوصول إلى رابط 'وسيط'",
"filterByLinkText": "تصفية الروابط حسب نص الرابط",
"matchLinksOutsideATags": "تطابق الروابط خارج علامات <a>",
"intermediateLinkNotFound": "لم يتم العثور على رابط وسيط",
"intermediateLink": "رابط وسيط",
"exemptFromBackgroundUpdates": "إعفاء من التحديثات في الخلفية (إذا تم تمكينها)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Provjerite 'posljednu' ('latest') oznaku",
"intermediateLinkRegex": "Filter za 'srednju' vezu za posjetu",
"filterByLinkText": "Filtriraj linkove prema tekstu linka",
"matchLinksOutsideATags": "Match links outside <a> tags",
"intermediateLinkNotFound": "Intermediate veza nije nađena",
"intermediateLink": "Intermediate veza",
"exemptFromBackgroundUpdates": "Izuzmi iz ažuriranja u pozadini (ako su uključeni)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Comprova l'etiqueta 'Latest' (última versió)",
"intermediateLinkRegex": "Filtra per un enllaç 'intermediari' per anar-hi",
"filterByLinkText": "Filtra els enllaços pel text de l'enllaç",
"matchLinksOutsideATags": "Match links outside <a> tags",
"intermediateLinkNotFound": "No s'ha trobat l'enllaç intermediari",
"intermediateLink": "Enllaç intermediari",
"exemptFromBackgroundUpdates": "Exempta d'actualitzacions en segon pla (si han estat habilitades)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Ověřit značku „latest“",
"intermediateLinkRegex": "Filtr pro návštěvu „prostředního“ odkazu",
"filterByLinkText": "Filtrovat odkazy podle textu odkazu",
"matchLinksOutsideATags": "Shoda odkazů mimo značky <a>",
"intermediateLinkNotFound": "Připojený odkaz nenalezen",
"intermediateLink": "Připojený odkaz",
"exemptFromBackgroundUpdates": "Vyloučit z aktualizací na pozadí (je-li povoleno)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Verificer 'seneste'-tagget",
"intermediateLinkRegex": "Filtrer efter et 'mellemliggende' link at besøge",
"filterByLinkText": "Filtrer links efter linktekst",
"matchLinksOutsideATags": "Match links uden for <a>-tags",
"intermediateLinkNotFound": "Mellemliggende link ikke fundet",
"intermediateLink": "Mellemliggende link",
"exemptFromBackgroundUpdates": "Undtag fra baggrundsopdateringer (hvis aktiveret)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "„Latest“-Tag überprüfen",
"intermediateLinkRegex": "Filter für einen „Zwischen“-Link, der zuerst besucht werden soll",
"filterByLinkText": "Links durch Linktext filtern",
"matchLinksOutsideATags": "Links außerhalb von <a>-Tags anpassen",
"intermediateLinkNotFound": "„Zwischen“-Link nicht gefunden",
"intermediateLink": "„Zwischen“-Link",
"exemptFromBackgroundUpdates": "Von Hintergrundaktualisierungen (falls aktiviert) ausschließen",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Inspekti la etikedon 'latest'",
"intermediateLinkRegex": "Filtri por 'pera' vizitota ligilo",
"filterByLinkText": "Filtri ligilojn laŭ ligiloteksto",
"matchLinksOutsideATags": "Match links outside <a> tags",
"intermediateLinkNotFound": "Netrovebla pera ligilo",
"intermediateLink": "Pera ligilo",
"exemptFromBackgroundUpdates": "Escepti el la fonaj ĝisdatigoj (se aktiva)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Verify the 'latest' tag",
"intermediateLinkRegex": "Filter for an 'intermediate' link to visit",
"filterByLinkText": "Filter links by link text",
"matchLinksOutsideATags": "Match links outside <a> tags",
"intermediateLinkNotFound": "Intermediate link not found",
"intermediateLink": "Intermediate link",
"exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Comprobar etiqueta 'Latest'",
"intermediateLinkRegex": "Filtrar por enlace 'intermedio' para visitar primero",
"filterByLinkText": "Filtrar enlaces por texto del enlace",
"matchLinksOutsideATags": "Enlaces coincidentes fuera de las etiquetas <a>",
"intermediateLinkNotFound": "Enlace intermedio no encontrado",
"intermediateLink": "Enlace intermedio",
"exemptFromBackgroundUpdates": "No actualizar en segundo plano (si está habilitado)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "برچسب \"آخرین\" را تأیید کنید",
"intermediateLinkRegex": "برای بازدید از پیوند «میانگین» فیلتر کنید",
"filterByLinkText": "لینک ها را بر اساس متن پیوند فیلتر کنید",
"matchLinksOutsideATags": "Match links outside <a> tags",
"intermediateLinkNotFound": "لینک میانی پیدا نشد",
"intermediateLink": "پیوند میانی",
"exemptFromBackgroundUpdates": "معاف از به‌روزرسانی‌های پس‌زمینه (در صورت فعال بودن)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Vérifier la balise 'latest'",
"intermediateLinkRegex": "Filtrer un lien 'intermédiaire' à visiter",
"filterByLinkText": "Filtrer les liens par texte du lien",
"matchLinksOutsideATags": "Liens en dehors des balises <a>",
"intermediateLinkNotFound": "Lien intermédiaire introuvable",
"intermediateLink": "Lien intermédiaire",
"exemptFromBackgroundUpdates": "Exclure des mises à jour en arrière-plan (si activées)",

View File

@@ -254,7 +254,8 @@
"verifyLatestTag": "Ellenőrizze a „legújabb” címkét",
"intermediateLinkRegex": "Szűrő egy „köztes” hivatkozás felkereséséhez",
"filterByLinkText": "Hivatkozások szűrése hivatkozásszöveg alapján",
"intermediateLinkNotFound": "Köztes hivatkozás nem található",
"matchLinksOutsideATags": "Hivatkozások keresése az <a> címkéken kívül is",
"intermediateLinkNotFound": "Nem található köztes hivatkozás",
"intermediateLink": "Köztes hivatkozás",
"exemptFromBackgroundUpdates": "Mentes a háttérben történő frissítések alól (ha engedélyezett)",
"bgUpdatesOnWiFiOnly": "Háttérfrissítések letiltása, amikor az eszköz nem csatlakozik a Wi-Fi-hez",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Verifikasi label 'terbaru'",
"intermediateLinkRegex": "Filter tautan 'perantara' untuk dikunjungi",
"filterByLinkText": "Filter tautan berdasarkan teks tautan",
"matchLinksOutsideATags": "Mencocokkan tautan di luar tag <a>",
"intermediateLinkNotFound": "Tautan perantara tidak ditemukan",
"intermediateLink": "Tautan perantara",
"exemptFromBackgroundUpdates": "Dikecualikan dari pembaruan latar belakang (jika diaktifkan)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Verifica l'etichetta 'Latest'",
"intermediateLinkRegex": "Filtro per un collegamento 'intermedio' da visitare",
"filterByLinkText": "Filtra i collegamenti in base al testo del collegamento",
"matchLinksOutsideATags": "Corrispondenza dei collegamenti al di fuori dei tag <a>",
"intermediateLinkNotFound": "Link intermedio non trovato",
"intermediateLink": "Collegamento intermedio",
"exemptFromBackgroundUpdates": "Esente da aggiornamenti in secondo piano (se attivo)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "'latest'タグを確認する",
"intermediateLinkRegex": "訪問する「中間」リンクのフィルター",
"filterByLinkText": "テキストでリンクをフィルタリングする",
"matchLinksOutsideATags": "<a>タグの外にあるリンクに一致させる",
"intermediateLinkNotFound": "中間リンクが見つかりませんでした",
"intermediateLink": "中間リンク",
"exemptFromBackgroundUpdates": "バックグラウンドアップデートを行わない (有効な場合)",
@@ -334,7 +335,7 @@
"foregroundService": "Obtainium フォアグラウンドサービス",
"foregroundServiceExplanation": "アップデート確認にフォアグラウンドサービスを使用する(より信頼性が高いが、より電力を消費する)",
"fgServiceNotice": "この通知は、バックグラウンドでアップデートを確認するために必要ですOSの設定で非表示にできます。",
"excludeSecrets": "秘密を除く",
"excludeSecrets": "シークレットを除く",
"removeAppQuestion": {
"one": "アプリを削除しますか?",
"other": "アプリを削除しますか?"

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "'최신' 태그 확인",
"intermediateLinkRegex": "'중간' 링크 방문 필터",
"filterByLinkText": "링크 텍스트로 링크 필터링",
"matchLinksOutsideATags": "<> 태그 외부의 링크 일치",
"intermediateLinkNotFound": "중간 링크를 찾을 수 없습니다",
"intermediateLink": "중간 링크",
"exemptFromBackgroundUpdates": "백그라운드 업데이트에서 제외 (활성화된 경우)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "'ഏറ്റവും പുതിയ' ടാഗ് പരിശോധിക്കുക",
"intermediateLinkRegex": "സന്ദർശിക്കാൻ ഒരു 'ഇന്റർമീഡിയറ്റ്' ലിങ്കിനായി ഫിൽട്ടർ ചെയ്യുക",
"filterByLinkText": "ലിങ്ക് ടെക്സ്റ്റ് ഉപയോഗിച്ച് ലിങ്കുകൾ ഫിൽട്ടർ ചെയ്യുക",
"matchLinksOutsideATags": "Match links outside <a> tags",
"intermediateLinkNotFound": "ഇന്റർമീഡിയറ്റ് ലിങ്ക് കണ്ടെത്തിയില്ല",
"intermediateLink": "ഇന്റർമീഡിയറ്റ് ലിങ്ക്",
"exemptFromBackgroundUpdates": "ബാക്ക്ഗ്രൗണ്ട് അപ്‌ഡേറ്റുകളിൽ നിന്ന് ഒഴിവാക്കുക (പ്രവർത്തനക്ഷമമാക്കിയിട്ടുണ്ടെങ്കിൽ)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Het label 'Laatste' verifiëren",
"intermediateLinkRegex": "Filteren op een 'Intermediaire' link om te bezoeken",
"filterByLinkText": "Links filteren op linktekst",
"matchLinksOutsideATags": "Koppelingen buiten <a>-tags matchen",
"intermediateLinkNotFound": "Intermediaire link niet gevonden",
"intermediateLink": "Intermediaire link",
"exemptFromBackgroundUpdates": "Vrijgesteld van achtergrond-updates (indien ingeschakeld)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Zweryfikuj najnowszy tag",
"intermediateLinkRegex": "Filtr linków \"pośrednich\" do odwiedzenia w pierwszej kolejności",
"filterByLinkText": "Filtruj linki według tekstu linku",
"matchLinksOutsideATags": "Dopasowywanie linków poza znacznikami <a>",
"intermediateLinkNotFound": "Nie znaleziono linku pośredniego",
"intermediateLink": "Link pośredni",
"exemptFromBackgroundUpdates": "Wyklucz z uaktualnień w tle (jeśli są włączone)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Verificar a tag 'mais recente'",
"intermediateLinkRegex": "Filtrar por um link 'intermediário' para visitar",
"filterByLinkText": "Filtrar links por texto do link",
"matchLinksOutsideATags": "Corresponder links fora das tags <a>",
"intermediateLinkNotFound": "Link intermediário não encontrado",
"intermediateLink": "Link intermediário",
"exemptFromBackgroundUpdates": "Isento de atualizações em segundo plano (caso ativadas)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Verifique a 'última' etiqueta",
"intermediateLinkRegex": "Filtrar um link 'intermediário' para visitar",
"filterByLinkText": "Filtrar links pelo texto do link",
"matchLinksOutsideATags": "Corresponder ligações fora das etiquetas <a>",
"intermediateLinkNotFound": "Link intermediário não encontrado",
"intermediateLink": "Link intermediário",
"exemptFromBackgroundUpdates": "Isento de atualizações em segundo-plano (se ativadas)",

View File

@@ -253,7 +253,8 @@
"backgroundUpdateLimitsExplanation": "Успешность фоновой установки можно определить только после открытия Obtainium",
"verifyLatestTag": "Проверять метку «latest»",
"intermediateLinkRegex": "Фильтр для «промежуточной» ссылки для посещения",
"filterByLinkText": "Фильтрация ссылок по тексту ссылки",
"filterByLinkText": "Фильтровать ссылки по тексту ссылки",
"matchLinksOutsideATags": "Сопоставлять ссылки вне тегов <a>",
"intermediateLinkNotFound": "Промежуточная ссылка не найдена",
"intermediateLink": "Промежуточная ссылка",
"exemptFromBackgroundUpdates": "Исключить из фоновых обновлений (если включено)",

View File

@@ -21,6 +21,7 @@ const neverAutoTranslate = {
obtainiumImport: ['nl'],
appLogs: ['nl'],
apks: ['vi'],
minute: ['fr'],
tencentAppStore: ['*']
}

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Verifiera 'senaste'-taggen",
"intermediateLinkRegex": "Filtrera för en \"mellanliggande\" länk att besöka",
"filterByLinkText": "Filtrera länkar efter länktext",
"matchLinksOutsideATags": "Matcha länkar utanför <a>-taggar",
"intermediateLinkNotFound": "Mellanlänk hittades inte",
"intermediateLink": "Mellanlänk",
"exemptFromBackgroundUpdates": "Undta från bakgrundsuppdateringar (om aktiverad)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "'latest' etiketini doğrula",
"intermediateLinkRegex": "Ziyaret Edilecek 'Orta Düzey' Bağlantıyı Filtrele",
"filterByLinkText": "Bağlantıları bağlantı metnine göre filtrele",
"matchLinksOutsideATags": "<a> etiketleri dışındaki bağlantıları eşleştirin",
"intermediateLinkNotFound": "Ara bağlantı bulunamadı",
"intermediateLink": "Ara bağlantı",
"exemptFromBackgroundUpdates": "Arka plan güncellemelerinden muaf tut (etkinse)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Перевірити тег 'latest'",
"intermediateLinkRegex": "Фільтр для 'Проміжного' Посилання для Відвідування",
"filterByLinkText": "Фільтрувати посилання за текстом посилання",
"matchLinksOutsideATags": "Зіставлення посилань поза тегами <a>",
"intermediateLinkNotFound": "Проміжне посилання не знайдено",
"intermediateLink": "Проміжне посилання",
"exemptFromBackgroundUpdates": "Виключено з фонових оновлень (якщо ввімкнено)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "Xác minh thẻ 'mới nhất'",
"intermediateLinkRegex": "Lọc tìm liên kết 'Trung cấp' để truy cập",
"filterByLinkText": "Lọc liên kết theo văn bản liên kết",
"matchLinksOutsideATags": "Khớp các liên kết bên ngoài thẻ <a>",
"intermediateLinkNotFound": "Không tìm thấy liên kết trung gian",
"intermediateLink": "Liên kết trung gian",
"exemptFromBackgroundUpdates": "Miễn cập nhật nền (nếu được bật)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "驗證「最新」標籤",
"intermediateLinkRegex": "過濾要存取的「中間」連結",
"filterByLinkText": "按連結文字過濾連結",
"matchLinksOutsideATags": "匹配 <a> 標籤外的連結",
"intermediateLinkNotFound": "沒有找到中間連結",
"intermediateLink": "中間連結",
"exemptFromBackgroundUpdates": "免除背景更新(若已啟用)",

View File

@@ -254,6 +254,7 @@
"verifyLatestTag": "验证“Latest”标签",
"intermediateLinkRegex": "筛选中转链接的正则表达式",
"filterByLinkText": "根据链接文本进行筛选",
"matchLinksOutsideATags": "匹配 <a> 标签外的链接",
"intermediateLinkNotFound": "未找到中转链接",
"intermediateLink": "中转链接",
"exemptFromBackgroundUpdates": "禁用后台更新(仅此应用生效,即使已启用全局后台更新)",

View File

@@ -32,6 +32,7 @@ class FDroid extends AppSource {
GeneratedFormSwitch(
'trySelectingSuggestedVersionCode',
label: tr('trySelectingSuggestedVersionCode'),
defaultValue: true,
),
],
[

View File

@@ -29,6 +29,13 @@ class FDroidRepo extends AppSource {
defaultValue: false,
),
],
[
GeneratedFormSwitch(
'trySelectingSuggestedVersionCode',
label: tr('trySelectingSuggestedVersionCode'),
defaultValue: true,
),
],
];
}
@@ -170,6 +177,7 @@ class FDroidRepo extends AppSource {
}
standardUrl = removeQueryParamsFromUrl(standardUrl);
bool pickHighestVersionCode = additionalSettings['pickHighestVersionCode'];
bool trySelectingSuggestedVersionCode = additionalSettings['trySelectingSuggestedVersionCode'];
if (appIdOrName == null) {
throw NoReleasesError();
}
@@ -207,38 +215,58 @@ class FDroidRepo extends AppSource {
foundApps[0].querySelector('name')?.innerHtml ?? appId;
var appName = foundApps[0].querySelector('name')?.innerHtml ?? appId;
var releases = foundApps[0].querySelectorAll('package');
if (releases.isEmpty) {
throw NoReleasesError();
}
String? changeLog = foundApps[0].querySelector('changelog')?.innerHtml;
String? latestVersion = releases[0].querySelector('version')?.innerHtml;
String? added = releases[0].querySelector('added')?.innerHtml;
DateTime? releaseDate = added != null ? DateTime.parse(added) : null;
if (latestVersion == null) {
throw NoVersionError();
}
var latestVersionReleases = releases
.where(
(element) =>
element.querySelector('version')?.innerHtml == latestVersion &&
element.querySelector('apkname') != null,
)
.toList();
if (latestVersionReleases.length > 1 && pickHighestVersionCode) {
latestVersionReleases.sort((e1, e2) {
return int.parse(
e2.querySelector('versioncode')!.innerHtml,
).compareTo(int.parse(e1.querySelector('versioncode')!.innerHtml));
});
latestVersionReleases = [latestVersionReleases[0]];
String? marketvercodeStr = foundApps[0].querySelector('marketvercode')?.innerHtml;
int? marketvercode = int.tryParse(marketvercodeStr ?? '');
List selectedReleases = [];
if (trySelectingSuggestedVersionCode && marketvercode != null) {
selectedReleases = releases.where((e) =>
int.tryParse(e.querySelector('versioncode')?.innerHtml ?? '') == marketvercode &&
e.querySelector('apkname') != null
).toList();
}
List<String> apkUrls = latestVersionReleases
String? appAuthorName = foundApps[0].querySelector('author')?.innerHtml;
if (appAuthorName != null) {
authorName = appAuthorName;
}
if (selectedReleases.isEmpty) {
selectedReleases = releases.where((e) =>
e.querySelector('version')?.innerHtml == latestVersion &&
e.querySelector('apkname') != null
).toList();
if (selectedReleases.length > 1 && pickHighestVersionCode) {
selectedReleases.sort((e1, e2) {
return int.parse(e2.querySelector('versioncode')!.innerHtml)
.compareTo(int.parse(e1.querySelector('versioncode')!.innerHtml));
});
selectedReleases = [selectedReleases[0]];
}
}
String? selectedVersion = selectedReleases[0].querySelector('version')?.innerHtml;
if (selectedVersion == null) {
throw NoVersionError();
}
String? added = selectedReleases[0].querySelector('added')?.innerHtml;
DateTime? releaseDate = added != null ? DateTime.parse(added) : null;
List<String> apkUrls = selectedReleases
.map(
(e) =>
'${res.request!.url.toString().split('/').reversed.toList().sublist(1).reversed.join('/')}/${e.querySelector('apkname')!.innerHtml}',
)
.toList();
return APKDetails(
latestVersion,
selectedVersion,
getApkUrlsFromUrls(apkUrls),
AppNames(authorName, appName),
releaseDate: releaseDate,
changeLog: changeLog,
);
} else {
throw getObtainiumHttpError(res);

View File

@@ -129,6 +129,8 @@ Future<List<MapEntry<String, String>>> grabLinksCommon(
Uri reqUrl,
Map<String, dynamic> additionalSettings,
) async {
bool matchLinksOutsideATags =
additionalSettings['matchLinksOutsideATags'] == true;
var html = parse(rawBody);
List<MapEntry<String, String>> allLinks = html
.querySelectorAll('a')
@@ -143,7 +145,7 @@ Future<List<MapEntry<String, String>>> grabLinksCommon(
.where((element) => element.key.isNotEmpty)
.map((e) => MapEntry(ensureAbsoluteUrl(e.key, reqUrl), e.value))
.toList();
if (allLinks.isEmpty) {
if (allLinks.isEmpty || matchLinksOutsideATags) {
allLinks = getLinksInLines(rawBody);
}
if (allLinks.isEmpty) {
@@ -247,6 +249,12 @@ class HTML extends AppSource {
];
var commonFormItems = [
[GeneratedFormSwitch('filterByLinkText', label: tr('filterByLinkText'))],
[
GeneratedFormSwitch(
'matchLinksOutsideATags',
label: tr('matchLinksOutsideATags')
),
],
[GeneratedFormSwitch('skipSort', label: tr('skipSort'))],
[GeneratedFormSwitch('reverseSort', label: tr('takeFirstLink'))],
[

View File

@@ -0,0 +1,87 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
class LiteAPKs extends AppSource {
LiteAPKs() {
hosts = ['liteapks.com'];
name = 'LiteAPKs';
}
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
RegExp standardUrlRegEx = RegExp(
'^https?://(www\\.)?${getSourceRegex(hosts)}/+[^/]+',
caseSensitive: false,
);
RegExpMatch? match = standardUrlRegEx.firstMatch(url);
if (match == null) {
throw InvalidURLError(name);
}
return match.group(0)!;
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
Map<String, dynamic> additionalSettings,
) async {
var standardUri = Uri.parse(standardUrl);
var slug = standardUri.path
.split('.')
.reversed
.toList()
.sublist(1)
.reversed
.join('.');
Response res1 = await sourceRequest(
'${standardUri.origin}/wp-json/wp/v2/posts?slug=$slug',
additionalSettings,
);
if (res1.statusCode != 200) {
throw getObtainiumHttpError(res1);
}
var liteAppId = jsonDecode(res1.body)[0]['id'];
if (liteAppId == null) {
throw NoReleasesError();
}
Response res2 = await sourceRequest(
'${standardUri.origin}/wp-json/v2/posts/$liteAppId',
additionalSettings,
);
if (res2.statusCode != 200) {
throw getObtainiumHttpError(res2);
}
var json = jsonDecode(res2.body);
var appName = json['data']?['title'] as String?;
var author = json['data']?['publisher'] as String?;
var version = json['data']?['versions']?[0]?['version'] as String?;
if (version == null) {
throw NoVersionError();
}
var apkUrls =
((json['data']?['versions']?[0]?['version_downloads'] as List<dynamic>?)
?.map((l) => l['version_download_link']) ??
[])
.map(
(l) => MapEntry<String, String>(
Uri.decodeComponent(Uri.parse(l).pathSegments.last),
l,
),
)
.toList();
return APKDetails(
version,
apkUrls,
AppNames(
author ?? Uri.parse(standardUrl).host,
appName ?? standardUrl.split('/').last,
),
);
}
}

View File

@@ -25,6 +25,7 @@ import 'package:obtainium/app_sources/huaweiappgallery.dart';
import 'package:obtainium/app_sources/izzyondroid.dart';
import 'package:obtainium/app_sources/html.dart';
import 'package:obtainium/app_sources/jenkins.dart';
import 'package:obtainium/app_sources/liteapks.dart';
import 'package:obtainium/app_sources/neutroncode.dart';
import 'package:obtainium/app_sources/rustore.dart';
import 'package:obtainium/app_sources/sourceforge.dart';
@@ -1076,6 +1077,7 @@ class SourceProvider {
HuaweiAppGallery(),
Tencent(),
CoolApk(),
LiteAPKs(),
VivoAppStore(),
Jenkins(),
APKMirror(),

View File

@@ -5,10 +5,10 @@ packages:
dependency: "direct main"
description:
name: android_intent_plus
sha256: dfc1fd3a577205ae8f11e990fb4ece8c90cceabbee56fcf48e463ecf0bd6aae3
sha256: "2329378af63f49b985cb2e110ac784d08374f1e2b1984be77ba9325b1c8cce11"
url: "https://pub.dev"
source: hosted
version: "5.3.0"
version: "5.3.1"
android_package_installer:
dependency: "direct main"
description:
@@ -48,10 +48,10 @@ packages:
dependency: "direct main"
description:
name: app_links
sha256: "85ed8fc1d25a76475914fff28cc994653bd900bc2c26e4b57a49e097febb54ba"
sha256: "5f88447519add627fe1cbcab4fd1da3d4fed15b9baf29f28b22535c95ecee3e8"
url: "https://pub.dev"
source: hosted
version: "6.4.0"
version: "6.4.1"
app_links_linux:
dependency: transitive
description:
@@ -104,10 +104,10 @@ packages:
dependency: "direct main"
description:
name: battery_plus
sha256: fb794c34cee2e4ea31005fb17ff15e1d904951ec7f15eedead741021870ee834
sha256: "03d5a6bb36db9d2b977c548f6b0262d5a84c4d5a4cfee2edac4a91d57011b365"
url: "https://pub.dev"
source: hosted
version: "6.2.2"
version: "6.2.3"
battery_plus_platform_interface:
dependency: transitive
description:
@@ -160,10 +160,10 @@ packages:
dependency: "direct main"
description:
name: connectivity_plus
sha256: "051849e2bd7c7b3bc5844ea0d096609ddc3a859890ec3a9ac4a65a2620cc1f99"
sha256: b5e72753cf63becce2c61fd04dfe0f1c430cc5278b53a1342dc5ad839eab29ec
url: "https://pub.dev"
source: hosted
version: "6.1.4"
version: "6.1.5"
connectivity_plus_platform_interface:
dependency: transitive
description:
@@ -232,10 +232,10 @@ packages:
dependency: "direct main"
description:
name: dynamic_color
sha256: eae98052fa6e2826bdac3dd2e921c6ce2903be15c6b7f8b6d8a5d49b5086298d
sha256: "43a5a6679649a7731ab860334a5812f2067c2d9ce6452cf069c5e0c25336c17c"
url: "https://pub.dev"
source: hosted
version: "1.7.0"
version: "1.8.1"
easy_localization:
dependency: "direct main"
description:
@@ -288,10 +288,10 @@ packages:
dependency: "direct main"
description:
name: file_picker
sha256: "13ba4e627ef24503a465d1d61b32596ce10eb6b8903678d362a528f9939b4aa8"
sha256: f2d9f173c2c14635cc0e9b14c143c49ef30b4934e8d1d274d6206fcb0086a06f
url: "https://pub.dev"
source: hosted
version: "10.2.1"
version: "10.3.3"
fixnum:
dependency: transitive
description:
@@ -482,10 +482,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e
sha256: b0694b7fb1689b0e6cc193b3f1fcac6423c4f93c74fb20b806c6b6f196db0c31
url: "https://pub.dev"
source: hosted
version: "2.0.28"
version: "2.0.30"
flutter_test:
dependency: transitive
description: flutter
@@ -548,10 +548,10 @@ packages:
dependency: "direct main"
description:
name: http
sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b"
sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
url: "https://pub.dev"
source: hosted
version: "1.4.0"
version: "1.5.0"
http_parser:
dependency: transitive
description:
@@ -572,26 +572,26 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
url: "https://pub.dev"
source: hosted
version: "10.0.9"
version: "11.0.2"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev"
source: hosted
version: "3.0.9"
version: "3.0.10"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.0.2"
lints:
dependency: transitive
description:
@@ -676,18 +676,18 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9
sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db"
url: "https://pub.dev"
source: hosted
version: "2.2.17"
version: "2.2.18"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2"
path_provider_linux:
dependency: transitive
description:
@@ -820,26 +820,26 @@ packages:
dependency: "direct main"
description:
name: provider
sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84"
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
url: "https://pub.dev"
source: hosted
version: "6.1.5"
version: "6.1.5+1"
share_plus:
dependency: "direct main"
description:
name: share_plus
sha256: b2961506569e28948d75ec346c28775bb111986bb69dc6a20754a457e3d97fa0
sha256: d7dc0630a923883c6328ca31b89aa682bacbf2f8304162d29f7c6aaff03a27a1
url: "https://pub.dev"
source: hosted
version: "11.0.0"
version: "11.1.0"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: "1032d392bc5d2095a77447a805aa3f804d2ae6a4d5eef5e6ebb3bd94c1bc19ef"
sha256: "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a"
url: "https://pub.dev"
source: hosted
version: "6.0.0"
version: "6.1.0"
shared_preferences:
dependency: "direct main"
description:
@@ -852,10 +852,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_android
sha256: "20cbd561f743a342c76c151d6ddb93a9ce6005751e7aa458baad3858bfbfb6ac"
sha256: a2608114b1ffdcbc9c120eb71a0e207c71da56202852d4aab8a5e30a82269e74
url: "https://pub.dev"
source: hosted
version: "2.4.10"
version: "2.4.12"
shared_preferences_foundation:
dependency: transitive
description:
@@ -947,10 +947,10 @@ packages:
dependency: transitive
description:
name: sqflite_android
sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b"
sha256: ecd684501ebc2ae9a83536e8b15731642b9570dc8623e0073d227d0ee2bfea88
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2+2"
sqflite_common:
dependency: transitive
description:
@@ -1019,10 +1019,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
url: "https://pub.dev"
source: hosted
version: "0.7.4"
version: "0.7.6"
timezone:
dependency: transitive
description:
@@ -1059,18 +1059,18 @@ packages:
dependency: transitive
description:
name: url_launcher_android
sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79"
sha256: "07cffecb7d68cbc6437cd803d5f11a86fe06736735c3dfe46ff73bcb0f958eed"
url: "https://pub.dev"
source: hosted
version: "6.3.16"
version: "6.3.21"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb"
sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7
url: "https://pub.dev"
source: hosted
version: "6.3.3"
version: "6.3.4"
url_launcher_linux:
dependency: transitive
description:
@@ -1083,10 +1083,10 @@ packages:
dependency: transitive
description:
name: url_launcher_macos
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f
url: "https://pub.dev"
source: hosted
version: "3.2.2"
version: "3.2.3"
url_launcher_platform_interface:
dependency: transitive
description:
@@ -1123,18 +1123,18 @@ packages:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.2.0"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
url: "https://pub.dev"
source: hosted
version: "15.0.0"
version: "15.0.2"
web:
dependency: transitive
description:
@@ -1155,10 +1155,10 @@ packages:
dependency: transitive
description:
name: webview_flutter_android
sha256: "9573ad97890d199ac3ab32399aa33a5412163b37feb573eb5b0a76b35e9ffe41"
sha256: "3c4eb4fcc252b40c2b5ce7be20d0481428b70f3ff589b0a8b8aaeb64c6bed701"
url: "https://pub.dev"
source: hosted
version: "4.8.2"
version: "4.10.2"
webview_flutter_platform_interface:
dependency: transitive
description:
@@ -1171,10 +1171,10 @@ packages:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: "71523b9048cf510cfa1fd4e0a3fa5e476a66e0884d5df51d59d5023dba237107"
sha256: fb46db8216131a3e55bcf44040ca808423539bc6732e7ed34fb6d8044e3d512f
url: "https://pub.dev"
source: hosted
version: "3.22.1"
version: "3.23.0"
win32:
dependency: transitive
description:
@@ -1208,5 +1208,5 @@ packages:
source: hosted
version: "6.3.0"
sdks:
dart: ">=3.8.1 <4.0.0"
flutter: ">=3.29.0"
dart: ">=3.9.0 <4.0.0"
flutter: ">=3.35.0"

View File

@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.2.3+2319
version: 1.2.4+2320
environment:
sdk: ^3.8.1