Migration from WordPress to Second Crack

The first step in migrating from WordPress to Second Crack was to move all the posts from the WordPress database to .md files on disk. This can be a cumbersome task and I have not found a good way to do this.
The process I followed was manually going from post to post and converting it to MarkDown. You can use your favourite search engine to find a convertor that fits you, I used a javascript solution I was able to use inside my webbrowser. The blog I migrated
from did not have any pages, so there was no need for me to migrate those.

Posts

Using the query below I fetched the posts from the database (where wp_ is the WordPress table prefix for your tables), this returns all posts and drafts present in the WordPress database, ignoring all revisions:

SELECT post_date, post_name, post_content, post_status, guid FROM wp_posts WHERE post_type = 'post';

Permalinks

After you have completed the migration of the posts, the hard part is done. What remains now is to handle the permalinks that have changed in the migration. My blog used to run on an Apache server with the mod_rewrite module on to make prettier URLs possible.
Unfortunately the permalink structure of Second Crack is fixed. If someone had bookmarked or links to one of my old blog URLs that would have ended up in an ugly 404 Not Found page. In order to solve this problem I created a custom 404 page with URL detection.

Configurating a custom HTML page when a page cannot be found is easy on both Apache and nginx.

#Apache (this is already in the .htaccess provided by Second Crack):
ErrorDocument /404.html

#nginx:
errorpage /404.html

In the www folder to the blog I created a 404.html document with the same template as the other blog pages. The blog contents is replaced with a simple statement that the Requested document could not be found.

Now if someone visited an old URL they would at least see a pretty error page. But because of the static structure of the posts I saw a possibility to redirect the user to the correct page in the new structure.
I started with the permalinks and issued the following SQL query to get the permalinks and convert those to the Second Crack post structure. Keep in mind that the WordPress permalinks end with a / and the Second Crack permalinks do not.

SELECT CONCAT(CONCAT(DATE_FORMAT(post_date, '%Y/%m/'), post_name), '/'), CONCAT(DATE_FORMAT(post_date, '%Y/%m/%d'), post_name) FROM wpdg_posts WHERE post_status = 'publish' AND post_type='post';

Javascript solution

These permalinks are used in a piece of javascript which attempts to determine whether the not found URL is an old permalink:

var oldWordpressPermalinks = new Array(
        new Array('/2012/11/unfreezing-putty-after-pressing-ctrls/','/2012/11/01/unfreezing-putty-after-pressing-ctrls'),
        new Array('/2012/11/installing-mpd-on-windows/','/2012/11/16/installing-mpd-on-windows'),
        new Array('/2012/11/decrease-video-file-size-using-ffmpeg/','/2012/11/19/decrease-video-file-size-using-ffmpeg'),
        ...
);

for( iter = 0; iter < oldWordpressPermalinks.length - 1; iter++) {
    if( oldWordpressPermalinks[iter][0] == path ) { 
        window.location.href = 'http://' + window.location.hostname + oldWordpressPermalinks[iter][1];
        break;
    }
}

You can see it for yourself, just visit a non-existing page on this blog.

Category and tag links in WordPress can be processed in a similar matter. Second Crack does not support categories, so here the assumption is made that there is a tagname for the category. There is also no check whether the tag where is being redirected to actual exists.

//check for URLs of the format/category/howto/page/2 (the page/2 part is optional)
var catPatt = /^\/category\/([a-zA-Z0-9]+)\//;
catRes = catPatt.exec(path);
if( catRes ) { //match
    window.location.href = 'http://' + window.location.hostname + '/tagged-' + catRes[1] + '.html';
}

//check for /tag/mantisbt
var tagPatt = /^\/tag\/([a-zA-Z0-9]+)$/;
tagRes = tagPatt.exec(path);
if( tagRes ) { //match
    window.location.href = 'http://' + window.location.hostname + '/tagged-' + tagRes[1] + '.html';
}

There are some other WordPress URLs currently not covered, such as /2013/01 but that was more complicated, since there are also physical folders on disk with the same name.

RSS Feed

Last item on the list for the migration is the RSS feed. In my WordPress configuration the feed was located on /feed/. I have configured my nginx webserver to permanently redirect to /rss.xml, the RSS location Second Crack.

#Apache:
Redirect 301 /feed/ /rss.xml

#nginx:
rewrite ^/feed/$ /rss.xml permanent;

Place this in your nginx server block and all subscribers to your old blog will still be able to access the new feed.

Leave a Comment

Running Second Crack on a Windows computer

This blog is hosted on a Linux server, but I generate the blog on my Windows laptop. Some small changes are required in order to get it to work on Windows. The readme.md on the Second Crack is very elaborate in the installation notes. This blogpost only describes the changes I had to make to get it to work on Windows.

Installation

I have installed Second Crack in a separate folder, in C:\apps\secondcrack. The source files are placed in _C:\blog_, in the following structure:

\cache
\drafts
\media
\pages
\posts
\templates
\www
    \css
    \js
    \img

The config.php in the Second Crack folder I have changed to reflect this structure.

Code change

The update.php script in the Second Crack engine folder which triggers the blog update must be changed. A locking mechanism has been implemented in this file, but it does not work under Windows because the used PHP extension (POSIX) is not available.
Thefore the lines in update.php related to locking must be commented out. This is the following snippet as an example:

update.php
<?php
/*define('LOCK_FILE', isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '/tmp/secondcrack-updater.pid');

// Ensure that no other instances are running
...
    fwrite(STDERR, "Cannot write lock file: " . LOCK_FILE . "\n");
    exit(1);
}*/

$fdir = dirname(__FILE__);

This will disable all functionality related to locking. Now updating the blog is a matter of executing (assuming the php.exe is installed in c:\php\php.exe:

c:\php\php.exe c:\apps\secondcrack\engine\update.php

Leave a Comment

Blog migration to Second Crack

The last weeks I have been migrating the blogging engine of this site to Second Crack. This is blog engine in PHP which generates static files as output. This means that no database is required to have this blog running.

The choice to migrate the blog engine was made after I had migrated the blog from a VPS to a Raspberry Pi which I have running at home. The available resources was limited and I needed a way to make all sites running on the system as light-weight as possible (if you are interested, the RPi itself is running on the arkOS distribution.

In the migration from WordPress to Second Crack I had to take some hurdles in order to get it working the way I liked it. The coming weeks I will be publishing some posts on the different subjects, for example: running Second Crack on Windows, migration WordPress permalinks, configuration on Nginx.

This post will be updated with links to the different posts. Last update: January 11th 2014.

  1. Second Crack on Windows
  2. Migration from WordPress to Second Crack
  3. Second Crack on nginx
  4. Second Crack template changes

Leave a Comment

VLC fullscreen on external display

I was looking for a way to set up VLC to always start the video fullscreen on the second external monitor. I have found some ways to do this online, in two different approaches: via a batch file and via VLC settings.

Batch file

Create a batch file with the following contents:

set vlcPath="C:\\Program Files\\VideoLAN\\VLC\\vlc.exe"
%vlcPath% %1 --video-x=1600 --video-y=400 --fullscreen --no-video-title-show --no-embedded-video --no-qt-fs-controller

Replace the values vlcPath with the exact path to your VLC installation. Also, replace video-x and video-y with the x and y values on which your second monitor is positioned. You can play a video by dragging / dropping a video file onto the batch file.

Via VLC settings

You can also set these options directly via the settings. This means that all video’s played via VLC on that computer use these settings.

  1. Open the preferences dialog (Tools –> Preferences)
  2. In the interface tab, choose Native, and un-tick “Embed video in interface” (this enables the controls to be separated from the video)
  3. Choose “All” in the “Show settings” box at the bottom left of the preferences window
  4. Choose the video options from the left
  5. Tick Fullscreen video output
  6. Scroll down and set an X and Y position that are on the second monitor – so set an X position larger then the width of the first screen. The value of the Y coordinate doesn’t matter much, but mustn’t be negative otherwise both values will be ignored.
  7. Save the settings

Leave a Comment

Create simple project using Maven

Maven supports a simple mechanism to generate a project with the required structure and files already in place. Simply execute the command below:

mvn archetype:generate -DgroupId=com.test -DartifactId=mytest

Replace com.test and mytest with your preferred name and package for your project.

The maven documentation page contains a short list of the most common archtetypes. When you enter the command an interactive console will start from which you can select the preferred archetype to start with. You must enter the number of the archetype or you can specify a filter by packagename to shorten the list of options.

Leave a Comment

setuid bit not set on sudo

I encountered the following message when attempting to execute a sudo command on a freshly installed system:

[webdevelop@arkos01 ~]$ sudo su -
sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set

To fix this, I had to login as root via SSH (by setting the sshd config value PermitRootLogin to yes) and execute the following command:

chmod u+s /usr/bin/sudo

Leave a Comment

MantisTouch login not working after LDAP switch

Ran into the problem that MantisTouch was not working. This was after a recent upgrade of the Mantis bugtracking system to use LDAP for authentication. Every login attempt would fail without further details other than that the username/password is incorrect. After some analysis found the cause: the config parameter _$g_log_level_ was set to _LOG_LDAP_. Somehow the log command resulted in an error:

[mantisconnect.php] Error Type: SYSTEM NOTICE,\nError Description: Undefined offset: 1
Stack Trace:ldap_api.php L349 log_event(<integer>16, <string>'Binding to LDAP server')

Disabling the debug log fixed the issue. Read on for the steps taken in the analysis.

Analysis

  1. In the Mantis touch files:
  2. Checked the file login_page.php for the cause of the log message. This page turned out to be only the displaying.
  3. login.php was the file which did the actual login attempt, invoking the WebService class from core/webservice_api.php
  4. Noticed that Mantis uses soap for the remote procedure calls
  5. Some debug echo statements in that file showed that the username and password arrived correctly just before invoking the soap webservice
  6. Found the URL to the soap interface in the WebService constructor PHPDoc (/api/soap/mantisconnect.php)
  7. Stored the WSDL from the URL and loaded it into SoapUI
  8. Executed the same API call from SoapUI as mantistouch does: _mc_enum_status_. Found this in the authenticate() call in _webservice_api.php_ which is invoked from login.php
  9. The response in SoapUI return a SoapFault with the message: Error Type: SYSTEM NOTICE, Error Description: Undefined offset: 1
  10. On checking the Apache logs of the mantis installing found that there was a notice there, related to _core/ldap_api.php_
  11. Added some debug statements to see which lines the script reached before the error and it turned out that it did not get any further than the log line mentioned in the stack trace
  12. Disabled the $_log_level parameter and this resolved the error!
  13. Further investigation showed a configuration error made during the implementation checks of the LDAP authentication. The file path mentioned in the _$g_log_destination_ parameter was incorrect, it was missing a directory name somewhere halfway the path. The strange thing is that this only affected the mantisconnect part, not the normal user interface.

Leave a Comment