Last active
August 29, 2015 14:00
-
-
Save eexit/774b49a2d6f1e49430a2 to your computer and use it in GitHub Desktop.
This file a Wordpress to Ghost image importer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
This file a Wordpress to Ghost image importer. | |
Before you run this script, you must have done the following: | |
1. Import your blog content in Ghost with Markdown syntax (very important). | |
I used ExitWP (https://github.com/thomasf/exitwp) then | |
replaced all my Ghost data by its equivalent in Markdown | |
2. Export your Ghost database (yourblogurl/ghost/debug) | |
3. Configure this script (see variables below) | |
4. Run this script in console (needs PHP >= 5.3) | |
5. Re-generate a ghost.db file (backup your old one first) by | |
deleting it and restarting the app | |
6. Import your updated Ghost database (generated by this script) | |
7. Move all your pictures into your Ghost installation picture directory | |
*/ | |
// Your WP domain + content path | |
$uploadPath = 'blog.eexit.net/wp-content/uploads/'; | |
// Your exported Ghost DB path | |
$ghostFile = __DIR__ . '/GhostData.json'; | |
// The path where you want the images to be downloaded (as a temp dir) | |
$downloadDir = __DIR__ . '/images/'; | |
/* | |
---------------------------------------------------------------- | |
DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING | |
---------------------------------------------------------------- | |
*/ | |
ini_set('html_errors', false); | |
header('Content-Type: text/plain'); | |
$updatedGhost = __DIR__ . '/GhostDataUpdated.json'; | |
$sanitize = function($dirty) { | |
return preg_replace('/([\.\/])/', '\\\$1', $dirty); | |
}; | |
$jsonValidator = function($jsonFilePath) { | |
if (!json_decode(file_get_contents($jsonFilePath))) { | |
$jsonErrors = array( | |
0 => 'JSON_ERROR_NONE', | |
1 => 'JSON_ERROR_DEPTH', | |
2 => 'JSON_ERROR_STATE_MISMATCH', | |
3 => 'JSON_ERROR_CTRL_CHAR', | |
4 => 'JSON_ERROR_SYNTAX', | |
5 => 'JSON_ERROR_UTF8' | |
); | |
throw new InvalidArgumentException(sprintf('JSON error (code %s) for file "%s": %s', | |
json_last_error(), | |
$jsonFilePath, | |
$jsonErrors[json_last_error()] | |
)); | |
} | |
}; | |
$pathBuilder = function ($dateVal, $stripDownloadDir = false) use ($downloadDir) { | |
$dateVal = explode('/', $dateVal); | |
$datetime = new DateTime(); | |
$datetime->setDate($dateVal[0], $dateVal[1], 1); | |
if ($stripDownloadDir) { | |
return sprintf('%s%s', | |
$datetime->format(sprintf('Y%sM', DIRECTORY_SEPARATOR)), | |
DIRECTORY_SEPARATOR | |
); | |
} | |
return sprintf('%s%s%s', | |
$downloadDir, | |
$datetime->format(sprintf('Y%sM', DIRECTORY_SEPARATOR)), | |
DIRECTORY_SEPARATOR | |
); | |
}; | |
try { | |
$ghostDb = file_get_contents($ghostFile); | |
if (!is_writable(__DIR__)) { | |
throw new InvalidArgumentException(sprintf( | |
'Cannot write current directory "%s". Please check permissions.', | |
__DIR__ | |
)); | |
} | |
if (!is_readable($ghostFile)) { | |
throw new InvalidArgumentException(sprintf( | |
'Cannot read Ghost DB file "%s". Please check permissions.', | |
$ghostFile | |
)); | |
} | |
$jsonValidator($ghostFile); | |
if (!is_writable($downloadDir)) { | |
throw new InvalidArgumentException(sprintf( | |
'Download directory is not writtable: %s', | |
$downloadDir | |
)); | |
} | |
$uploadPath = $sanitize($uploadPath); | |
$pattern = sprintf('/\(((https?:\/\/%s(\d{4}\/\d{2}))\/([^)]*))\)/', $uploadPath); | |
$count = preg_match_all($pattern, $ghostDb, $matches); | |
echo <<< EOT | |
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | |
|W|P|2|G|h|o|s|t| |i|m|a|g|e| |i|m|p|o|r|t|e|r| | |
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | |
There are $count URLs found: | |
EOT; | |
foreach ($matches[1] as $key => $url) { | |
$targetDir = $pathBuilder($matches[3][$key]); | |
$targetFile = sprintf('%s%s', $targetDir, basename($url)); | |
$fileRelPath = sprintf('/content/images/%s', | |
$pathBuilder($matches[3][$key], true) | |
); | |
// Replaces Windows directory separator by slashes | |
$fileRelPath = str_replace(DIRECTORY_SEPARATOR, '/', $fileRelPath); | |
// Adds the file to the picture relative path | |
$fileRelPath .= $matches[4][$key]; | |
if (!is_dir($targetDir)) { | |
if (!mkdir($targetDir, 0777, true)) { | |
throw new RuntimeException(sprintf( | |
'Unable to create directory: %s', | |
$targetDir | |
)); | |
} | |
} | |
if (!$fileContent = file_get_contents($url)) { | |
throw new InvalidArgumentException(sprintf( | |
'Unable to download: %s', $url | |
)); | |
} | |
if (!file_put_contents($targetFile, $fileContent)) { | |
throw new RuntimeException(sprintf( | |
'Unable to write the file "%s". Check your permissions!', | |
$targetFile | |
)); | |
} | |
// Replaces the file URL by the relative path in the DB file | |
$ghostDb = str_replace($url, $fileRelPath, $ghostDb); | |
echo sprintf('[ %s/%s ] %s%s', ($key + 1), $count, $targetFile, PHP_EOL); | |
} | |
// Save the new DB | |
if (!file_put_contents($updatedGhost, $ghostDb)) { | |
throw new RuntimeException(sprintf( | |
'Unable to create the updated Ghost DB file "%s"', | |
$updatedGhost | |
)); | |
} | |
// Validates the format of the new DB | |
$jsonValidator($updatedGhost); | |
echo <<< EOT | |
Importing done. | |
Your new Ghost database is: $updatedGhost. | |
All your pictures have been downloaded in: $downloadDir. | |
You must move them into your Ghost instance directory, beware of file permissions. | |
Example: | |
Ghost/content/images | |
└── 2014 | |
├── Apr | |
└── May | |
Script written by Joris Berthelot <admin@eexit.net> | |
http://github.com/eexit | |
EOT; | |
} catch (Exception $e) { | |
echo <<< EOT | |
Oops! Something went wrong. | |
You should carefully read the following error and fix whatever it says. | |
Before relaunching the script, please consider: | |
- delete everyhing in: $downloadDir | |
- delete the new DB (if created): $updatedGhost | |
Error message: {$e->getMessage()} | |
EOT; | |
exit(1); | |
} | |
exit(0); | |
/* | |
Copyright (c) 2014 Joris Berthelot <admin@eexit.net> | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files (the "Software"), to deal | |
in the Software without restriction, including without limitation the rights | |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
copies of the Software, and to permit persons to whom the Software is | |
furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in | |
all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
THE SOFTWARE. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment