initial version

This commit is contained in:
Robin Appelman 2017-08-08 13:34:56 +02:00
commit 8b64b8c31c
8 changed files with 463 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.env
vendor

17
README.md Normal file
View file

@ -0,0 +1,17 @@
# Migrate
Script to migrate demos to cold storage
## Usage
The migrate scripts expects demos to be stored in the format as created by the [backup script](https://github.com/demostf/backup)
The following environment variables are required for the script
- SOURCE: The url of the api to backup the demos from (https://api.demos.tf)
- STORAGE_ROOT: The directory the demos are in
- BASE_URL: The base url that the demos can be accessed from
- BACKEND: The name for the backend to set the demos to
- KEY: The edit key for the api
The script will look in a .env file if the variables aren't set in the environment

11
composer.json Normal file
View file

@ -0,0 +1,11 @@
{
"autoload": {
"psr-4": {
"Demostf\\Migrate\\": "src/"
}
},
"require": {
"vlucas/phpdotenv": "^2.4",
"guzzlehttp/guzzle": "^6.3"
}
}

299
composer.lock generated Normal file
View file

@ -0,0 +1,299 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "f44dc88b45565b32549a6fe5e4001349",
"packages": [
{
"name": "guzzlehttp/guzzle",
"version": "6.3.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699",
"reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699",
"shasum": ""
},
"require": {
"guzzlehttp/promises": "^1.0",
"guzzlehttp/psr7": "^1.4",
"php": ">=5.5"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^4.0 || ^5.0",
"psr/log": "^1.0"
},
"suggest": {
"psr/log": "Required for using the Log middleware"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.2-dev"
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle is a PHP HTTP client library",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"rest",
"web service"
],
"time": "2017-06-22T18:50:49+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "v1.3.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
"shasum": ""
},
"require": {
"php": ">=5.5.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle promises library",
"keywords": [
"promise"
],
"time": "2016-12-20T10:07:11+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "1.4.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
"reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Tobias Schultze",
"homepage": "https://github.com/Tobion"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
"request",
"response",
"stream",
"uri",
"url"
],
"time": "2017-03-20T17:10:46+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "vlucas/phpdotenv",
"version": "v2.4.0",
"source": {
"type": "git",
"url": "https://github.com/vlucas/phpdotenv.git",
"reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c",
"reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"require-dev": {
"phpunit/phpunit": "^4.8 || ^5.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"autoload": {
"psr-4": {
"Dotenv\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause-Attribution"
],
"authors": [
{
"name": "Vance Lucas",
"email": "vance@vancelucas.com",
"homepage": "http://www.vancelucas.com"
}
],
"description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
"keywords": [
"dotenv",
"env",
"environment"
],
"time": "2016-09-01T10:05:43+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}

23
migrate.php Normal file
View file

@ -0,0 +1,23 @@
<?php declare(strict_types=1);
require 'vendor/autoload.php';
if (!getenv('STORAGE_ROOT')) {
$env = new \Dotenv\Dotenv(__DIR__);
$env->load();
}
$store = new \Demostf\Migrate\Store(getenv('STORAGE_ROOT'), getenv('BASE_URL'));
$api = new \Demostf\Migrate\Api(getenv('SOURCE'));
$migrate = new \Demostf\Migrate\Migrate($api, $store, getenv('BACKEND'), getenv('KEY'));
$statePath = getenv('STATE_FILE');
$fromDate = new DateTime('-2 month');
$list = $api->listDemos(1, 'ASC', 'static');
foreach ($list as $demo) {
if ($demo['time'] < $fromDate) {
echo "${demo['id']}\n";
$migrate->migrateDemo($demo);
}
}

40
src/Api.php Normal file
View file

@ -0,0 +1,40 @@
<?php declare(strict_types=1);
namespace Demostf\Migrate;
use GuzzleHttp\Client;
class Api {
private $endpoint;
private $client;
public function __construct($endpoint) {
$this->endpoint = $endpoint;
$this->client = new Client();
}
public function listDemos(int $page = 0, string $order = 'DESC', $backend = ''): array {
$url = $this->endpoint . '/demos?page=' . $page . '&order=' . $order . '&backend=' . $backend;
$content = file_get_contents($url);
$demos = json_decode($content, true);
foreach ($demos as &$data) {
$date = new \DateTime();
$date->setTimestamp($data['time']);
$data['time'] = $date;
}
return $demos;
}
public function changeDemo(int $id, string $backend, string $path, string $url, string $hash, string $key): bool {
$request = $this->client->post($this->endpoint . '/demos/' . $id . '/url', [
'form_params' => [
'hash' => $hash,
'backend' => $backend,
'url' => $url,
'path' => $path,
'key' => $key
]
]);
return $request->getStatusCode() === 200;
}
}

38
src/Migrate.php Normal file
View file

@ -0,0 +1,38 @@
<?php declare(strict_types=1);
namespace Demostf\Migrate;
class Migrate {
private $api;
private $store;
private $backend;
private $key;
public function __construct(Api $api, Store $store, string $backend, string $key) {
$this->api = $api;
$this->store = $store;
$this->backend = $backend;
$this->key = $key;
}
public function migrateDemo(array $demo): bool {
if (!$this->store->exists($demo['name'])) {
return false;
}
$hash = $this->store->hash($demo['name']);
if ($hash !== $demo['hash']) {
throw new \Exception('hash mismatch');
}
return $this->api->changeDemo(
$demo['id'],
$this->backend,
$this->store->generatePath($demo['name']),
$this->store->generateUrl($demo['name']),
$hash,
$this->key
);
}
}

33
src/Store.php Normal file
View file

@ -0,0 +1,33 @@
<?php declare(strict_types=1);
namespace Demostf\Migrate;
class Store {
private $baseDir;
private $baseUrl;
public function __construct($baseDir, $baseUrl) {
$this->baseDir = $baseDir;
$this->baseUrl = $baseUrl;
}
public function hash(string $name): string {
return md5_file($this->generatePath($name));
}
public function generatePath(string $name): string {
return $this->baseDir . $this->getPrefix($name) . $name;
}
private function getPrefix(string $name): string {
return '/' . substr($name, 0, 2) . '/' . substr($name, 2, 2) . '/';
}
public function exists(string $name): bool {
return file_exists($this->generatePath($name));
}
public function generateUrl(string $name) {
return $this->baseUrl . $this->getPrefix($name) . $name;
}
}