[1727] | 1 | #!/usr/bin/perl |
---|
| 2 | |
---|
| 3 | use warnings; |
---|
| 4 | use strict; |
---|
| 5 | use Getopt::Long; |
---|
| 6 | use DBI; |
---|
| 7 | use File::Basename; |
---|
| 8 | use Time::Local; |
---|
| 9 | use List::Util qw/shuffle min/; |
---|
| 10 | |
---|
| 11 | my %opt; |
---|
| 12 | GetOptions( |
---|
| 13 | \%opt, |
---|
| 14 | qw/dbname=s dbuser=s dbpass=s prefix=s |
---|
| 15 | total=i start_date=s end_date=s |
---|
| 16 | help/ |
---|
| 17 | ); |
---|
| 18 | |
---|
| 19 | if (defined($opt{help})) |
---|
| 20 | { |
---|
| 21 | print <<FIN; |
---|
| 22 | |
---|
[2342] | 23 | Fill the user comments table of Piwigo. |
---|
[1727] | 24 | |
---|
| 25 | Usage: pwg_fill_comments.pl --dbname=<database_name> |
---|
| 26 | --dbuser=<username> |
---|
| 27 | --dbpass=<password> |
---|
| 28 | --tagfile=<tags filename> |
---|
| 29 | [--prefix=<tables prefix>] |
---|
| 30 | [--help] |
---|
| 31 | |
---|
| 32 | --dbname, --dbuser and --dbpass are connexion parameters. |
---|
| 33 | |
---|
| 34 | --tagfile |
---|
| 35 | |
---|
| 36 | --prefix : determines the prefix for your table names. |
---|
| 37 | |
---|
| 38 | --help : show this help |
---|
| 39 | |
---|
| 40 | FIN |
---|
| 41 | |
---|
| 42 | exit(0); |
---|
| 43 | } |
---|
| 44 | |
---|
| 45 | my $usage = "\n\n".basename($0)." --help for help\n\n"; |
---|
| 46 | |
---|
| 47 | foreach my $option (qw/dbname dbuser dbpass start_date end_date/) { |
---|
| 48 | if (not exists $opt{$option}) { |
---|
| 49 | die 'Error: '.$option.' is a mandatory option', $usage; |
---|
| 50 | } |
---|
| 51 | } |
---|
| 52 | |
---|
[2342] | 53 | $opt{prefix} = 'piwigo_' if (not defined $opt{prefix}); |
---|
[1727] | 54 | my $dbh = DBI->connect( |
---|
| 55 | 'DBI:mysql:'.$opt{dbname}, |
---|
| 56 | $opt{dbuser}, |
---|
| 57 | $opt{dbpass} |
---|
| 58 | ); |
---|
| 59 | |
---|
| 60 | my $query; |
---|
| 61 | my $sth; |
---|
| 62 | |
---|
| 63 | |
---|
| 64 | # retrieve all available users |
---|
| 65 | $query = ' |
---|
| 66 | SELECT id |
---|
| 67 | FROM '.$opt{prefix}.'users |
---|
| 68 | '; |
---|
| 69 | my @user_ids = keys %{ $dbh->selectall_hashref($query, 'id') }; |
---|
| 70 | |
---|
| 71 | # set a list of IP addresses for each users |
---|
| 72 | my %user_IPs = (); |
---|
| 73 | foreach my $user_id (@user_ids) { |
---|
| 74 | for (1 .. 1 + int rand 5) { |
---|
| 75 | push( |
---|
| 76 | @{ $user_IPs{$user_id} }, |
---|
| 77 | join( |
---|
| 78 | '.', |
---|
| 79 | map {1 + int rand 255} 1..4 |
---|
| 80 | ) |
---|
| 81 | ); |
---|
| 82 | } |
---|
| 83 | } |
---|
| 84 | |
---|
| 85 | # use Data::Dumper; print Dumper(\%user_IPs); exit(); |
---|
| 86 | |
---|
| 87 | # start and end dates |
---|
| 88 | my ($year,$month,$day,$hour,$min,$sec) |
---|
| 89 | = ($opt{start_date} =~ m/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/); |
---|
| 90 | my $start_unixtime = timelocal(0,0,0,$day,$month-1,$year); |
---|
| 91 | |
---|
| 92 | ($year,$month,$day,$hour,$min,$sec) |
---|
| 93 | = ($opt{end_date} =~ m/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/); |
---|
| 94 | my $end_unixtime = timelocal(0,0,0,$day,$month-1,$year); |
---|
| 95 | |
---|
| 96 | # "tags from image" and "images from tag" |
---|
| 97 | $query = ' |
---|
| 98 | SELECT image_id, tag_id |
---|
| 99 | FROM '.$opt{prefix}.'image_tag |
---|
| 100 | '; |
---|
| 101 | my %image_tags = (); |
---|
| 102 | my %tag_images = (); |
---|
| 103 | my %related_tag_of = (); |
---|
| 104 | my @tags = (); |
---|
| 105 | $sth = $dbh->prepare($query); |
---|
| 106 | $sth->execute(); |
---|
| 107 | while (my $row = $sth->fetchrow_hashref()) { |
---|
| 108 | push( |
---|
| 109 | @{$image_tags{$row->{image_id}}}, |
---|
| 110 | $row->{tag_id} |
---|
| 111 | ); |
---|
| 112 | |
---|
| 113 | push( |
---|
| 114 | @{$tag_images{$row->{tag_id}}}, |
---|
| 115 | $row->{image_id} |
---|
| 116 | ); |
---|
| 117 | |
---|
| 118 | push ( |
---|
| 119 | @tags, |
---|
| 120 | $row->{tag_id} |
---|
| 121 | ); |
---|
| 122 | } |
---|
| 123 | |
---|
| 124 | # foreach my $tag_id (keys %tag_images) { |
---|
| 125 | # printf( |
---|
| 126 | # "tag %5u: %5u images\n", |
---|
| 127 | # $tag_id, |
---|
| 128 | # scalar @{$tag_images{$tag_id}} |
---|
| 129 | # ); |
---|
| 130 | # } |
---|
| 131 | # exit(); |
---|
| 132 | |
---|
| 133 | # use Data::Dumper; print Dumper(\%tag_images); exit(); |
---|
| 134 | |
---|
| 135 | # categories from image_id |
---|
| 136 | $query = ' |
---|
| 137 | SELECT image_id, category_id |
---|
| 138 | FROM '.$opt{prefix}.'image_category |
---|
| 139 | '; |
---|
| 140 | my %image_categories = (); |
---|
| 141 | my %category_images =(); |
---|
| 142 | my %categories = (); |
---|
| 143 | $sth = $dbh->prepare($query); |
---|
| 144 | $sth->execute(); |
---|
| 145 | while (my $row = $sth->fetchrow_hashref()) { |
---|
| 146 | push( |
---|
| 147 | @{$image_categories{$row->{image_id}}}, |
---|
| 148 | $row->{category_id} |
---|
| 149 | ); |
---|
| 150 | |
---|
| 151 | push( |
---|
| 152 | @{$category_images{$row->{category_id}}}, |
---|
| 153 | $row->{image_id} |
---|
| 154 | ); |
---|
| 155 | |
---|
| 156 | $categories{ $row->{category_id} }++; |
---|
| 157 | } |
---|
| 158 | |
---|
| 159 | my @images = keys %image_categories; |
---|
| 160 | my @categories = keys %categories; |
---|
| 161 | |
---|
| 162 | # use Data::Dumper; |
---|
| 163 | # print Dumper(\%image_categories); |
---|
| 164 | |
---|
| 165 | my @sections = ( |
---|
| 166 | 'categories', |
---|
| 167 | # 'tags', |
---|
| 168 | # 'search', |
---|
| 169 | # 'list', |
---|
| 170 | # 'favorites', |
---|
| 171 | # 'most_visited', |
---|
| 172 | # 'best_rated', |
---|
| 173 | # 'recent_pics', |
---|
| 174 | # 'recent_cats', |
---|
| 175 | ); |
---|
| 176 | |
---|
| 177 | my @inserts = (); |
---|
| 178 | |
---|
| 179 | USER : foreach my $user_id (@user_ids) { |
---|
| 180 | print 'user_id: ', $user_id, "\n"; |
---|
| 181 | |
---|
| 182 | my $current_unixtime = $start_unixtime; |
---|
| 183 | my @IPs = @{ $user_IPs{$user_id} }; |
---|
| 184 | |
---|
| 185 | VISIT : foreach my $visit_num (1..100_000) { |
---|
| 186 | print 'visit: ', $visit_num, "\n"; |
---|
| 187 | my @temp_inserts = (); |
---|
| 188 | my $IP = (@IPs)[int rand @IPs]; |
---|
| 189 | my $current_page = 0; |
---|
| 190 | my $visit_size = 10 + int rand 90; |
---|
| 191 | $current_unixtime+= 86_400 + int rand(86_400 * 30); |
---|
| 192 | |
---|
| 193 | my $section = $sections[int rand scalar @sections]; |
---|
| 194 | # print 'section: ', $section, "\n"; |
---|
| 195 | |
---|
| 196 | push( |
---|
| 197 | @temp_inserts, |
---|
| 198 | { |
---|
| 199 | section => $section, |
---|
| 200 | } |
---|
| 201 | ); |
---|
| 202 | |
---|
| 203 | if ($section eq 'categories') { |
---|
| 204 | CATEGORY : foreach my $category_id ( |
---|
| 205 | (shuffle @categories)[1..int rand scalar @categories] |
---|
| 206 | ) { |
---|
| 207 | # print 'category: ', $category_id, "\n"; |
---|
| 208 | push( |
---|
| 209 | @temp_inserts, |
---|
| 210 | { |
---|
| 211 | category_id => $category_id, |
---|
| 212 | } |
---|
| 213 | ); |
---|
| 214 | |
---|
| 215 | my @images = @{$category_images{$category_id}}; |
---|
| 216 | IMAGE : foreach my $image_id ( |
---|
| 217 | (shuffle @images)[1..min(10, scalar @images)] |
---|
| 218 | ) { |
---|
| 219 | push( |
---|
| 220 | @temp_inserts, |
---|
| 221 | { |
---|
| 222 | category_id => $category_id, |
---|
| 223 | image_id => $image_id, |
---|
| 224 | } |
---|
| 225 | ); |
---|
| 226 | } |
---|
| 227 | } |
---|
| 228 | } |
---|
| 229 | |
---|
| 230 | if ($section eq 'tags') { |
---|
| 231 | # TODO |
---|
| 232 | } |
---|
| 233 | |
---|
| 234 | # transfert @temp_inserts to @inserts |
---|
| 235 | print 'temp_insert size: ', scalar @temp_inserts, "\n"; |
---|
| 236 | foreach my $temp_insert (@temp_inserts) { |
---|
| 237 | $current_unixtime+= 5 + int rand 25; |
---|
| 238 | next VISIT if ++$current_page == $visit_size; |
---|
| 239 | last VISIT if $current_unixtime >= $end_unixtime; |
---|
| 240 | |
---|
| 241 | my $date = unixtime_to_mysqldate($current_unixtime); |
---|
| 242 | my $time = unixtime_to_mysqltime($current_unixtime); |
---|
| 243 | |
---|
| 244 | my ($year, $month, $day) = split '-', $date; |
---|
| 245 | my ($hour) = split ':', $time; |
---|
| 246 | |
---|
| 247 | $temp_insert->{date} = $date; |
---|
| 248 | $temp_insert->{time} = $time; |
---|
| 249 | $temp_insert->{year} = $year; |
---|
| 250 | $temp_insert->{month} = $month; |
---|
| 251 | $temp_insert->{day} = $day; |
---|
| 252 | $temp_insert->{hour} = $hour; |
---|
| 253 | $temp_insert->{IP} = $IP; |
---|
| 254 | $temp_insert->{section} = $section; |
---|
| 255 | $temp_insert->{user_id} = $user_id; |
---|
| 256 | |
---|
| 257 | push(@inserts, $temp_insert); |
---|
| 258 | } |
---|
| 259 | } |
---|
| 260 | } |
---|
| 261 | |
---|
| 262 | @inserts = sort { |
---|
| 263 | $a->{date} cmp $b->{date} |
---|
| 264 | or $a->{time} cmp $b->{time} |
---|
| 265 | } @inserts; |
---|
| 266 | |
---|
| 267 | if (scalar @inserts) { |
---|
| 268 | my @columns = |
---|
| 269 | qw/ |
---|
| 270 | date time year month day hour |
---|
| 271 | user_id IP |
---|
| 272 | section category_id image_id |
---|
| 273 | /; |
---|
| 274 | |
---|
| 275 | my $question_marks_string = '('; |
---|
| 276 | $question_marks_string.= join( |
---|
| 277 | ',', |
---|
| 278 | map {'?'} @columns |
---|
| 279 | ); |
---|
| 280 | $question_marks_string.= ')'; |
---|
| 281 | |
---|
| 282 | my $query = ' |
---|
| 283 | INSERT INTO '.$opt{prefix}.'history |
---|
| 284 | ('.join(', ', @columns).') |
---|
| 285 | VALUES |
---|
| 286 | '; |
---|
| 287 | $query.= join( |
---|
| 288 | ',', |
---|
| 289 | map {$question_marks_string} (1 .. scalar @inserts) |
---|
| 290 | ); |
---|
| 291 | $query.= ' |
---|
| 292 | '; |
---|
| 293 | |
---|
| 294 | # print $query, "\n"; |
---|
| 295 | |
---|
| 296 | my @values = (); |
---|
| 297 | |
---|
| 298 | foreach my $insert (@inserts) { |
---|
| 299 | push( |
---|
| 300 | @values, |
---|
| 301 | map { |
---|
| 302 | $insert->{$_} |
---|
| 303 | } @columns |
---|
| 304 | ); |
---|
| 305 | } |
---|
| 306 | |
---|
| 307 | $sth = $dbh->prepare($query); |
---|
| 308 | $sth->execute(@values) |
---|
| 309 | or die 'cannot execute insert query'; |
---|
| 310 | } |
---|
| 311 | |
---|
| 312 | sub unixtime_to_mysqldate { |
---|
| 313 | my ($unixtime) = @_; |
---|
| 314 | |
---|
| 315 | ($sec,$min,$hour,$day,$month,$year) = localtime($unixtime); |
---|
| 316 | |
---|
| 317 | return sprintf( |
---|
| 318 | '%d-%02d-%02d', |
---|
| 319 | $year+1900, |
---|
| 320 | $month+1, |
---|
| 321 | $day, |
---|
| 322 | ); |
---|
| 323 | } |
---|
| 324 | |
---|
| 325 | sub unixtime_to_mysqltime { |
---|
| 326 | my ($unixtime) = @_; |
---|
| 327 | |
---|
| 328 | ($sec,$min,$hour,$day,$month,$year) = localtime($unixtime); |
---|
| 329 | |
---|
| 330 | return sprintf( |
---|
| 331 | '%d:%d:%d', |
---|
| 332 | $hour, |
---|
| 333 | $min, |
---|
| 334 | $sec |
---|
| 335 | ); |
---|
| 336 | } |
---|