Convert floppy disk image files asynchronously using Greaseweazle from WordPress. This plugin exposes a REST API for conversion jobs, polling status, and downloading outputs.
- Asynchronous conversion jobs using background shell execution
- REST API endpoints for
convertandstatus - Built-in optional ClamAV scan on upload
- Support for many legacy floppy image formats
- Optional ZIP extraction workflow (
7z+zip) - Automatic repair for 720 KB Yamaha/FAT12 images with a blank or omitted first sector before ZIP extraction
- Ensoniq EPS/EPS16/ASR EFE import/export via intermediate IMG images
- Ensoniq EPS/EPS16 EDE disk-image import/export via intermediate IMG images
- Shortcodes for rendering a converter form and progress bar
- Daily cleanup of old conversion artifacts
- WordPress (current supported version)
- PHP with
exec()available - Greaseweazle CLI (
gw) installed on the server (required) 7zandzipCLI tools available for ZIP output- PHP CLI available to the web process for Yamaha/FAT12 copy-protection repair and Ensoniq EFE/EDE conversion; set the
fic_php_cli_pathfilter if needed - Standard shell tools (
find,rm,ps) clamdscan(optional, used when available)
- Copy this plugin folder into
wp-content/plugins/floppy-image-conversion-tool. - Activate Floppy Image Converter in WordPress admin.
- Ensure server paths for
gwand optionalclamdscanare valid. - Place a shortcode in a page, or call the REST API directly.
[floppy-converter-form][floppy-image-converter][progress-bar]
[floppy-converter-form] supports:
show_advanced="1"(default)show_advanced="0"
Example:
[floppy-converter-form show_advanced="0"]
Frontend note:
- This plugin provides the form markup/CSS and API endpoints.
- Wire the form submit + polling behavior from your theme/plugin JavaScript using the IDs in
templates/converter-form.php.
Namespace: floppy/v1
Starts a new conversion job.
Required fields:
file(multipart file upload)out_fmtdiskdef
Example:
curl -X POST "https://example.com/wp-json/floppy/v1/convert" \
-F "file=@/path/to/disk.img" \
-F "out_fmt=zip" \
-F "diskdef=ibm.720"Typical success response:
{
"job_id": "f7d0f8f0-13cc-4a2b-b750-2f600c1f7f57",
"download_url": "https://example.com/wp-json/floppy/v1/download?job_id=f7d0f8f0-13cc-4a2b-b750-2f600c1f7f57&out_fmt=zip&filename=disk.zip",
"download_filename": "disk.zip"
}Polls job state.
Possible status values:
processingcompleteerror
Typical processing response:
{
"status": "processing",
"message": "STEP 3/6",
"percent": 58,
"step": 3,
"step_total": 6,
"phase": "Extracting files from intermediate image"
}Typical complete response:
{
"status": "complete",
"download_url": "https://example.com/wp-json/floppy/v1/download?job_id=<job>&out_fmt=<fmt>&filename=<clean-name>.<fmt>",
"download_filename": "<clean-name>.<fmt>"
}Streams the finished conversion with a sanitized, user-facing filename via
Content-Disposition while keeping UUID-based storage paths on disk.
Typical error response:
{
"status": "error",
"message": "No files extracted from IMG (nothing to zip).",
"log_tail": ["..."]
}Input formats:
a2r, adf, ads, adm, adl, bin, ctr, d1m, d2m, d4m, d64, d71, d81, d88, dcp, dim, dmk, do, dsd, dsk, ede, edsk, efe, fd, fdi, hdm, hfe, ima, img, imd, ipf, mgt, msa, nfd, nsi, po, raw, sf7, scp, ssd, st, td0, xdf
Output formats:
- All input formats above
zip
Ensoniq EFE notes:
- Uploading an
.efefirst creates a temporary Ensoniq IMG using the selectedensoniq.800orensoniq.1600disk definition, then passes that IMG to Greaseweazle for the requested output. - When
out_fmt=efe, the selected Ensoniq image must contain exactly one exportable file. Useout_fmt=zipfor disks with multiple files. - When
out_fmt=zipanddiskdefisensoniq.800orensoniq.1600, the ZIP contains extracted.efefiles from the Ensoniq EPS/EPS16/ASR filesystem. - Other ZIP jobs continue to use the generic archive extraction path via
7z.
Ensoniq EDE notes:
- EDE is a compact Giebler EPS/EPS16 disk-image container, not a single-file EFE container.
- EDE conversion requires
diskdef=ensoniq.800; the ASR 1600K sibling format is EDA. - Older classic EDE headers such as
EPS Diskare supported in addition to newerEPS-16 Diskheaders. - Uploading
.edefirst expands it to a temporary raw Ensoniq IMG, then passes that IMG to Greaseweazle for other output formats. - When
out_fmt=ede, the intermediate IMG is compacted back to EDE after conversion.
Disk definitions:
- Includes a large built-in list (IBM, Amiga, Acorn, ZX, etc.) in
includes/config.phpviafic_allowed_diskdefs().
Override executable paths via WordPress filters:
add_filter( 'fic_greaseweazle_cli_path', function () {
return '/opt/greaseweazle/.venv/bin/gw';
} );
add_filter( 'fic_clamdscan_path', function () {
return '/usr/bin/clamdscan';
} );
add_filter( 'fic_php_cli_path', function () {
return '/usr/bin/php';
} );- Converted files/logs are stored under:
wp-content/uploads/floppy-convert/ - A cleanup cron runs daily and removes artifacts older than one week
- Job metadata is stored as a WordPress transient for one hour
- REST endpoints currently use public permission callbacks (
__return_true). - If you need restricted access, replace with an auth/capability check.
- Shell arguments are escaped and error messages are sanitized before API output.
floppy-image-converter.phpplugin bootstrap and hooksincludes/config.phpformats, diskdefs, defaultsincludes/helpers.phppath/process helpers and filtersincludes/conversion.phpupload handling and conversion pipelineincludes/status.phplog parsing and status responsesincludes/rest.phpREST route registrationincludes/frontend.phpshortcodes and template renderingincludes/cleanup.phpscheduled artifact cleanuptemplates/converter-form.phpshortcode HTML templateassets/floppy-converter.cssshortcode CSSassets/repair-copy-protected-yamaha-720k.phpcopy-protected Yamaha/FAT12 repair helperassets/create-ensoniq-img-from-efe.phpEnsoniq EFE to IMG helperassets/convert-ensoniq-ede.phpEnsoniq EDE/IMG conversion helperassets/extract-ensoniq-efe.phpEnsoniq EPS/EPS16/ASR EFE extraction helper
PHP syntax check:
php -l floppy-image-converter.php
for f in includes/*.php templates/*.php; do php -l "$f"; done