5 load_people.pl - loading user accounts into cxgn databases
9 load_people.pl -H [dbhost] -D [dbname] -i [infile]
11 =head1 COMMAND-LINE OPTIONS
19 host name (required) e.g. "localhost"
23 database name (required) e.g. "cxgn_cassava"
27 path to infile (required)
37 Test run. Rolling back at the end.
43 This script loads user account data into the sgn_people.sp_person and sgn_people.sp_login table. Each column in the spreadsheet represents a single user, and one row will be added to sp_login and one row to sp_person.
45 The input file is xlsx format, and should have the following columns (column order is not important):
59 The first four columns listed are required.
61 The script outputs the username, first_name, last_name, email and assigned initial random password. This can be used to send the password to the user.
65 Lukas Mueller <lam87@cornell.edu>, Nov 2022
78 use Spreadsheet
::XLSX
;
79 use Bio
::Chado
::Schema
;
80 use CXGN
::People
::Person
;
81 use CXGN
::People
::Schema
;
82 use CXGN
::DB
::InsertDBH
;
83 use SGN
::Model
::Cvterm
;
85 use Crypt
::RandPasswd
;
86 our ($opt_H, $opt_D, $opt_i, $opt_t);
94 print STDERR
"Input file: $file\n";
95 print STDERR
"DB host: $dbhost\n";
96 print STDERR
"DB name: $dbname\n";
97 print STDERR
"Rollback: $opt_t\n";
99 if (!$opt_H || !$opt_D || !$opt_i) {
100 pod2usage
(-verbose
=> 2, -message
=> "Must provide options -H (hostname), -D (database name), -i (input file)\n");
103 my $dbh = CXGN
::DB
::InsertDBH
->new( { dbhost
=>$dbhost,
105 dbargs
=> {AutoCommit
=> 0,
110 my $people_schema = CXGN
::People
::Schema
->connect( sub { $dbh->get_actual_dbh() } );
112 my $schema= Bio
::Chado
::Schema
->connect( sub { $dbh->get_actual_dbh() } );
113 $dbh->do('SET search_path TO public,sgn,sgn_people');
115 my $converter = Text
::Iconv
->new("utf-8", "windows-1251");
117 my $excel = Spreadsheet
::XLSX
->new($opt_i, $converter);
121 foreach my $sheet (@
{$excel->{Worksheet
}}) {
123 printf("Sheet: %s\n", $sheet->{Name
});
125 $sheet->{MaxRow
} ||= $sheet->{MinRow
};
127 print STDERR
"MIN ROW = ".$sheet->{MinRow
}."\n";
131 my @required_headers = qw
| first_name last_name username email
|;
136 foreach my $row ($sheet->{MinRow
} .. $sheet->{MaxRow
}) {
137 @header = @
{$sheet->{Cells
}->[0]};
139 for(my $i =0; $i< @header; $i++) {
140 print STDERR
$header[$i]->{Val
}."\n";
141 $ch{$header[$i]->{Val
} } = $i;
145 print STDERR
"HEADERS: ".Dumper
(\
%ch);
146 print STDERR
"REQUIRED: ".Dumper
(\
@required_headers);
149 foreach my $h (@required_headers) {
150 if (!exists($ch{$h})) {
151 push @missing_headers, $h;
155 if (@missing_headers) {
156 print STDERR
"Required headers include: ". join(", ", @required_headers)."\n";
157 print STDERR
"Missing: ".join(", ", @missing_headers)."\n";
159 die "Check file format for header requirements.";
162 foreach my $row (1 .. $sheet->{MaxRow
}) {
164 $sheet->{MaxCol
} ||= $sheet->{MinCol
};
166 my @fields = map { $_ ->{Val
} } @
{$sheet->{Cells
}->[$row]};
169 for(my $n =0; $n< @header; $n++) {
171 $data{$header[$n]->{Val
}} = $fields[$n];
175 print STDERR
"DATA: ".Dumper
(\
%data);
177 if (!$data{username
} || !$data{email
} || !$data{first_name
} || !$data{last_name
}) {
178 print STDERR
"Not enough information provided in row ".join(", ", @fields).". Skipping.\n";
182 my $row = $people_schema->resultset("SpPerson")->find( { username
=> $data{username
} } );
184 print STDERR
"Username $data{username} already exists in the database. Skipping this row.\n";
189 my $rs = $people_schema->resultset("SpPerson")
190 ->search( { '-or' => [ contact_email
=> $data{email
}, private_email
=> $data{email
}, pending_email
=> $data{email
} ] } );
192 if ($rs->count > 0) {
193 print STDERR
"Email $data{email} already exists in the database in contact_email, pending_email, or private_email field. Skipping this row.\n";
198 # $row = $people_schema->resultset("SpPerson")->find( { pending_email => $data{email} });
200 # print STDERR "Email $data{email} already exists in the database in pending_email field. Skipping this row.\n";
204 my $password =Crypt
::RandPasswd
->word( 8 , 8 );
205 if ($data{username
}) {
206 my $login = CXGN
::People
::Login
->new($dbh);
208 $login->set_username($data{username
});
209 $login->set_private_email($data{email
});
210 $login->set_pending_email($data{email
});
211 $login->set_organization($data{organization
});
212 $login->set_password($password);
214 print "$data{first_name}\t$data{last_name}\t$data{username}\t$data{email}\t$password\n";
216 my $sp_person_id = $login->store();
218 print STDERR
"SP PERSON ID = ".$sp_person_id."\n";
220 my $person = CXGN
::People
::Person
->new($dbh, $sp_person_id);
222 $person->set_first_name($data{first_name
});
223 $person->set_last_name($data{last_name
});
224 $person->set_contact_email($data{email
});
225 $person->set_address($data{address
});
226 $person->set_country($data{country
});
227 $person->set_phone_number($data{phone_number
});
228 $person->set_research_keywords($data{research_keywords
});
229 $person->set_research_interests($data{research_interests
});
230 $person->set_webpage($data{webpage
});
238 $schema->txn_do($coderef);
240 print "Transaction succeeded! Commiting user data! \n\n";
243 die "Not storing, rolling back\n";
248 die "An error occured! Rolling back!" . $_ . "\n";