diff --git a/.gitignore b/.gitignore index 95ad31b..3d021d7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ *.swo build -config.ini +*.ini *.db bindata.go diff --git a/AUTHORS.md b/AUTHORS.md index bea1e4d..c9f40e6 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -8,3 +8,4 @@ WriteFreely is built by [Matt Baer](https://github.com/thebaer), with contributi * [Brad Koehn](https://github.com/koehn) * [kaiyou](https://github.com/kaiyou) * [Aaron Ogle](https://github.com/geekgonecrazy) +* [Norman](https://github.com/nkoehring) diff --git a/README.md b/README.md index 00778d8..bde2d7d 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,9 @@ WriteFreely is a beautifully pared-down blogging platform that's simple on the s It's designed to be flexible and share your writing widely, so it's built around plain text and can publish to the _fediverse_ via ActivityPub. It's easy to install and light enough to run on a Raspberry Pi. -**[Start a blog on our instance](https://write.as/new/blog/federated)** - [Try the editor](https://write.as/new) -[Find another instance](https://writefreely.org/instances) +[Find an instance](https://writefreely.org/instances) ## Features @@ -42,6 +40,18 @@ It's designed to be flexible and share your writing widely, so it's built around * Build more advanced apps and extensions with the [well-documented API](https://developers.write.as/docs/api/) * Designed around user privacy and consent +## Hosting + +We offer two kinds of hosting services that make WriteFreely deployment painless: [Write.as](https://write.as) for individuals, and [WriteFreely.host](https://writefreely.host) for communities. Besides saving you time, as a customer you directly help fund WriteFreely development. + +### [![Write.as](https://write.as/img/writeas-wf-readme.png)](https://write.as/) + +Start a personal blog on [Write.as](https://write.as), our flagship instance. Built to eliminate setup friction and preserve your privacy, Write.as helps you start a blog in seconds. It supports custom domains (with SSL) and multiple blogs / pen names per account. [Read more here](https://write.as/pricing). + +### [![WriteFreely.host](https://writefreely.host/img/wfhost-wf-readme.png)](https://writefreely.host) + +[WriteFreely.host](https://writefreely.host) makes it easy to start a close-knit community — to share knowledge, complement your Mastodon instance, or publish updates in your organization. We take care of the hosting, upgrades, backups, and maintenance so you can focus on writing. + ## Quick start WriteFreely has minimal requirements to get up and running — you only need to be able to run an executable. @@ -59,7 +69,7 @@ Now extract the files from the archive, change into the directory, and do the fo # 2) (if you chose MySQL in the previous step) Log into MySQL and run: # CREATE DATABASE writefreely; -# 3) Import the schema with: +# 3) (if you chose Multi-user setup) Import the schema with: ./writefreely --init-db # 4) Generate data encryption keys diff --git a/app.go b/app.go index 192628b..202b3e8 100644 --- a/app.go +++ b/app.go @@ -54,7 +54,7 @@ var ( debugging bool // Software version can be set from git env using -ldflags - softwareVer = "0.7.1" + softwareVer = "0.8.0" // DEPRECATED VARS // TODO: pass app.cfg into GetCollection* calls so we can get these values @@ -618,5 +618,15 @@ func adminInitDatabase(app *app) { log.Info("Created.") } } + + // Set up migrations table + log.Info("Updating appmigrations table...") + err = migrations.SetInitialMigrations(migrations.NewDatastore(app.db.DB, app.db.driverName)) + if err != nil { + log.Error("Unable to set initial migrations: %v", err) + os.Exit(1) + } + log.Info("Done.") + os.Exit(0) } diff --git a/less/fonts.less b/less/fonts.less index fd01dd4..7ee5356 100644 --- a/less/fonts.less +++ b/less/fonts.less @@ -3,6 +3,7 @@ font-family: 'Open Sans'; font-style: normal; font-weight: 400; + font-display: optional; src: url('/fonts/open-sans-v13-latin-regular.eot'); /* IE9 Compat Modes */ src: local('Open Sans'), local('OpenSans'), url('/fonts/open-sans-v13-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ @@ -16,6 +17,7 @@ font-family: 'Open Sans'; font-style: normal; font-weight: 700; + font-display: optional; src: url('/fonts/open-sans-v13-latin-700.eot'); /* IE9 Compat Modes */ src: local('Open Sans Bold'), local('OpenSans-Bold'), url('/fonts/open-sans-v13-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ @@ -29,6 +31,7 @@ font-family: 'Lora'; font-style: normal; font-weight: 400; + font-display: optional; src: url('/fonts/Lora-Regular.eot'); /* IE9 Compat Modes */ src: local('Lora'), local('Lora-Regular'), url('/fonts/Lora-Regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ @@ -41,6 +44,7 @@ font-family: 'Lora'; font-style: normal; font-weight: 700; + font-display: optional; src: url('/fonts/Lora-Bold.eot'); /* IE9 Compat Modes */ src: local('Lora Bold'), local('Lora-Bold'), url('/fonts/Lora-Bold.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ @@ -49,13 +53,14 @@ url('/fonts/Lora-Bold.ttf') format('truetype'); /* Safari, Android, iOS */ } @font-face { - font-family: 'Lora'; - font-style: italic; - font-weight: 400; - src: url('/fonts/Lora-Italic.eot'); /* IE9 Compat Modes */ - src: local('Lora Italic'), local('Lora-Italic'), - url('/fonts/Lora-Italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ - url('/fonts/Lora-Italic.woff2') format('woff2'), /* Super Modern Browsers */ - url('/fonts/Lora-Italic.woff') format('woff'), /* Modern Browsers */ - url('/fonts/Lora-Italic.ttf') format('truetype'); /* Safari, Android, iOS */ + font-family: 'Lora'; + font-style: italic; + font-weight: 400; + font-display: optional; + src: url('/fonts/Lora-Italic.eot'); /* IE9 Compat Modes */ + src: local('Lora Italic'), local('Lora-Italic'), + url('/fonts/Lora-Italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('/fonts/Lora-Italic.woff2') format('woff2'), /* Super Modern Browsers */ + url('/fonts/Lora-Italic.woff') format('woff'), /* Modern Browsers */ + url('/fonts/Lora-Italic.ttf') format('truetype'); /* Safari, Android, iOS */ } diff --git a/migrations/migrations.go b/migrations/migrations.go index 2aa3643..1d6e0c4 100644 --- a/migrations/migrations.go +++ b/migrations/migrations.go @@ -58,6 +58,19 @@ var migrations = []Migration{ New("support user invites", supportUserInvites), // -> V1 (v0.8.0) } +// CurrentVer returns the current migration version the application is on +func CurrentVer() int { + return len(migrations) +} + +func SetInitialMigrations(db *datastore) error { + _, err := db.Exec("INSERT INTO appmigrations (version, migrated, result) VALUES (?, "+db.now()+", ?)", CurrentVer(), "") + if err != nil { + return err + } + return nil +} + func Migrate(db *datastore) error { var version int var err error diff --git a/schema.sql b/schema.sql index 6687f5d..b3fae97 100644 --- a/schema.sql +++ b/schema.sql @@ -34,6 +34,18 @@ CREATE TABLE IF NOT EXISTS `appcontent` ( -- -------------------------------------------------------- +-- +-- Table structure for table `appmigrations` +-- + +CREATE TABLE `appmigrations` ( + `version` int(11) NOT NULL, + `migrated` datetime NOT NULL, + `result` text NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + -- -- Table structure for table `collectionattributes` -- diff --git a/sqlite.sql b/sqlite.sql index 6c7160a..90989ed 100644 --- a/sqlite.sql +++ b/sqlite.sql @@ -32,6 +32,18 @@ CREATE TABLE IF NOT EXISTS `appcontent` ( -- -------------------------------------------------------- +-- +-- Table structure for table appmigrations +-- + +CREATE TABLE `appmigrations` ( + `version` INT NOT NULL, + `migrated` DATETIME NOT NULL, + `result` TEXT NOT NULL +); + +-- -------------------------------------------------------- + -- -- Table structure for table collectionattributes --