diff options
Diffstat (limited to 'lib/FIDD.php')
-rw-r--r-- | lib/FIDD.php | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/lib/FIDD.php b/lib/FIDD.php new file mode 100644 index 0000000..8cf78fe --- /dev/null +++ b/lib/FIDD.php @@ -0,0 +1,215 @@ +<?php +/** + * FIDD class. See ../README.md. + * + * PHP 5.3 + * + * @license http://www.opensource.org/licenses/MIT MIT + * @author Romain d'Alverny @rdalverny +*/ + +include 'lib/lib.php'; +include 'lib/fabpot-yaml/lib/sfYaml.php'; + +/** +*/ +class FIDD +{ + /** + * @param string $app_path + * @param string $url rsync url to sync from + * @param string $prefix + * + * @return boolean + */ + public static function run($app_path, $url, $prefix) + { + $tmp_path = $app_path . '/var/tmp'; + + echo sprintf("rsync'ing bcd.mageia.org files from %s...\n", $url); + if (self::rsync_mirror_files($url, $tmp_path)) { + echo "Failed to rsync remote ISOs...\n"; + return false; + } + + echo "fetching ISOs filesize...\n"; + $filesizes = self::rsync_get_filesizes($url); + + echo "building definition file...\n"; + $info = self::build_definitions($prefix, $tmp_path, $filesizes); + + self::save_definitions($info, $app_path . '/var/definitions'); + + return true; + } + + /** + * Dump $definitions into JSON, YAML and INI formats in $dir. + * + * @param array $definitions + * @param string $app_root + * + * @return void + */ + private static function save_definitions($definitions, $dir) + { + ksort($definitions); + + // JSON + file_put_contents($dir . '/data.json', json_encode($definitions)); + + // dump into YAML + $s = sfYaml::dump($definitions, 10); + file_put_contents($dir . '/data.yaml', $s); + + // dump into INI + write_ini_file($definitions, $dir . '/data.ini', true); + + echo sprintf("Found %d items:\n - %s\n\nand %d invalid ones.\n", + count($definitions), + implode("\n - ", array_keys($definitions)), + isset($definitions['invalid']) ? count($definitions['invalid']) : 0); + + echo "Data is now available in 3 formats: var/definitions/data.{json,yaml,ini}. Help yourself!\n\n"; + } + + /** + * Mirror files from remote. + * + * @param string $url + * @param string $dir where to mirror files + */ + private static function rsync_mirror_files($url, $dir) + { + $cmd = sprintf('/usr/bin/rsync -avHP --exclude=*.iso %s %s', + escapeshellarg($url), + escapeshellarg($dir)); + + exec($cmd, $out, $ret); + + return $ret; + } + + /** + * Get and format all ISOs file size. + * + * @param string $url rsync url where to look at data. + * + * @return array ["file.iso" => "size", ...] + */ + private static function rsync_get_filesizes($url) + { + $cmd = sprintf('/usr/bin/rsync -a --list-only %s | awk \'{print $2"\t"$5}\'', + escapeshellarg($url)); + + $isos = array(); + + exec($cmd, $out, $ret); + if ($ret === 0) { + foreach ($out as $line) { + $line = explode("\t", trim($line)); + if (trim(substr($line[1], -3, 3)) == 'iso') { + $file = explode('/', $line[1]); + $isos[$file[1]] = formatBytes($line[0], 1); + } + } + } + + return $isos; + } + + /** + * Parse mirrors files in $dir and build a catalog of these. + * + * @param string $prefix + * @param string $dir where to look for files + * @param array $filesizes sizes of each .iso file + * + * @return array + */ + function build_definitions($prefix, $dir, $filesizes) + { + $info = array(); + $isos = glob($dir . '/*'); + + foreach ($isos as $isodir) { + $data = array(); + $files = glob($isodir . '/*.*'); + + foreach ($files as $f) { + $fi = pathinfo($f); + $ext = $fi['extension']; + + switch ($fi['extension']) + { + case 'md5': + $key = str_replace('.iso.md5', '.iso', basename($f)); + $data['file'] = $key; + $data['md5'] = self::get_checksum_value($f); + break; + case 'sha1': $data['sha1'] = self::get_checksum_value($f); break; + case 'langs': $data['langs'] = implode(', ', explode("\n", trim(file_get_contents($f)))); break; + } + } + + if (null !== ($ret = self::is_correct_name($data['file']))) { + $data['path'] = sprintf('%s/%s', + $ret['release'] == '' ? sprintf('iso/%s', $ret['version']) : 'iso/cauldron', + str_replace('.iso', '', $data['file']) + ); + $data['torrent'] = sprintf('iso/cauldron/torrents/%s', str_replace('.iso', '.torrent', $data['file'])); + $data['name'] = str_replace(array('-', '.iso', 'i586', 'x86_64'), array(' ', '', '32bit', '64bit'), $data['file']); + $data['size'] = $filesizes[$data['file']]; + + $info[$data['file']] = $data; + } else { + $info['invalid'][] = $data; + } + //$info[str_replace($prefix . '-', '', $key)] = $data; + } + + return $info; + } + + /** + * Extract checksum from .md5 or .sha1 file. + * + * @param string $f + * + * @return string + */ + private static function get_checksum_value($f) + { + $s = trim(file_get_contents($f)); + $s = explode(" ", $s); + return trim($s[0]); + } + + /** + * Validate and extract Mageia image name. + * + * @see https://wiki.mageia.org/en/Product_naming + * + * @param string $s + * + * @return array + */ + public static function is_correct_name($s) + { + $re = '/^(Mageia)-(\d+)(-(alpha|beta|RC|rc)(\d*))?(-(.*))?-(i586|x86_64|dual)?(-(CD|DVD|BR))?(-(build\_\w+))?\.(.*)$/'; + if (preg_match($re, $s, $arr)) { + $ret = array( + 'name' => $arr[1], + 'version' => $arr[2], + 'release' => $arr[4] . $arr[5], + 'variant' => $arr[7], + 'arch' => $arr[8], + 'medium' => $arr[10], + 'build' => $arr[12], + 'ext' => $arr[13] + ); + return $ret; + } + return false; + } +}
\ No newline at end of file |