460077714dee15db558f13621cb795d4d1c739b1
[catagits/App-IdiotBox.git] / lib / App / IdiotBox / Importer.pm
1 package App::IdiotBox::Importer;
2
3 use strict;
4 use warnings FATAL => 'all';
5 use App::IdiotBox::Common qw(@SupportedFormats);
6 use Cwd;
7 use IO::All;
8 use ExtUtils::MakeMaker qw(prompt);
9 use File::Spec::Functions qw(catfile catdir);
10 use POSIX qw(strftime);
11
12 my $supported_formats_re = join('|', @SupportedFormats);
13
14 sub log_info (&) { print $_[0]->(), "\n"; }
15
16 sub run {
17   my ($class, $ib) = @_;
18   my @buckets = $ib->buckets->flatten;
19   my %bucket_by_slug;
20   log_info { "Available buckets to import into:" };
21
22   my $bucket;
23     
24   BUCKETS: {
25     foreach my $idx (0 .. $#buckets) {
26       my $bucket = $buckets[$idx];
27       $bucket_by_slug{$bucket->slug} = $bucket;
28       log_info { "(${idx}) ${\$bucket->slug} : ${\$bucket->name}" };
29     }
30     log_info { sprintf("(%d) new : Create new bucket\n", $#buckets + 1) };
31
32     CHOOSE: {
33       my $choice = prompt("Which bucket to import into (by number or slug) ?");
34       if ($choice =~ /^\d+$/) {
35         $bucket = $buckets[$choice];
36       } else {
37         $bucket = $bucket_by_slug{$choice};
38       }
39
40       if (!$bucket && ($choice eq 'new' || $choice eq $#buckets + 1)) {
41         my $sn = prompt("What's the new short name (url path) for the slug ?");
42         my $ln = prompt("What's the new long name (description) for the slug ?");
43
44         $sn =~ s/ /-/g;
45
46         my $nb = $ib->buckets->add(bless({
47           slug => $sn,
48           name => $ln,
49         }, 'App::IdiotBox::Bucket'));
50
51         log_info { "Created new bucket" };
52         push @buckets, $nb;
53         redo BUCKETS;
54       }
55
56       unless ($bucket) {
57         log_info {
58            "No bucket for ${choice} - valid options are 0 to ${\$#buckets + 1}"
59            ." or slug (e.g. ${\$buckets[0]->slug})"
60          };
61          redo CHOOSE;
62       }
63     }
64   }
65   my $ann = $ib->recent_announcements->add(bless({
66     bucket => $bucket,
67     made_at => strftime("%Y-%m-%d %H:%M:%S",localtime),
68   }, 'App::IdiotBox::Announcement'));
69
70   log_info { "Created new announcement, id ".$ann->id };
71
72   my $video_files = $class->video_files_from_dir(my $source_dir = cwd);
73
74   my %videos;
75
76   foreach my $video_file (keys %{$video_files}) {
77
78     log_info { "Processing file ${video_file}" };
79     my @parts = split(/[- ]+/, $video_file);
80     my @options;
81     foreach my $idx (1 .. $#parts) {
82       my @opt = @{$options[$idx] = [
83         join(' ', @parts[0..$idx-1]),
84         join(' ', @parts[$idx..$#parts]),
85       ]};
86       log_info { "(${idx}) ".join(' / ', @opt) };
87     }
88     my $info;
89     CHOICE: {
90       my $choice = prompt(
91         'What author is this for (enter number for pre-selected combination) ?',
92         2
93       );
94       if ($choice =~ /^\d+$/) {
95         @{$info}{qw(author name)} = @{$options[$choice] || redo CHOICE};
96       } else {
97         $info->{author} = $choice;
98       }
99     }
100     $info->{name} = prompt('What is the name of this talk?', $info->{name});
101     (my $slug = lc $info->{name}) =~ s/ /-/g;
102     $info->{slug} = prompt('What is the slug for this talk?', $slug);
103     $info->{bucket} = $bucket;
104     $info->{announcement} = $ann;
105     $info->{announcement_id} = $ann->id; # Temp fix so INSERT behaves -- alh
106     $videos{$video_file} = bless($info, 'App::IdiotBox::Video');
107   }
108   foreach my $video_file (keys %videos) {
109     my $video = $videos{$video_file};
110     my $target_dir = catdir($ib->config->{base_dir}, $video->url_path);
111     io($target_dir)->mkpath;
112     log_info { "Copying video files to ${target_dir}"};
113     foreach my $ext (@{$video_files->{$video_file}}) {
114       no warnings 'void';
115       io(catfile($target_dir, "${\$video->file_name}.${ext}"))
116         < io(catfile($source_dir, "${video_file}.${ext}"));
117     }
118   }
119   
120   $bucket->videos->add($_) for values %videos;
121 }
122
123 sub video_files_from_dir {
124   my ($class, $dir) = @_;
125   my %videos;
126   foreach my $file (io($dir)->all_files) {
127     $file->filename =~ /^([^\.]+)\.($supported_formats_re)$/ or next;
128     push(@{$videos{$1}||=[]}, $2);
129   }
130   \%videos;
131 }
132
133 1;