aboutsummaryrefslogtreecommitdiff
path: root/bridges/FDroidRepoBridge.php
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/FDroidRepoBridge.php')
-rw-r--r--bridges/FDroidRepoBridge.php370
1 files changed, 193 insertions, 177 deletions
diff --git a/bridges/FDroidRepoBridge.php b/bridges/FDroidRepoBridge.php
index c26bbacf..74147310 100644
--- a/bridges/FDroidRepoBridge.php
+++ b/bridges/FDroidRepoBridge.php
@@ -1,150 +1,162 @@
<?php
-class FDroidRepoBridge extends BridgeAbstract {
- const NAME = 'F-Droid Repository Bridge';
- const URI = 'https://f-droid.org/';
- const DESCRIPTION = 'Query any F-Droid Repository for its latest updates.';
-
- const ITEM_LIMIT = 50;
-
- const PARAMETERS = array(
- 'global' => array(
- 'url' => array(
- 'name' => 'Repository URL',
- 'title' => 'Usually ends with /repo/',
- 'required' => true,
- 'exampleValue' => 'https://srv.tt-rss.org/fdroid/repo'
- )
- ),
- 'Latest Updates' => array(
- 'sorting' => array(
- 'name' => 'Sort By',
- 'type' => 'list',
- 'values' => array(
- 'Latest added apps' => 'added',
- 'Latest updated apps' => 'lastUpdated'
- )
- ),
- 'locale' => array(
- 'name' => 'Locale',
- 'defaultValue' => 'en-US'
- )
- ),
- 'Follow Package' => array(
- 'package' => array(
- 'name' => 'Package Identifier',
- 'required' => true,
- 'exampleValue' => 'org.fox.ttrss'
- )
- )
- );
-
- // Stores repo information
- private $repo;
-
- public function getURI() {
- if (empty($this->queriedContext))
- return parent::getURI();
-
- $url = rtrim($this->GetInput('url'), '/');
- return strstr($url, '?', true) ?: $url;
- }
-
- public function getName() {
- if (empty($this->queriedContext))
- return parent::getName();
-
- $name = $this->repo['repo']['name'];
- switch($this->queriedContext) {
- case 'Latest Updates':
- return $name;
- case 'Follow Package':
- return $this->getInput('package') . ' - ' . $name;
- default:
- returnServerError('Unimplemented Context (getName)');
- }
- }
-
- public function collectData() {
- $this->repo = $this->getRepo();
- switch($this->queriedContext) {
- case 'Latest Updates':
- $this->getAllUpdates();
- break;
- case 'Follow Package':
- $this->getPackage($this->getInput('package'));
- break;
- default:
- returnServerError('Unimplemented Context (collectData)');
- }
- }
-
- private function getRepo() {
- $url = $this->getURI();
-
- // Get repo information (only available as JAR)
- $jar = getContents($url . '/index-v1.jar');
- $jar_loc = tempnam(sys_get_temp_dir(), '');
- file_put_contents($jar_loc, $jar);
-
- // JAR files are specially formatted ZIP files
- $jar = new ZipArchive;
- if ($jar->open($jar_loc) !== true) {
- returnServerError('Failed to extract archive');
- }
-
- // Get file pointer to the relevant JSON inside
- $fp = $jar->getStream('index-v1.json');
- if (!$fp) {
- returnServerError('Failed to get file pointer');
- }
-
- $data = json_decode(stream_get_contents($fp), true);
- fclose($fp);
- $jar->close();
- return $data;
- }
-
- private function getAllUpdates() {
- $apps = $this->repo['apps'];
- usort($apps, function($a, $b) {
- return $b[$this->getInput('sorting')] <=> $a[$this->getInput('sorting')];
- });
- $apps = array_slice($apps, 0, self::ITEM_LIMIT);
- foreach($apps as $app) {
- $latest = reset($this->repo['packages'][$app['packageName']]);
-
- if (isset($app['localized'])) {
- // Try provided locale, then en-US, then any
- $lang = $app['localized'];
- $lang = $lang[$this->getInput('locale')] ?? $lang['en-US'] ?? reset($lang);
- } else
- $lang = array();
-
- $item = array();
- $item['uri'] = $this->getURI() . '/' . $latest['apkName'];
- $item['title'] = $lang['name'] ?? $app['packageName'];
- $item['title'] .= ' ' . $latest['versionName'];
- $item['timestamp'] = date(DateTime::ISO8601, (int) ($app['lastUpdated'] / 1000));
- if (isset($app['authorName']))
- $item['author'] = $app['authorName'];
- if (isset($app['categories']))
- $item['categories'] = $app['categories'];
-
- // Adding Content
- $icon = $app['icon'] ?? '';
- if (!empty($icon)) {
- $icon = $this->getURI() . '/icons-320/' . $icon;
- $item['enclosures'] = array($icon);
- $icon = '<img src="' . $icon . '">';
- }
- $summary = $lang['summary'] ?? $app['summary'] ?? '';
- $description = markdownToHtml(trim($lang['description'] ?? $app['description'] ?? 'None'));
- $whatsNew = markdownToHtml(trim($lang['whatsNew'] ?? 'None'));
- $website = $this->link($lang['webSite'] ?? $app['webSite'] ?? $app['authorWebSite'] ?? null);
- $source = $this->link($app['sourceCode'] ?? null);
- $issueTracker = $this->link($app['issueTracker'] ?? null);
- $license = $app['license'] ?? 'None';
- $item['content'] = <<<EOD
+
+class FDroidRepoBridge extends BridgeAbstract
+{
+ const NAME = 'F-Droid Repository Bridge';
+ const URI = 'https://f-droid.org/';
+ const DESCRIPTION = 'Query any F-Droid Repository for its latest updates.';
+
+ const ITEM_LIMIT = 50;
+
+ const PARAMETERS = [
+ 'global' => [
+ 'url' => [
+ 'name' => 'Repository URL',
+ 'title' => 'Usually ends with /repo/',
+ 'required' => true,
+ 'exampleValue' => 'https://srv.tt-rss.org/fdroid/repo'
+ ]
+ ],
+ 'Latest Updates' => [
+ 'sorting' => [
+ 'name' => 'Sort By',
+ 'type' => 'list',
+ 'values' => [
+ 'Latest added apps' => 'added',
+ 'Latest updated apps' => 'lastUpdated'
+ ]
+ ],
+ 'locale' => [
+ 'name' => 'Locale',
+ 'defaultValue' => 'en-US'
+ ]
+ ],
+ 'Follow Package' => [
+ 'package' => [
+ 'name' => 'Package Identifier',
+ 'required' => true,
+ 'exampleValue' => 'org.fox.ttrss'
+ ]
+ ]
+ ];
+
+ // Stores repo information
+ private $repo;
+
+ public function getURI()
+ {
+ if (empty($this->queriedContext)) {
+ return parent::getURI();
+ }
+
+ $url = rtrim($this->GetInput('url'), '/');
+ return strstr($url, '?', true) ?: $url;
+ }
+
+ public function getName()
+ {
+ if (empty($this->queriedContext)) {
+ return parent::getName();
+ }
+
+ $name = $this->repo['repo']['name'];
+ switch ($this->queriedContext) {
+ case 'Latest Updates':
+ return $name;
+ case 'Follow Package':
+ return $this->getInput('package') . ' - ' . $name;
+ default:
+ returnServerError('Unimplemented Context (getName)');
+ }
+ }
+
+ public function collectData()
+ {
+ $this->repo = $this->getRepo();
+ switch ($this->queriedContext) {
+ case 'Latest Updates':
+ $this->getAllUpdates();
+ break;
+ case 'Follow Package':
+ $this->getPackage($this->getInput('package'));
+ break;
+ default:
+ returnServerError('Unimplemented Context (collectData)');
+ }
+ }
+
+ private function getRepo()
+ {
+ $url = $this->getURI();
+
+ // Get repo information (only available as JAR)
+ $jar = getContents($url . '/index-v1.jar');
+ $jar_loc = tempnam(sys_get_temp_dir(), '');
+ file_put_contents($jar_loc, $jar);
+
+ // JAR files are specially formatted ZIP files
+ $jar = new ZipArchive();
+ if ($jar->open($jar_loc) !== true) {
+ returnServerError('Failed to extract archive');
+ }
+
+ // Get file pointer to the relevant JSON inside
+ $fp = $jar->getStream('index-v1.json');
+ if (!$fp) {
+ returnServerError('Failed to get file pointer');
+ }
+
+ $data = json_decode(stream_get_contents($fp), true);
+ fclose($fp);
+ $jar->close();
+ return $data;
+ }
+
+ private function getAllUpdates()
+ {
+ $apps = $this->repo['apps'];
+ usort($apps, function ($a, $b) {
+ return $b[$this->getInput('sorting')] <=> $a[$this->getInput('sorting')];
+ });
+ $apps = array_slice($apps, 0, self::ITEM_LIMIT);
+ foreach ($apps as $app) {
+ $latest = reset($this->repo['packages'][$app['packageName']]);
+
+ if (isset($app['localized'])) {
+ // Try provided locale, then en-US, then any
+ $lang = $app['localized'];
+ $lang = $lang[$this->getInput('locale')] ?? $lang['en-US'] ?? reset($lang);
+ } else {
+ $lang = [];
+ }
+
+ $item = [];
+ $item['uri'] = $this->getURI() . '/' . $latest['apkName'];
+ $item['title'] = $lang['name'] ?? $app['packageName'];
+ $item['title'] .= ' ' . $latest['versionName'];
+ $item['timestamp'] = date(DateTime::ISO8601, (int) ($app['lastUpdated'] / 1000));
+ if (isset($app['authorName'])) {
+ $item['author'] = $app['authorName'];
+ }
+ if (isset($app['categories'])) {
+ $item['categories'] = $app['categories'];
+ }
+
+ // Adding Content
+ $icon = $app['icon'] ?? '';
+ if (!empty($icon)) {
+ $icon = $this->getURI() . '/icons-320/' . $icon;
+ $item['enclosures'] = [$icon];
+ $icon = '<img src="' . $icon . '">';
+ }
+ $summary = $lang['summary'] ?? $app['summary'] ?? '';
+ $description = markdownToHtml(trim($lang['description'] ?? $app['description'] ?? 'None'));
+ $whatsNew = markdownToHtml(trim($lang['whatsNew'] ?? 'None'));
+ $website = $this->link($lang['webSite'] ?? $app['webSite'] ?? $app['authorWebSite'] ?? null);
+ $source = $this->link($app['sourceCode'] ?? null);
+ $issueTracker = $this->link($app['issueTracker'] ?? null);
+ $license = $app['license'] ?? 'None';
+ $item['content'] = <<<EOD
{$icon}
<p>{$summary}</p>
<h1>Description</h1>
@@ -157,40 +169,44 @@ class FDroidRepoBridge extends BridgeAbstract {
<p>Issue Tracker: {$issueTracker}</p>
<p>license: {$app['license']}</p>
EOD;
- $this->items[] = $item;
- }
- }
-
- private function getPackage($package) {
- if (!isset($this->repo['packages'][$package])) {
- returnClientError('Invalid Package Name');
- }
- $package = $this->repo['packages'][$package];
-
- $count = self::ITEM_LIMIT;
- foreach($package as $version) {
- $item = array();
- $item['uri'] = $this->getURI() . '/' . $version['apkName'];
- $item['title'] = $version['versionName'];
- $item['timestamp'] = date(DateTime::ISO8601, (int) ($version['added'] / 1000));
- $item['uid'] = $version['versionCode'];
- $size = round($version['size'] / 1048576, 1); // Bytes -> MB
- $sdk_link = 'https://developer.android.com/studio/releases/platforms';
- $item['content'] = <<<EOD
+ $this->items[] = $item;
+ }
+ }
+
+ private function getPackage($package)
+ {
+ if (!isset($this->repo['packages'][$package])) {
+ returnClientError('Invalid Package Name');
+ }
+ $package = $this->repo['packages'][$package];
+
+ $count = self::ITEM_LIMIT;
+ foreach ($package as $version) {
+ $item = [];
+ $item['uri'] = $this->getURI() . '/' . $version['apkName'];
+ $item['title'] = $version['versionName'];
+ $item['timestamp'] = date(DateTime::ISO8601, (int) ($version['added'] / 1000));
+ $item['uid'] = $version['versionCode'];
+ $size = round($version['size'] / 1048576, 1); // Bytes -> MB
+ $sdk_link = 'https://developer.android.com/studio/releases/platforms';
+ $item['content'] = <<<EOD
<p>size: {$size}MB</p>
<p>Minimum SDK: {$version['minSdkVersion']}
(<a href="{$sdk_link}">SDK to Android Version List</a>)</p>
<p>hash ({$version['hashType']}): {$version['hash']}</p>
EOD;
- $this->items[] = $item;
- if (--$count <= 0)
- break;
- }
- }
-
- private function link($url) {
- if (empty($url))
- return null;
- return '<a href="' . $url . '">' . $url . '</a>';
- }
+ $this->items[] = $item;
+ if (--$count <= 0) {
+ break;
+ }
+ }
+ }
+
+ private function link($url)
+ {
+ if (empty($url)) {
+ return null;
+ }
+ return '<a href="' . $url . '">' . $url . '</a>';
+ }
}
?s=13&d=retro' width='13' height='13' alt='Gravatar' /> Jorge Jiménez 1-1/+1 2023-09-01keep export star as (#4451)Gravatar Dylan Conway 1-14/+0 2023-09-01bun-vscode 0.0.8Gravatar Colin McDonnell 3-41/+39 2023-09-01Update commandsGravatar Colin McDonnell 3-4/+6 2023-09-01fix `Bun.serve` with tls and `Bun.file` (#4450)Gravatar Dylan Conway 3-14/+40 2023-09-01exclusive maxGravatar Dylan Conway 1-1/+1 2023-09-01Fix debug console from appears on startGravatar Ashcon Partovi 2-2/+5 2023-09-01Add configuration options to extensionGravatar Ashcon Partovi 5-5/+137 2023-09-01Fix run button starting cwd at /Gravatar Ashcon Partovi 1-0/+2 2023-09-01fix(runtime): fix dns_resolver crash (#4435)Gravatar dave caruso 3-17/+19 2023-09-01Fix background colorGravatar Ashcon Partovi 1-2/+3 2023-09-01Allow older versions of VSCodeGravatar Ashcon Partovi 2-6/+5 2023-09-01Fix README for extensionGravatar Ashcon Partovi 2-7/+12 2023-09-01Update VSCode extensionGravatar Ashcon Partovi 1-3/+4 2023-09-01Fix breakpoint on entry for extensionGravatar Ashcon Partovi 5-18/+15 2023-09-01Add Bun.canReload event to inspectorGravatar Ashcon Partovi 2-0/+17 2023-08-31JavaScript Debug Terminal == Bun TerminalGravatar Ashcon Partovi 1-0/+32 2023-08-31fix(runtime): `fs.cp` edge cases (#4439)Gravatar dave caruso 2-8/+44 2023-08-31only set initial debugger breakpoint once (#4441)Gravatar Dylan Conway 1-2/+11 2023-08-31Make breakpoints faster in VSCode extensionGravatar Ashcon Partovi 1-241/+327 2023-08-31`bun install` correctly join dependency URLs (#4421)Gravatar Julian 6-64/+243 2023-08-31get name if not provided in `FormData.append` (#4434)Gravatar Dylan Conway 4-5/+45 2023-08-31Fix vscode debug terminalGravatar Ashcon Partovi 1-21/+0