Skip to content
This repository has been archived by the owner on Aug 9, 2021. It is now read-only.

Commit

Permalink
feat(package): defer apk / upk parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
btry committed Sep 27, 2017
1 parent 70752dc commit c84d114
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 78 deletions.
153 changes: 93 additions & 60 deletions inc/package.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,29 +232,6 @@ public function prepareInputForAdd($input) {
$this->createEntityDirectory(dirname($destination));
if (rename($uploadedFile, $destination)) {
$fileExtension = pathinfo($destination, PATHINFO_EXTENSION);
$filename = pathinfo($destination, PATHINFO_FILENAME);
if ($fileExtension == 'apk') {
$apk = new \ApkParser\Parser($destination);
} else if ($fileExtension == 'upk') {
$upkParser = new PluginFlyvemdmUpkparser($destination);
$apk = $upkParser->getApkParser();
if (!($apk instanceof \ApkParser\Parser)) {
Session::addMessageAfterRedirect(__('Could not parse the UPK file', 'flyvemdm'));
return false;
}
}
$manifest = $apk->getManifest();
$iconResourceId = $manifest->getApplication()->getIcon();
$labelResourceId = $manifest->getApplication()->getLabel();
$iconResources = $apk->getResources($iconResourceId);
$apkLabel = $apk->getResources($labelResourceId);
$input['icon'] = base64_encode(stream_get_contents($apk->getStream($iconResources[0])));
$input['name'] = $manifest->getPackageName();
if ((!isset($input['alias'])) || (strlen($input['alias']) == 0)) {
$input['alias'] = $apkLabel[0]; // Get the first item
}
$input['version'] = $manifest->getVersionName();
$input['version_code'] = $manifest->getVersionCode();
$input['filesize'] = fileSize($destination);
$input['dl_filename'] = basename($uploadedFile);
} else {
Expand Down Expand Up @@ -317,48 +294,30 @@ public function prepareInputForUpdate($input) {
}
}

try {
$input['filename'] = $this->fields['entities_id'] . "/" . uniqid() . "_" . basename($uploadedFile);
$destination = FLYVEMDM_PACKAGE_PATH . "/" . $input['filename'];
$this->createEntityDirectory(dirname($destination));
if (rename($uploadedFile, $destination)) {
if ($fileExtension == "apk") {
$apk = new \ApkParser\Parser($destination);
} else if ($fileExtension == "upk") {
$upkParser = new PluginFlyvemdmUpkparser($destination);
$apk = $upkParser->getApkParser();
if (!($apk instanceof \ApkParser\Parser)) {
Session::addMessageAfterRedirect(__('Could not parse the UPK file', "flyvemdm"));
return false;
if (isset($uploadedFile)) {
try {
$input['filename'] = $this->fields['entities_id'] . "/" . uniqid() . "_" . basename($uploadedFile);
$destination = FLYVEMDM_PACKAGE_PATH . "/" . $input['filename'];
$this->createEntityDirectory(dirname($destination));
if (rename($uploadedFile, $destination)) {
$input['filesize'] = fileSize($destination);
$input['dl_filename'] = basename($uploadedFile);
if ($filename != $this->fields['filename']) {
unlink(FLYVEMDM_PACKAGE_PATH . "/" . $this->fields['filename']);
}
} else {
if (!is_writable(dirname($destination))) {
$destination = dirname($destination);
Toolbox::logInFile('php-errors', "Plugin Flyvemdm : Directory '$destination' is not writeable");
}
Session::addMessageAfterRedirect(__('Unable to save the file', "flyvemdm"));
$input = false;
}
$manifest = $apk->getManifest();
$iconResourceId = $manifest->getApplication()->getIcon();
$labelResourceId = $manifest->getApplication()->getLabel();
$iconResources = $apk->getResources($iconResourceId);
$apkLabel = $apk->getResources($labelResourceId);
$input['icon'] = base64_encode(stream_get_contents($apk->getStream($iconResources[0])));
$input['name'] = $manifest->getPackageName();
$input['version'] = $manifest->getVersionName();
$input['version_code'] = $manifest->getVersionCode();
$input['filesize'] = fileSize($destination);
$input['dl_filename'] = basename($uploadedFile);
if ($filename != $this->fields['filename']) {
unlink(FLYVEMDM_PACKAGE_PATH . "/" . $this->fields['filename']);
}
} else {
if (!is_writable(dirname($destination))) {
$destination = dirname($destination);
Toolbox::logInFile('php-errors', "Plugin Flyvemdm : Directory '$destination' is not writeable");
}
Session::addMessageAfterRedirect(__('Unable to save the file', "flyvemdm"));
} catch (Exception $e) {
// Ignore exceptions for now
$input = false;
}
} catch (Exception $e) {
// Ignore exceptions for now
$input = false;
}

return $input;
}

Expand Down Expand Up @@ -581,6 +540,80 @@ protected function sendFile() {
exit(0);
}

/**
* Launch parsing of applciation files
*
* @see PluginFlyvemdmPackage::parseApplication()
*
* @param CronTask $crontask
*
* @return integer >0 means done, < 0 means not finished, 0 means nothing to do
*/
public static function cronParseApplication(CronTask $crontask) {
global $DB;

$cronStatus = 0;

$request = [
'FROM' => static::getTable(),
'WHERE' => ['AND' => [
'parse_status' => 'pending',
]],
'LIMIT' => 10
];
foreach ($DB->request($request) as $data) {
$package = new static();
$package->getFromDB($data['id']);
if ($package->parseApplication()) {
$cronStatus++;
}
}

return $cronStatus;
}

/**
* Analyzes an application (APK or UPK) to collect metadata
*
* @return boolean true if success, false otherwise
*/
private function parseApplication() {
$destination = FLYVEMDM_PACKAGE_PATH . '/' . $this->fields['filename'];
$fileExtension = pathinfo($destination, PATHINFO_EXTENSION);
if ($fileExtension == 'apk') {
$apk = new \ApkParser\Parser($destination);
} else if ($fileExtension == 'upk') {
$upkParser = new PluginFlyvemdmUpkparser($destination);
$apk = $upkParser->getApkParser();
if (!($apk instanceof \ApkParser\Parser)) {
$this->update([
'id' => $this->fields['id'],
'parse_status' => 'failed'
]);
return false;
}
}
$manifest = $apk->getManifest();
$iconResourceId = $manifest->getApplication()->getIcon();
$labelResourceId = $manifest->getApplication()->getLabel();
$iconResources = $apk->getResources($iconResourceId);
$apkLabel = $apk->getResources($labelResourceId);

$input = [];
$input['icon'] = base64_encode(stream_get_contents($apk->getStream($iconResources[0])));
$input['name'] = $manifest->getPackageName();
if ((!isset($input['alias'])) || (strlen($input['alias']) == 0)) {
$input['alias'] = $apkLabel[0]; // Get the first item
}
$input['version'] = $manifest->getVersionName();
$input['version_code'] = $manifest->getVersionCode();

$input['id'] = $this->fields['id'];
$input['parse_status'] = 'parsed';
$this->update($input);
return true;
}

/**
* Deletes the packages related to the entity
* @param CommonDBTM $item
Expand Down
17 changes: 11 additions & 6 deletions install/installer.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,6 @@ protected function upgrade($fromVersion) {
* @param string $toVersion
*/
protected function upgradeOneStep($toVersion) {

$suffix = str_replace('.', '_', $toVersion);
$includeFile = __DIR__ . "/upgrade/update_to_$suffix.php";
if (is_readable($includeFile) && is_file($includeFile)) {
Expand All @@ -506,11 +505,17 @@ protected function upgradeOneStep($toVersion) {
}

protected function createJobs() {
CronTask::Register('PluginFlyvemdmMqttupdatequeue', 'UpdateTopics', MINUTE_TIMESTAMP,
array(
'comment' => __('Update retained MQTT topics for fleet policies', 'flyvemdm'),
'mode' => CronTask::MODE_EXTERNAL
));
CronTask::Register(PluginFlyvemdmMqttupdatequeue::class, 'UpdateTopics', MINUTE_TIMESTAMP,
[
'comment' => __('Update retained MQTT topics for fleet policies', 'flyvemdm'),
'mode' => CronTask::MODE_EXTERNAL
]);

CronTask::Register(PluginFlyvemdmPackage::class, 'ParseApplication', MINUTE_TIMESTAMP,
[
'comment' => __('Parse uploaded applications', 'flyvemdm'),
'mode' => CronTask::MODE_EXTERNAL
]);
}

/**
Expand Down
22 changes: 11 additions & 11 deletions install/mysql/plugin_flyvemdm_empty.sql
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,17 @@ CREATE TABLE IF NOT EXISTS `glpi_plugin_flyvemdm_mqttusers` (
-- Export de la structure de table glpi-flyvemdm. glpi_plugin_flyvemdm_packages
DROP TABLE IF EXISTS `glpi_plugin_flyvemdm_packages`;
CREATE TABLE IF NOT EXISTS `glpi_plugin_flyvemdm_packages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '',
`alias` varchar(255) NOT NULL DEFAULT '',
`version` varchar(255) NOT NULL DEFAULT '',
`version_code` varchar(255) NOT NULL DEFAULT '',
`icon` text COLLATE utf8_unicode_ci NOT NULL,
`filename` varchar(255) NOT NULL DEFAULT '',
`filesize` int(11) NOT NULL DEFAULT '0',
`entities_id` int(11) NOT NULL DEFAULT '0',
`dl_filename` varchar(255) NOT NULL DEFAULT '',
`is_parsed` tinyint(1) NOT NULL DEFAULT '0',
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '',
`alias` varchar(255) NOT NULL DEFAULT '',
`version` varchar(255) NOT NULL DEFAULT '',
`version_code` varchar(255) NOT NULL DEFAULT '',
`icon` text COLLATE utf8_unicode_ci NOT NULL,
`filename` varchar(255) NOT NULL DEFAULT '',
`filesize` int(11) NOT NULL DEFAULT '0',
`entities_id` int(11) NOT NULL DEFAULT '0',
`dl_filename` varchar(255) NOT NULL DEFAULT '',
`parse_status` enum('pending', 'parsed', 'failed') NOT NULL DEFAULT 'pending',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Expand Down
4 changes: 4 additions & 0 deletions install/upgrade/update_to_dev.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,8 @@ function plugin_flyvemdm_update_to_dev(Migration $migration) {
// All policies exist for Android
$migration->addPostQuery("UPDATE `$table` SET `is_android_policy` = '1'");

// update Applications table
$table = 'glpi_plugin_flyvemdm_packages';
$migration->addField($table, 'parse_status', "enum('pending', 'parsed', 'failed')", ['after' => 'dl_filename', 'default' => 'pending']);
$migration->addPostQuery("UPDATE `$table` SET `parse_status` = 'parsed'");
}
4 changes: 3 additions & 1 deletion setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ function plugin_init_flyvemdm() {

if ($plugin->isActivated('flyvemdm')) {
require_once(__DIR__ . '/vendor/autoload.php');
require_once(__DIR__ . '/lib/GlpiLocalesExtension.php');
if (!class_exists('GlpiLocalesExtension')) {
require_once(__DIR__ . '/lib/GlpiLocalesExtension.php');
}

plugin_flyvemdm_registerClasses();
plugin_flyvemdm_addHooks();
Expand Down

0 comments on commit c84d114

Please sign in to comment.