Loop for newest version in appstore response

The current implementation when fetching apps from the appstore is to assume that the first element is the newest version, this is now always applicable and leads to the fact that for some apps (e.g. nextant) the newest version is not delivered. This can be easily tested by comparing the version of the downloaded Nextant version.

This change will loop over all releases delivered by the appstore and chooses the newest compatible one. While not the cleanest solution, it does its job.

Most of the code are actually unit tests. Whereas I have copied the whole original response from the appstore and also have performed the transformation. So that's why the diff looks so huge.

Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
This commit is contained in:
Lukas Reschke 2016-11-24 14:29:57 +01:00
parent e3489d92fd
commit 6a4c0cf237
No known key found for this signature in database
GPG Key ID: B9F6980CF6E759B1
4 changed files with 1946 additions and 12 deletions

View File

@ -21,12 +21,16 @@
namespace OC\App\AppStore\Fetcher;
use OC\App\AppStore\Version\VersionParser;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Files\IAppData;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
class AppFetcher extends Fetcher {
/** @var IConfig */
private $config;
/**
* @param IAppData $appData
* @param IClientService $clientService
@ -44,6 +48,7 @@ class AppFetcher extends Fetcher {
);
$this->fileName = 'apps.json';
$this->config = $config;
$versionArray = \OC_Util::getVersion();
$this->endpointUrl = sprintf(
@ -53,4 +58,66 @@ class AppFetcher extends Fetcher {
$versionArray[2]
);
}
/**
* Only returns the latest compatible app release in the releases array
*
* @return array
*/
protected function fetch() {
$client = $this->clientService->newClient();
$response = $client->get($this->endpointUrl);
$responseJson = [];
$responseJson['data'] = json_decode($response->getBody(), true);
$responseJson['timestamp'] = $this->timeFactory->getTime();
$response = $responseJson;
$ncVersion = $this->config->getSystemValue('version');
$ncMajorVersion = explode('.', $ncVersion)[0];
foreach($response['data'] as $dataKey => $app) {
$releases = [];
// Filter all compatible releases
foreach($app['releases'] as $release) {
// Exclude all nightly releases
if($release['isNightly'] === false) {
// Exclude all versions not compatible with the current version
$versionParser = new VersionParser();
$version = $versionParser->getVersion($release['rawPlatformVersionSpec']);
if(
// Major version is bigger or equals to the minimum version of the app
version_compare($ncMajorVersion, $version->getMinimumVersion(), '>=')
// Major version is smaller or equals to the maximum version of the app
&& version_compare($ncMajorVersion, $version->getMaximumVersion(), '<=')) {
$releases[] = $release;
}
}
}
// Get the highest version
$versions = [];
foreach($releases as $release) {
$versions[] = $release['version'];
}
usort($versions, 'version_compare');
$versions = array_reverse($versions);
$compatible = false;
if(isset($versions[0])) {
$highestVersion = $versions[0];
foreach ($releases as $release) {
if ((string)$release['version'] === (string)$highestVersion) {
$compatible = true;
$response['data'][$dataKey]['releases'] = [$release];
break;
}
}
}
if(!$compatible) {
unset($response['data'][$dataKey]);
}
}
return $response;
}
}

View File

@ -30,11 +30,11 @@ abstract class Fetcher {
const INVALIDATE_AFTER_SECONDS = 300;
/** @var IAppData */
private $appData;
protected $appData;
/** @var IClientService */
private $clientService;
protected $clientService;
/** @var ITimeFactory */
private $timeFactory;
protected $timeFactory;
/** @var string */
protected $fileName;
/** @var string */
@ -53,6 +53,20 @@ abstract class Fetcher {
$this->timeFactory = $timeFactory;
}
/**
* Fetches the response from the server
*
* @return array
*/
protected function fetch() {
$client = $this->clientService->newClient();
$response = $client->get($this->endpointUrl);
$responseJson = [];
$responseJson['data'] = json_decode($response->getBody(), true);
$responseJson['timestamp'] = $this->timeFactory->getTime();
return $responseJson;
}
/**
* Returns the array with the categories on the appstore server
*
@ -77,12 +91,8 @@ abstract class Fetcher {
}
// Refresh the file content
$client = $this->clientService->newClient();
try {
$response = $client->get($this->endpointUrl);
$responseJson = [];
$responseJson['data'] = json_decode($response->getBody(), true);
$responseJson['timestamp'] = $this->timeFactory->getTime();
$responseJson = $this->fetch();
$file->putContent(json_encode($responseJson));
return json_decode($file->getContent(), true)['data'];
} catch (\Exception $e) {

File diff suppressed because one or more lines are too long

View File

@ -21,7 +21,6 @@
namespace Test\App\AppStore\Fetcher;
use OC\App\AppStore\Fetcher\AppFetcher;
use OC\App\AppStore\Fetcher\Fetcher;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Files\IAppData;