{"id":21091349,"url":"https://github.com/andreasscherbaum/s9y-to-hugo","last_synced_at":"2025-10-07T23:17:42.784Z","repository":{"id":209087162,"uuid":"666577239","full_name":"andreasscherbaum/s9y-to-hugo","owner":"andreasscherbaum","description":"Transform S9y blog into Hugo Markdown pages","archived":false,"fork":false,"pushed_at":"2023-11-25T00:52:17.000Z","size":34,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-08T15:54:24.405Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andreasscherbaum.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-07-14T22:20:24.000Z","updated_at":"2023-11-25T00:09:51.000Z","dependencies_parsed_at":"2023-11-25T01:25:49.386Z","dependency_job_id":"7c955fcf-ffa9-4308-84c0-b24fd2da66fb","html_url":"https://github.com/andreasscherbaum/s9y-to-hugo","commit_stats":null,"previous_names":["andreasscherbaum/s9y-to-hugo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/andreasscherbaum/s9y-to-hugo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreasscherbaum%2Fs9y-to-hugo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreasscherbaum%2Fs9y-to-hugo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreasscherbaum%2Fs9y-to-hugo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreasscherbaum%2Fs9y-to-hugo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andreasscherbaum","download_url":"https://codeload.github.com/andreasscherbaum/s9y-to-hugo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreasscherbaum%2Fs9y-to-hugo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278861070,"owners_count":26058638,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T21:45:16.205Z","updated_at":"2025-10-07T23:17:42.736Z","avatar_url":"https://github.com/andreasscherbaum.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# s9y-to-hugo\n\nTransform S9y blog into Hugo Markdown pages\n\n## Description\n\nThis script migrates a [Serendipity](https://s9y.org/) blog into Markdown pages for the [Hugo](https://gohugo.io/) static blogging engine.\n\n## Requirements\n\n* Local Hugo installation\n* S9y database export\n* Images from the S9y blog\n* Initialized Hugo blog\n* Python packages from [requirements.txt](requirements.txt)\n\nA Python [virtualenv](https://docs.python.org/3/library/venv.html) can be created using the `make virtualenv` [Makefile](Makefile) target.\n\n## Preparation\n\n[Initialize](https://gohugo.io/getting-started/quick-start/) a [new Hugo site](https://gohugo.io/commands/hugo_new_site/).\n\nUse the new site as `targetdir` for the migration. Make sure a Hugo configfile (`hugo.yaml|json|toml)`) exists.\n\nMake sure the [archetypes](https://gohugo.io/content-management/archetypes/) match what you expect for the new content. The migration will run `hugo new` ([documentation(https://gohugo.io/commands/hugo_new/)]) for each migrated blog posting.\n\nMake sure the [taxonomies](https://gohugo.io/content-management/taxonomies/) are set. The migration script will use `categories`, `tags` and `authors`.\n\nMake sure that `hugo new` creates an empty posting with all the details you need in there.\n\n## Usage and commandline options\n\nThe script requires a couple of mandatory options, and has additional optional options which allow for moving the blog, or allow debugging the migration process.\n\n```\n./s9y-to-hugo.py \u003coptions\u003e\n```\n\nOr:\n\n```\n. ./virtualenv/bin/activate \u0026\u0026 ./s9y-to-hugo.py \u003coptions\u003e\n```\n\n### Commandline options\n\n* `--help`: Shows a list of available options\n* `-v`, `--verbose`: Show more verbose messages\n* `-q`, `--quiet`: Only show error messages, no informational messages\n* `--dbtype`: Select the type of source database (pg, mysql), currently only `pg` is supported\n* `--dbhost`: Database host\n* `--dbuser`: Database connection user\n* `--dbpass`: Database connection password\n* `--dbname`: Database name\n* `--dbport`: Database port (defaults to 5432 for PostgreSQL, 3306 for MySQL)\n* `--dbprefix`: Database table prefix (S9y allows hosting multiple blogs in the same database, [see documentation](https://docs.s9y.org/docs/users/using/configuration.html))\n* `--webprefix`: The URL path prefix for the new blog, default to `/` (make sure your template supports subdirectories)\n* `--oldwebprefix`: The URL path prefix of the old blog, default to `/` (migration to a new path is possible)\n* `--targetdir`: The directory where your new Hugo blog resides locally\n* `--imagedir`: The directory where images from the old blog are available for migration (must match path in blog postings)\n* `--rewritefile`: The rewrite file which will have redirects from old to new URLs\n* `--rewritetype`: Rewrite file type (webserver type), currently only `apache2` is supported\n* `--rewritejson`: A file which is populated with the redirect information (useful for updating the migrated posts)\n* `--httpsexitlist`: A file which contains hostnames which will be upgraded to https when writing exit link redirects\n* `--use-bundles`: Use [Hugp Page Bundles](https://gohugo.io/content-management/page-bundles/) instead of a flat file structure\n* `--remove-s9y-id`: Remove the S9y ID from the URL\n* `--add-date-to-url`: Prefix the URL and the local file/directory with the ISO date of the posting\n* `--ignore-post`: Do not migrate this posting, can be specified multiple times (use the relative URL from the S9y blog as parameter)\n* `--ignore-picture-errors`: Ignore missing local picture errors in this posting (otherwise migration is aborted), can be specified multiple times\n* `--use-utc`: Use UTC time instead of local time\n* `--write-html`: Write a copy of the original HTML to a `.html` file\n* `--archive-link`: Use this link for archive redirects (othewise `webprefix` is used)\n* `--add-year-link-to-archive`: Adds redirects to a specific year (where applicable) for the archive links\n* `--hugo-bin`: Use this binary as Hugo binary (otherwise auto-detected)\n\n## Post Migration\n\nAfter the migration, search the new blog postings for potential problems.\n\n### TextReplaced\n\n```\nfind \u003ctargetdir\u003e/content/post/ -type f -name \"*.md\" -print0 | xargs -0 grep \"TextReplaced\"\n```\n\nText for images was replaced, verify that everything looks alright.\n\nIf in doubt, use the `--write-html` option to create an additional file with the original HTML content.\n\n### PictureMissing\n\nA local picture is missing in the migrated blog posting. The `--ignore-picture-errors` option was used for this blog post.\n\n### UnsupportedTags\n\nOld and unsupported HTML flags have been found. S9y started off when HTML version 4 was still around. Very old blogs might contain unsupported HTML tags.\n\nThis affects old `\u003cstrike\u003e` tags, which have been replaced with `\u003cdel\u003e` during the migration.\n\nIt also affects `\u003cs\u003e` tags (recognized by the Markdown parser) and `\u003cu\u003e` tags (not recognized).\n\nConsider using the `--write-html` option to write out the HTML into a file.\n\n### CATEGORIESSKIPPED\n\nOne or more categories have not been migrated. This should only affect a root category from a category tree, but please check the details.\n\n### s9yID\n\nThe migration tool writes the original database ID for the posting into the `s9yID` Frontmatter tag.\n\n### OriginalLink\n\nThe migration tool writes the original blog posting URL into the `OriginalLink` Frontmatter tag.\n\n### QuotesChanged\n\nSome quotes have been changed, to remove unnecessary backslashes, or add necessary backslashes.\n\n## Comments\n\nCurrently, comments are not migrated.\n\nS9y supports a comment tree (comments answering comments). That's not something which can be easily shown in Markdown.\n\nPatches welcome, if you have an idea how to solve this.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreasscherbaum%2Fs9y-to-hugo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreasscherbaum%2Fs9y-to-hugo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreasscherbaum%2Fs9y-to-hugo/lists"}