migrate.pl 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #!/usr/bin/perl
  2. #Migrate tCMS1 data to tCMS2 flat file data model
  3. use strict;
  4. use warnings;
  5. use JSON::MaybeXS;
  6. use File::Slurper();
  7. use HTML::Parser;
  8. use UUID::Tiny ':std';
  9. use File::Copy;
  10. use DateTime;
  11. #Edit this to be whatever you need it to be
  12. my $docroot = "/var/www/teodesian.net/doc";
  13. my $dir = "/var/www/teodesian.net/doc/microblog/";
  14. opendir( my $dh, $dir ) or die;
  15. my @days = grep { !/^\./ } readdir $dh;
  16. closedir $dh;
  17. my $ring = JSON::MaybeXS->new();
  18. foreach my $day (@days) {
  19. opendir( my $dht, "$dir/$day" ) or die;
  20. my @times = grep { !/^\./ } readdir $dht;
  21. closedir $dht;
  22. my ( $month, $date, $year ) = split( /\./, $day );
  23. foreach my $time (@times) {
  24. my ( $hour, $min, $sec ) = split( /:/, $time );
  25. my $data;
  26. my $file = "$dir/$day/$time";
  27. print "Migrate $file\n";
  28. eval {
  29. my $content = File::Slurper::read_text($file);
  30. $data = $ring->decode($content);
  31. $data = json_remap($data);
  32. };
  33. $data = html_post($file) unless $data;
  34. my $dt = DateTime->new(
  35. year => $year + 2000,
  36. month => $month,
  37. day => $date,
  38. hour => $hour,
  39. minute => $min,
  40. second => $sec,
  41. );
  42. $data->{created} = $dt->epoch();
  43. $data->{id} = $data->{created};
  44. $data->{tags} = [ 'public', 'news' ];
  45. $data->{version} = 0;
  46. open( my $fh, '>', "data/files/$data->{created}" ) or die;
  47. print $fh encode_json( [$data] );
  48. close $fh;
  49. }
  50. }
  51. # Migrate blog posts
  52. $dir = "$docroot/blog";
  53. opendir( my $bh, $dir ) or die;
  54. my @blogs = grep { -f "$dir/$_" } readdir $bh;
  55. closedir $bh;
  56. my $offset = 0;
  57. foreach my $post (
  58. sort {
  59. my $anum = $a =~ m/^(\d*)-/;
  60. my $bnum = $b =~ m/^(\d*)-/;
  61. $b <=> $a
  62. } @blogs
  63. ) {
  64. my $postname = $post;
  65. $postname =~ s/^\d*-//g;
  66. $postname =~ s/\.post$//g;
  67. my $content = File::Slurper::read_text("$dir/$post");
  68. my $data = {
  69. title => $postname,
  70. data => $content,
  71. tags => [ 'blog', 'public' ],
  72. };
  73. my ( undef, undef, undef, undef, $uid, undef, undef, undef, undef, $ctime ) = stat("$dir/$post");
  74. my $user = lc( getpwuid($uid) );
  75. $user = scalar( grep { $user eq $_ } qw{/sbin/nologin www-data} ) ? 'nobody' : $user;
  76. $data->{user} = $user;
  77. $ctime += $offset;
  78. $data->{created} = $ctime;
  79. $data->{id} = $ctime;
  80. $data->{href} = "/blog/$ctime";
  81. $data->{version} = 0;
  82. print "Migrate blog post '$post'\n";
  83. open( my $fh, '>', "data/files/$data->{created}" ) or die;
  84. print $fh encode_json( [$data] );
  85. close $fh;
  86. $offset--;
  87. }
  88. exit 0;
  89. my $vdir = "$docroot/fileshare/video";
  90. opendir( my $vh, $vdir ) or die;
  91. my @vidyas = grep { -f "$vdir/$_" && $_ =~ m/\.m4v$/ } readdir $vh;
  92. closedir $vh;
  93. foreach my $vid (@vidyas) {
  94. my $postname = $vid;
  95. $postname =~ s/_/ /g;
  96. $postname =~ s/\.mv4$//g;
  97. my $data = {
  98. title => $postname,
  99. data => "Description forthcoming",
  100. tags => [ 'video', 'public' ],
  101. preview => "/img/sys/testpattern.jpg",
  102. };
  103. my ( undef, undef, undef, undef, $uid, undef, undef, undef, undef, $ctime ) = stat("$vdir/$vid");
  104. my $user = lc( getpwuid($uid) );
  105. $user = scalar( grep { $user eq $_ } qw{/sbin/nologin www-data} ) ? 'nobody' : $user;
  106. $data->{user} = $user;
  107. $data->{created} = $ctime;
  108. $data->{id} = $ctime;
  109. $data->{href} = "/assets/$ctime-$vid";
  110. $data->{version} = 0;
  111. #Copy over the video
  112. File::Copy::copy( "$vdir/$vid", "www/assets/$ctime-$vid" );
  113. print "Migrate video '$vid'\n";
  114. open( my $fh, '>', "data/files/$data->{created}" ) or die;
  115. print $fh encode_json( [$data] );
  116. close $fh;
  117. }
  118. sub json_remap {
  119. my $json = shift;
  120. return {
  121. preview => $json->{"image"},
  122. data => $json->{"comment"},
  123. user => lc( $json->{"poster"} ),
  124. title => $json->{"title"},
  125. audio_href => $json->{"audio"},
  126. href => $json->{"url"},
  127. video_href => $json->{"video"},
  128. };
  129. }
  130. sub html_post {
  131. my $file = shift;
  132. my $is_first_link = 1;
  133. my $data = { data => '', href => '' };
  134. my $p = HTML::Parser->new(
  135. handlers => [
  136. start => [
  137. sub {
  138. my ( $self, $attr, $text, $tagname ) = @_;
  139. if ( $tagname eq 'a' && $is_first_link ) {
  140. $data->{href} = $attr->{href};
  141. return;
  142. }
  143. return if $is_first_link;
  144. return if $tagname eq 'hr';
  145. $data->{data} .= $text;
  146. },
  147. 'self, attr, text,tagname'
  148. ],
  149. text => [
  150. sub {
  151. my ( $self, $attr, $text, $tagname ) = @_;
  152. if ($is_first_link) {
  153. $data->{title} .= $text;
  154. return;
  155. }
  156. $data->{data} .= $text;
  157. },
  158. 'self, attr, text,tagname'
  159. ],
  160. end => [
  161. sub {
  162. my ( $self, $attr, $text, $tagname ) = @_;
  163. if ( $tagname eq 'a' && $is_first_link ) {
  164. $is_first_link = 0;
  165. return;
  166. }
  167. return if $is_first_link;
  168. $data->{data} .= $text;
  169. },
  170. 'self, attr, text,tagname'
  171. ],
  172. ],
  173. );
  174. $p->parse_file($file);
  175. #Get the user name from ownership
  176. my ( undef, undef, undef, undef, $uid, undef, undef, undef, undef, $ctime ) = stat($file);
  177. my $user = lc( getpwuid($uid) );
  178. $user = scalar( grep { $user eq $_ } qw{/sbin/nologin www-data} ) ? 'nobody' : $user;
  179. $data->{user} = $user;
  180. $data->{created} = $ctime;
  181. return $data;
  182. }