Backend for songs.zachdecook.com
* Database: Allow songs to be imported from a textfile
Zach DeCook 2018-12-26
parent 97e82af · commit 83b5a59
-rw-r--r--laravel/app/Console/Commands/AddSongs.php91
-rw-r--r--laravel/app/Song.php11
-rw-r--r--laravel/database/migrations/2018_12_26_145136_create_songs_table.php10
3 files changed, 107 insertions, 5 deletions
diff --git a/laravel/app/Console/Commands/AddSongs.php b/laravel/app/Console/Commands/AddSongs.php
new file mode 100644
index 0000000..94cf3c0
--- /dev/null
+++ b/laravel/app/Console/Commands/AddSongs.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Song;
+use Illuminate\Console\Command;
+
+class AddSongs extends Command
+{
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'prosongsa:import {file}';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Import songs from an inputfile.';
+
+ /**
+ * Create a new command instance.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
+ public function handle()
+ {
+ define( 'AUTHOR_REGEX', "/^-(([A-Za-z.]+ ?)+)/" );
+ $filename = $this->argument('file');
+ $handle = fopen($filename, "r");
+
+ $theSong = [
+ 'text' => '',
+ 'verse' => '',
+ 'number' => FALSE,
+ ];
+
+ if ( !$handle ){
+ $this->error("Couldn't read file '$filename'");
+ return 1;
+ }
+ while (($line = fgets($handle)) !== false)
+ {
+ // If we see a number, then that is what song we are on.
+ $matches = array();
+ if ( preg_match("(^(X?C?B?\d+)\. )", $line, $matches) )
+ {
+ if ( $theSong['text'] && $theSong['number'] && $theSong['title']
+ && ( $theSong['number'] != $matches[1] ) ) {
+ Song::create( $theSong );
+ $this->line( "Created $theSong[title]" );
+ $theSong = [
+ 'text' => '',
+ 'verse' => '',
+ 'key' => NULL,
+ 'author' => NULL,
+ ];
+ }
+ $theSong['number'] = $matches[1];
+ $theSong['title'] = trim($line);
+ $this->line( "Creating $theSong[title]..." );
+ }
+
+ $theSong['text'] .= $line;
+
+ if ( preg_match( "/\{p?\d*\((.+m?)\)\}/", $line, $matches)
+ || preg_match("/^{Key: ?([^ ]*).*}/i", $line, $matches)
+ ) {
+ $theSong['key'] = $matches[1];
+ }
+ if ( preg_match( AUTHOR_REGEX, $line, $matches ) ) {
+ $theSong['author'] = $matches[1];
+ }
+ }
+ fclose($handle);
+ Song::create( $theSong );
+ }
+}
diff --git a/laravel/app/Song.php b/laravel/app/Song.php
new file mode 100644
index 0000000..876617f
--- /dev/null
+++ b/laravel/app/Song.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Song extends Model
+{
+ public $fillable = ['number', 'title', 'author', 'key', 'text'];
+ //
+}
diff --git a/laravel/database/migrations/2018_12_26_145136_create_songs_table.php b/laravel/database/migrations/2018_12_26_145136_create_songs_table.php
index 7208806..0fbee13 100644
--- a/laravel/database/migrations/2018_12_26_145136_create_songs_table.php
+++ b/laravel/database/migrations/2018_12_26_145136_create_songs_table.php
@@ -15,11 +15,11 @@ class CreateSongsTable extends Migration
{
Schema::create('songs', function (Blueprint $table) {
$table->increments('id');
- $table->string('number', 5);
- $table->string('title');
- $table->string('author');
- $table->string('verse');
- $table->string('key', 5);
+ $table->string('number', 5)->unique();
+ $table->string('title', 191)->default('');
+ $table->string('author', 191)->nullable();
+ $table->string('verse', 191)->nullable();
+ $table->string('key', 5)->nullable();
$table->text('text');
$table->timestamps();
});