scratch – Rev 139

Subversion Repositories:
Rev:
<?php

###########################################################################
##  Copyright (C) Wizardry and Steamworks 2017 - License: GNU GPLv3      ##
###########################################################################

require_once('php/pseudocrypt.php');
require_once('php/functions.php');
require_once('vendor/autoload.php');

### FFMpeg
require_once('vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/FFMpeg.php');

### Load configuration.
$config = spyc_load_file('config.yaml');

### If tags were specified then check whether the hash matches any tags.
$tags = array();
if(isset($_GET['tags']) && !empty($_GET['tags'])) {
    ## Extract the token field values.
    $tags = array_filter(
        array_map(
            function($item) {
                return $item->value;
            },
            array_values(
                json_decode(
                    stripslashes(
                        $_GET['tags']
                    )
                )
            )
        )
    );
    
    ## Connect or create the scratch database.
    $db = new PDO('sqlite:db/scratch.sqlite3');

    ## Set the error mode to exceptions.
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    try {
        $db->beginTransaction();
    
        ## Create tags table if it does not exist.
        $db->query('CREATE TABLE IF NOT EXISTS "tags" ("hash" text NOT NULL COLLATE NOCASE, "tag" text COLLATE NOCASE, UNIQUE("hash", "tag") ON CONFLICT REPLACE)');
    
        ## Select all the hashes that match supplied tags.
        $q = $db->prepare('SELECT "hash" FROM "tags" WHERE tag IN ('.implode(',', array_fill(0, count($tags), '?')).')');
        foreach($tags as $i => $tag)
            $q->bindValue($i+1, $tag);
    
        $result = $q->execute();
        $tags = $q->fetchAll(PDO::FETCH_COLUMN, 0);
        $db->commit();
    } catch(Exception $e) {
        error_log($e);
        ## Rollback.
        $db->rollback();
    }
}

### Open MIME.
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if (!$finfo) {
    http_response_code(500);
    die('Internal server error.');
}

echo json_encode(
    array_values(
        array_filter(
            array_map(
                function ($file) use ($config, $finfo, $tags) {
                    #### Get the file hash.
                    $fileHash = array_shift(explode('.', $file));
    
                    #### Build the user path.
                    $userPath = join(
                        DIRECTORY_SEPARATOR,
                        array(
                            $config['STORE_FOLDER'],
                            $file
                        )
                    );
    
                    #### If the extension is not allowed then skip this file.
                    $fileExtension = pathinfo($userPath, PATHINFO_EXTENSION);
                    if (!isset($fileExtension) ||
                        !in_array(strtoupper($fileExtension),
                            array_map('strtoupper', $config['ALLOWED_FILE_EXTENSIONS'])))
                        return null;
                       
                    #### Hook for various file extensions.
                    $opengraph = FALSE;
                    switch (strtoupper($fileExtension)) {
                        case "MP4":
                            ### Generate a hash for the preview image.
                            $previewHash = strtolower(
                                PseudoCrypt::hash(
                                    preg_replace(
                                        '/\D/',
                                        '',
                                        hash(
                                            'sha512',
                                            $fileHash
                                        )
                                    ),
                                    $config['ASSET_HASH_SIZE']
                                )
                            );
            
                            ### Build the user path.
                            $previewFile = join(
                                DIRECTORY_SEPARATOR,
                                array(
                                    $config['STORE_FOLDER'],
                                    $previewHash
                                )
                            );
            
                            ### Do not re-create the thumbnail if it already exists.
                            if (file_exists($previewFile.'.'.'jpg')) {
                                $opengraph = TRUE;
                                break;
                            }
            
                            ### Extract thumbnail.
                            $ffmpeg = FFMpeg\FFMpeg::create();
                            $video = $ffmpeg->open($userPath);
                            $frame = $video->frame(
                                FFMpeg\Coordinate\TimeCode::fromSeconds(
                                    $config['VIDEO_PREVIEW_IMAGE_FRAME_SECOND']
                                )
                            );
                            $frame->save($previewFile.'.'.'jpg');
                            $opengraph = TRUE;
                            break;
                        case "GIF":
                            $opengraph = TRUE;
                        case "PNG":
                        case "HTML":
                        case "HTM":
                        case "TGA":
                        case "SVG":
                        case "JPEG":
                        case "JPG":
                            $previewHash = $fileHash;
                            break;
                        default:
                            return null;
                    }
                    
                    if(!empty($tags) && !in_array($fileHash, $tags)) {
                        return array();
                    }
            
                    return array(
                        'url' => $fileHash,
                        'type' => finfo_file($finfo, $userPath),
                        'preview' => $previewHash,
                        'opengraph' => $opengraph
                    );
                },
                array_values(
                    array_filter(scandir($config['STORE_FOLDER']),
                        function ($entry) use ($config) {
                            return !is_dir($entry) && filesize(
                                join(
                                    DIRECTORY_SEPARATOR,
                                    array(
                                        $config['STORE_FOLDER'],
                                        $entry
                                    )
                                )
                            );
                        }
                    )
                )
            )
        )
    )
);

finfo_close($finfo);

Generated by GNU Enscript 1.6.5.90.