File Coverage

blib/lib/Rtmgr/Gen/Db.pm
Criterion Covered Total %
statement 23 237 9.7
branch 0 106 0.0
condition n/a
subroutine 8 17 47.0
pod 0 8 0.0
total 31 368 8.4


line stmt bran cond sub pod time code
1             package Rtmgr::Gen::Db;
2              
3 1     1   67132 use 5.006;
  1         4  
4 1     1   10 use strict;
  1         2  
  1         20  
5 1     1   4 use warnings;
  1         2  
  1         77  
6 1     1   664 use diagnostics;
  1         239526  
  1         11  
7 1     1   1008 use XML::RPC;
  1         11918  
  1         36  
8 1     1   510 use Data::Dump qw(dump);
  1         7282  
  1         59  
9 1     1   1586 use DBI;
  1         17751  
  1         83  
10              
11 1     1   17 use Exporter 'import';
  1         3  
  1         2509  
12             our @EXPORT_OK = qw(get_download_list create_db_table get_name get_tracker calc_scene insert_into_database_missing get_difference_between_server_and_database add_remove_extraneous_reccords);
13            
14             =head1 NAME
15              
16             Rtmgr::Gen::Db - Connect to rTorrent/ruTorrent installation and get a list of torrents, storing them to a database.
17              
18             =head1 VERSION
19              
20             Version 0.05
21              
22             =cut
23              
24             our $VERSION = '0.05';
25              
26              
27             =head1 SYNOPSIS
28              
29             Connects to a rTorrent/ruTorrent installation.
30              
31             This module connects to an installation of rTorrent/ruTorrent and builds a local SQLite database with the content of the seedbox.
32              
33             =head1 SUBROUTINES/METHODS
34              
35             #!/usr/bin/env perl
36             use Data::Dump qw(dump);
37              
38             use Rtmgr::Gen qw(get_download_list create_db_table get_name get_tracker calc_scene insert_into_database_missing get_difference_between_server_and_database add_remove_extr$
39             # Create Database.
40             my $create_db = create_db_table('database');
41             print $create_db;
42              
43             # Populate database with ID's 'HASH' of torrents.
44             my $dl_list_arr_ref = get_download_list('user','password','host','443','RPC2','database');
45             insert_into_database_missing($dl_list_arr_ref,'database');
46              
47             # Remove Extraneous Reccords from Database.
48             my $dl_list_ext_reccords = get_download_list('user','password','host','443','RPC2','database');
49             my $diff_list = get_difference_between_server_and_database($dl_list_ext_reccords,'database');
50             add_remove_extraneous_reccords($diff_list,'database');
51              
52             # Populate database with Torrent Names.
53             my $get_name = get_name('user','password','host','443','RPC2','database');
54             print $get_name;
55              
56             # Populate database with trackers.
57             my $get_tracker = get_tracker('user','password','host','443','RPC2','database');
58             print $get_tracker;
59              
60             # Check if release is a scene release by checking for entry in srrdb.
61             my $calc_scene = calc_scene('user','password','database');
62             print $calc_scene;
63              
64             =head2 get
65              
66             =cut
67             sub create_db_table {
68 0     0 0   my ($s_file) = @_;
69              
70             # Check to see if file exists or not. If not create it.
71 0 0         if (-e "$s_file".".db") {
72 0           print "\nDatabase exists.\n";
73             } else {
74 0           print "\nCreating Database...\n";
75             # Open SQLite database.
76 0           my $driver = "SQLite";
77 0           my $database = "$s_file.db";
78 0           my $dsn = "DBI:$driver:dbname=$database";
79 0           my $userid = ""; # Not implemented no need for database security on local filesystem at this time.
80 0           my $password = ""; # Not implemented.
81 0 0         my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr;
82              
83 0           print "Opened database successfully\n";
84              
85             # Create the database tables.
86 0           my $stmt = qq(CREATE TABLE SEEDBOX
87             (ID TEXT PRIMARY KEY NOT NULL,
88             BLANK TEXT NOT NULL,
89             SCENE TEXT NOT NULL,
90             TRACKER TEXT NOT NULL,
91             NAME TEXT NOT NULL););
92             # Error checking.
93 0           my $rv = $dbh->do($stmt);
94 0 0         if($rv < 0) {
95 0           print $DBI::errstr;
96             } else {
97 0           print "Table created successfully\n";
98             }
99 0           $dbh->disconnect();
100             }
101             }
102              
103             sub get_download_list {
104 0     0 0   my ($s_user, $s_pw, $s_url, $s_port, $s_endp, $s_file) = @_;
105             ## Validate input from ARGV
106 0 0         if (not defined $s_user) { die "USEAGE: Missing server user.\n"; }
  0            
107 0 0         if (not defined $s_pw) { die "USEAGE: Missing server password.\n"; }
  0            
108 0 0         if (not defined $s_url) { die "USEAGE: Missing server url.\n"; }
  0            
109 0 0         if (not defined $s_port) { die "USEAGE: Missing server port.\n"; }
  0            
110 0 0         if (not defined $s_endp) { die "USEAGE: Missing server endpoint.\n"; }
  0            
111 0 0         if (not defined $s_file) { die "USEAGE: Missing server db-filename.\n"; }
  0            
112             # Run Example: perl gen-db.pl user pass host port endpoint
113 0           my $xmlrpc = XML::RPC->new("https://$s_user\:$s_pw\@$s_url\:$s_port\/$s_endp");
114              
115 0           return $xmlrpc->call( 'download_list' );
116             }
117              
118             sub insert_into_database_missing {
119 0     0 0   foreach my $i (@{ $_[0] }){
  0            
120 0           my $hash_search = _lookup_hash($_[1],$i);
121 0 0         if ($hash_search == '0') {
122 0           print "HASH: NOT IN DATABSE ... Adding ...\n";
123             # Open SQLite database.
124 0           my $driver = "SQLite";
125 0           my $database = "$_[1].db";
126 0           my $dsn = "DBI:$driver:dbname=$database";
127 0           my $userid = ""; # Not implemented no need for database security on local filesystem at this time.
128 0           my $password = ""; # Not implemented.
129 0 0         my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr;
130             # Insert the value into the database.
131 0           my $stmt = qq(INSERT INTO SEEDBOX (ID,BLANK,SCENE,TRACKER,NAME)
132             VALUES ('$i', '', '', '', ''));
133 0 0         my $rv = $dbh->do($stmt) or die $DBI::errstr;
134 0           $dbh->disconnect();
135             } else {
136 0           print "HASH: $i \n";
137             }
138             }
139             }
140              
141             sub get_difference_between_server_and_database {
142             # $_[0]; # Reference to download list hash. Dereference with @{ $_[0] }
143             # $_[1]; # Scalar of name of database file.
144              
145             # Open SQLite database.
146 0     0 0   my $driver = "SQLite";
147 0           my $database = "$_[1].db";
148 0           my $dsn = "DBI:$driver:dbname=$database";
149 0           my $userid = ""; # Not implemented no need for database security on local filesystem at this time.
150 0           my $password = ""; # Not implemented.
151 0 0         my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr;
152              
153 0           my $stmt = qq(SELECT ID from SEEDBOX;);
154 0           my $sth = $dbh->prepare( $stmt );
155 0 0         my $rv = $sth->execute() or die $DBI::errstr;
156            
157 0           my @disk_array;
158             # Go through every item in database in while loop.
159 0           while(my @row = $sth->fetchrow_array()){
160 0           push(@disk_array, $row[0])
161             }
162 0 0         if( $rv < 0 ) {
163 0           print $DBI::errstr;
164             }
165             # Check if there is a difference between the two arrays.
166 0           my %diff1;
167             my %diff2;
168              
169 0           @diff1{ @disk_array } = @disk_array;
170 0           delete @diff1{ @{ $_[0] } };
  0            
171             # %diff1 contains elements from '@disk_array' that are not in '@{ $_[0] }'
172              
173 0           @diff2{ @{ $_[0] } } = @{ $_[0] };
  0            
  0            
174 0           delete @diff2{ @disk_array };
175             # %diff2 contains elements from '@{ $_[0] }' that are not in '@disk_array'
176              
177 0           my @k = (keys %diff1, keys %diff2);
178              
179 0           return(\@k);
180              
181 0           $dbh->disconnect();
182             }
183              
184             sub add_remove_extraneous_reccords{
185             # Open SQLite database.
186 0     0 0   my $driver = "SQLite";
187 0           my $database = "$_[1].db";
188 0           my $dsn = "DBI:$driver:dbname=$database";
189 0           my $userid = ""; # Not implemented no need for database security on local filesystem at this time.
190 0           my $password = ""; # Not implemented.
191 0 0         my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr;
192              
193              
194 0           print "\nExtraneous Database Reccords: \n";
195             # $_[0] is an array reference to either add or delete from database.
196 0           foreach my $i (@{ $_[0] }){
  0            
197 0           print "Key: $i\n";
198              
199 0           my $hash_search = _lookup_hash($_[1],$i);
200 0 0         if ($hash_search == '0') {
201 0           print "HASH: $i \n\t NOT IN DATABSE ... Adding ...\n";
202 0           my $stmt = qq(INSERT INTO SEEDBOX (ID,BLANK,SCENE,TRACKER,NAME)
203             VALUES ('$i', '', '', '', ''));
204 0 0         my $rv = $dbh->do($stmt) or die $DBI::errstr;
205             } else {
206 0           print "Key: $i | Does not belong in database.\n";
207             # Delete Operation.
208 0           my $stmt = qq(DELETE from SEEDBOX where ID = $i;);
209 0 0         my $rv = $dbh->do($stmt) or die $DBI::errstr;
210             }
211             }
212 0           $dbh->disconnect();
213             }
214              
215             sub _lookup_hash {
216             # This sub is passed the filename of a database, and a hash.
217             # If the hash exists in the database it returns the hash.
218             # If the hash does not exist in the database returns a 0.
219 0     0     my ($s_file, $hash) = @_;
220              
221             # Open SQLite database.
222 0           my $driver = "SQLite";
223 0           my $database = "$s_file.db";
224 0           my $dsn = "DBI:$driver:dbname=$database";
225 0           my $userid = ""; # Not implemented no need for database security on local filesystem at this time.
226 0           my $password = ""; # Not implemented.
227 0 0         my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr;
228              
229             # Run a check to see if the hash already exists in database.
230 0           my $stmt = qq(SELECT ID FROM SEEDBOX WHERE ID = "$hash";);
231 0           my $sth = $dbh->prepare( $stmt );
232 0 0         my $rv = $sth->execute() or die $DBI::errstr;
233              
234 0           my @row = $sth->fetchrow_array();
235              
236 0 0         if( $rv < 0 ) {
237 0           print $DBI::errstr;
238             } else {
239             # Check if the $row[0] returned from the database query has a value or not.
240 0 0         if(exists($row[0])){
241             } else {
242 0           return('0');
243             }
244             }
245             # Disconnect from database.
246 0           $sth->finish();
247 0           $dbh->disconnect();
248             }
249              
250             sub get_name {
251 0     0 0   my ($s_user, $s_pw, $s_url, $s_port, $s_endp, $s_file) = @_;
252              
253             ## Validate input from ARGV
254 0 0         if (not defined $s_user) { die "USEAGE: Missing server user.\n"; }
  0            
255 0 0         if (not defined $s_pw) { die "USEAGE: Missing server password.\n"; }
  0            
256 0 0         if (not defined $s_url) { die "USEAGE: Missing server url.\n"; }
  0            
257 0 0         if (not defined $s_port) { die "USEAGE: Missing server port.\n"; }
  0            
258 0 0         if (not defined $s_endp) { die "USEAGE: Missing server endpoint.\n"; }
  0            
259 0 0         if (not defined $s_file) { die "USEAGE: Missing server db-filename.\n"; }
  0            
260             # Run Example: perl gen-db.pl user pass host port endpoint
261 0           my $xmlrpc = XML::RPC->new("https://$s_user\:$s_pw\@$s_url\:$s_port\/$s_endp");
262              
263             # Open SQLite database.
264 0           my $driver = "SQLite";
265 0           my $database = "$s_file.db";
266 0           my $dsn = "DBI:$driver:dbname=$database";
267 0           my $userid = ""; # Not implemented no need for database security on local filesystem at this time.
268 0           my $password = ""; # Not implemented.
269 0 0         my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr;
270              
271 0           print "Opened database successfully\n";
272              
273             # Open database and itterate through it.
274 0           my $stmt = qq(SELECT ID, BLANK, SCENE, TRACKER, NAME from SEEDBOX;);
275 0           my $sth = $dbh->prepare( $stmt );
276 0 0         my $rv = $sth->execute() or die $DBI::errstr;
277              
278 0 0         if($rv < 0) {
279 0           print $DBI::errstr;
280             }
281              
282 0           while(my @row = $sth->fetchrow_array()) {
283             # Look in $row[4] for a value. if it is empty fetch a name for the hash in $row[0].
284 0 0         if($row[4]) {
285 0           print "NAME: $row[4]\n";
286             } else {
287             # Send a call to rtorrent and get the name of the corrisponding hash.
288 0           my $name = $xmlrpc->call( 'd.get_name',"$row[0]" );
289             # Update the corrisponding reccord in the database.
290 0           my $stmt = qq(UPDATE SEEDBOX set NAME = "$name" where ID='$row[0]';);
291 0 0         my $rv = $dbh->do($stmt) or die $DBI::errstr;
292              
293 0 0         if( $rv < 0 ) {
294 0           print $DBI::errstr;
295             } else {
296 0           print "ADDED: $name\n";
297             }
298             }
299             }
300 0           print "Operation done successfully\n";
301             # Disconnect from database.
302 0           $dbh->disconnect();
303             }
304              
305             sub get_tracker {
306 0     0 0   my ($s_user, $s_pw, $s_url, $s_port, $s_endp, $s_file) = @_;
307              
308             ## Validate input from ARGV
309 0 0         if (not defined $s_user) { die "USEAGE: Missing server user.\n"; }
  0            
310 0 0         if (not defined $s_pw) { die "USEAGE: Missing server password.\n"; }
  0            
311 0 0         if (not defined $s_url) { die "USEAGE: Missing server url.\n"; }
  0            
312 0 0         if (not defined $s_port) { die "USEAGE: Missing server port.\n"; }
  0            
313 0 0         if (not defined $s_endp) { die "USEAGE: Missing server endpoint.\n"; }
  0            
314 0 0         if (not defined $s_file) { die "USEAGE: Missing server db-filename.\n"; }
  0            
315             # Run Example: perl gen-db.pl user pass host port endpoint
316 0           my $xmlrpc = XML::RPC->new("https://$s_user\:$s_pw\@$s_url\:$s_port\/$s_endp");
317             # my $dl_list = $xmlrpc->call( 'download_list' );
318              
319             # Open SQLite database.
320 0           my $driver = "SQLite";
321 0           my $database = "$s_file.db";
322 0           my $dsn = "DBI:$driver:dbname=$database";
323 0           my $userid = ""; # Not implemented no need for database security on local filesystem at this time.
324 0           my $password = ""; # Not implemented.
325 0 0         my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr;
326              
327 0           print "Opened database successfully\n";
328            
329             # Open database and itterate through it.
330 0           my $stmt = qq(SELECT ID, BLANK, SCENE, TRACKER, NAME from SEEDBOX;);
331 0           my $sth = $dbh->prepare( $stmt );
332 0 0         my $rv = $sth->execute() or die $DBI::errstr;
333              
334 0 0         if($rv < 0) {
335 0           print $DBI::errstr;
336             }
337 0           while(my @row = $sth->fetchrow_array()) {
338             # Check to see if the NAME value is populated.
339 0 0         if($row[3]) {
340 0           print "HASH: ".$row[0]."\tBLANK: ".$row[1]."\tSCENE: ".$row[2]."\n\tTRACKER: ".$row[3]."\n\tNAME: ".$row[4]."\n";
341             } else {
342             # Get name for specific reccord in the loop.
343 0           my $url = $xmlrpc->call( 't.url',"$row[0]:t0" );
344             #dump($url); # Dump the call for testing purposes.
345             # Update reccords.
346 0           my $stmt = qq(UPDATE SEEDBOX set TRACKER = "$url" where ID='$row[0]';);
347 0 0         my $rv = $dbh->do($stmt) or die $DBI::errstr;
348              
349 0 0         if( $rv < 0 ) {
350 0           print $DBI::errstr;
351             } else {
352 0           print "HASH: ".$row[0]."\tBLANK: ".$row[1]."\tSCENE: ".$row[2]."\n\tTRACKER: ".$url."\n\tNAME: ".$row[4]."\n";
353             }
354             }
355             }
356 0           print "Operation done successfully\n";
357             # Disconnect from database.
358 0           $dbh->disconnect();
359             }
360              
361             sub calc_scene {
362 0     0 0   my ($s_usr, $s_pw, $s_file) = @_;
363              
364 0           print "Active Database: $s_file\n";
365              
366             # Open SQLite database.
367 0           my $driver = "SQLite";
368 0           my $database = "$s_file.db";
369 0           my $dsn = "DBI:$driver:dbname=$database";
370 0           my $userid = ""; # Not implemented no need for database security on local filesystem at this time.
371 0           my $password = ""; # Not implemented.
372 0 0         my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr;
373              
374 0           print "Opened database successfully\n";
375            
376             # Open database and itterate through it.
377 0           my $stmt = qq(SELECT ID, BLANK, SCENE, TRACKER, NAME from SEEDBOX;);
378 0           my $sth = $dbh->prepare( $stmt );
379 0 0         my $rv = $sth->execute() or die $DBI::errstr;
380              
381 0 0         if($rv < 0) {
382 0           print $DBI::errstr;
383             }
384              
385 0           while(my @row = $sth->fetchrow_array()) {
386             # Check to see if the NAME value is populated.
387 0           print "\nID: $row[0]\t";
388              
389 0 0         if($row[2]) {
390 0           print "\tsrrDB: $row[2]\n";
391 0           print "\tTRACKER: $row[3]\n";
392 0           print "\tNAME: $row[4]\n";
393             } else {
394 0           print "\n\t * * * Searching * * * $row[4]\n";
395 0           my $srrdb_query = qx(srrdb --username=$s_usr --password=$s_pw -s "$row[4]");
396              
397             # Create Database Reccord.
398 0           my $stmt = qq(UPDATE SEEDBOX set SCENE = "$srrdb_query" where ID='$row[0]';);
399 0 0         my $rv = $dbh->do($stmt) or die $DBI::errstr;
400 0 0         if( $rv < 0 ) {
401 0           print $DBI::errstr;
402             } else {
403 0           print "\tsrrDB: $srrdb_query\n";
404 0           print "\tTRACKER: $row[3]\n";
405 0           print "\tNAME: $row[4].\n";
406             }
407             }
408              
409 0           print "\t---\n";
410             }
411 0           print "\nOperation done successfully\n";
412              
413             # Disconnect from database.
414 0           $dbh->disconnect();
415             }
416              
417             =head1 AUTHOR
418              
419             Clem Morton, C<< >>
420              
421             =head1 BUGS
422              
423             Please report any bugs or feature requests to C, or through
424             the web interface at L. I will be notified, and then you'll
425             automatically be notified of progress on your bug as I make changes.
426              
427             =head1 SUPPORT
428              
429             You can find documentation for this module with the perldoc command.
430              
431             perldoc Rtmgr::Gen::Db
432              
433             You can also look for information at:
434              
435             =over 4
436              
437             =item * RT: CPAN's request tracker (report bugs here)
438              
439             L
440              
441             =item * AnnoCPAN: Annotated CPAN documentation
442              
443             L
444              
445             =item * CPAN Ratings
446              
447             L
448              
449             =item * Search CPAN
450              
451             L
452              
453             =back
454              
455              
456             =head1 ACKNOWLEDGEMENTS
457              
458              
459             =head1 LICENSE AND COPYRIGHT
460              
461             This software is Copyright (c) 2020 by Clem Morton.
462              
463             This is free software, licensed under:
464              
465             The Artistic License 2.0 (GPL Compatible)
466              
467             =cut
468              
469             1; # End of Rtmgr::Gen::Db