Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
bwinf
medal
Commits
26effac5
Commit
26effac5
authored
Apr 09, 2019
by
Robert Czechowski
Browse files
Rustfmt ALL the code!
parent
598119ab
Pipeline
#70
failed with stage
in 1 minute and 29 seconds
Changes
8
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
src/configreader_yaml.rs
View file @
26effac5
use
db_objects
::{
Contest
,
Task
group
,
Task
};
use
db_objects
::{
Contest
,
Task
,
Task
group
};
use
serde_yaml
;
...
...
@@ -9,19 +9,22 @@ struct ContestYaml {
participation_end
:
Option
<
String
>
,
duration_minutes
:
Option
<
u32
>
,
public_listing
:
Option
<
bool
>
,
tasks
:
Option
<
serde_yaml
::
Mapping
>
,
}
// The task path is stored relatively to the contest.yaml for easier identificationy
// Concatenation happens in functions::show_task
pub
fn
parse_yaml
(
content
:
&
str
,
filename
:
&
str
,
directory
:
&
str
)
->
Option
<
Contest
>
{
let
config
:
ContestYaml
=
serde_yaml
::
from_str
(
&
content
)
.unwrap
();
let
mut
contest
=
Contest
::
new
(
directory
.to_string
(),
filename
.to_string
(),
config
.name
?
,
config
.duration_minutes
?
,
config
.public_listing
.unwrap_or
(
false
),
None
,
None
);
let
mut
contest
=
Contest
::
new
(
directory
.to_string
(),
filename
.to_string
(),
config
.name
?
,
config
.duration_minutes
?
,
config
.public_listing
.unwrap_or
(
false
),
None
,
None
);
for
(
name
,
info
)
in
config
.tasks
?
{
if
let
serde_yaml
::
Value
::
String
(
name
)
=
name
{
...
...
@@ -30,46 +33,46 @@ pub fn parse_yaml(content: &str, filename: &str, directory: &str) -> Option<Cont
serde_yaml
::
Value
::
String
(
taskdir
)
=>
{
let
mut
task
=
Task
::
new
(
taskdir
,
3
);
taskgroup
.tasks
.push
(
task
);
}
,
}
serde_yaml
::
Value
::
Sequence
(
taskdirs
)
=>
{
let
mut
stars
=
2
;
for
taskdir
in
taskdirs
{
if
let
serde_yaml
::
Value
::
String
(
taskdir
)
=
taskdir
{
let
mut
task
=
Task
::
new
(
taskdir
,
stars
);
taskgroup
.tasks
.push
(
task
);
}
else
{
}
else
{
panic!
(
"Invalid contest YAML: {}{} (a)"
,
directory
,
filename
)
}
stars
+=
1
;
}
}
serde_yaml
::
Value
::
Mapping
(
taskdirs
)
=>
{
let
mut
stars
=
2
;
for
(
taskdir
,
taskinfo
)
in
taskdirs
{
if
let
(
serde_yaml
::
Value
::
String
(
taskdir
),
serde_yaml
::
Value
::
Mapping
(
taskinfo
))
=
(
taskdir
,
taskinfo
)
{
if
let
Some
(
serde_yaml
::
Value
::
Number
(
cstars
))
=
taskinfo
.get
(
&
serde_yaml
::
Value
::
String
(
"stars"
.to_string
()))
{
if
let
(
serde_yaml
::
Value
::
String
(
taskdir
),
serde_yaml
::
Value
::
Mapping
(
taskinfo
))
=
(
taskdir
,
taskinfo
)
{
if
let
Some
(
serde_yaml
::
Value
::
Number
(
cstars
))
=
taskinfo
.get
(
&
serde_yaml
::
Value
::
String
(
"stars"
.to_string
()))
{
stars
=
cstars
.as_u64
()
.unwrap
()
as
u8
;
}
let
mut
task
=
Task
::
new
(
taskdir
,
stars
);
taskgroup
.tasks
.push
(
task
);
stars
+=
1
;
}
else
{
}
else
{
panic!
(
"Invalid contest YAML: {}{} (b)"
,
directory
,
filename
)
}
}
}
_
=>
panic!
(
"Invalid contest YAML: {}{} (c)"
,
directory
,
filename
)
_
=>
panic!
(
"Invalid contest YAML: {}{} (c)"
,
directory
,
filename
)
,
}
contest
.taskgroups
.push
(
taskgroup
);
}
else
{
}
else
{
panic!
(
"Invalid contest YAML: {}{} (d)"
,
directory
,
filename
)
}
}
Some
(
contest
)
}
src/db_apply_migrations.rs
View file @
26effac5
...
...
@@ -3,22 +3,19 @@ use std::io::Read;
use
db_conn
::
MedalConnection
;
pub
fn
test
<
C
:
MedalConnection
>
(
conn
:
&
mut
C
)
{
let
mut
paths
:
Vec
<
_
>
=
fs
::
read_dir
(
format!
(
"migrations/{}"
,
conn
.dbtype
()))
.unwrap
()
.map
(|
r
|
r
.unwrap
())
.filter
(|
r
|
r
.path
()
.display
()
.to_string
()
.ends_with
(
".sql"
))
.collect
();
fs
::
read_dir
(
format!
(
"migrations/{}"
,
conn
.dbtype
()))
.unwrap
()
.map
(|
r
|
r
.unwrap
())
.filter
(|
r
|
{
r
.path
()
.display
()
.to_string
()
.ends_with
(
".sql"
)
})
.collect
();
paths
.sort_by_key
(|
dir
|
dir
.path
());
for
path
in
paths
{
for
path
in
paths
{
let
filename
=
path
.file_name
()
.into_string
()
.unwrap
();
if
!
conn
.migration_already_applied
(
&
filename
)
{
if
!
conn
.migration_already_applied
(
&
filename
)
{
let
mut
file
=
fs
::
File
::
open
(
path
.path
())
.unwrap
();
let
mut
contents
=
String
::
new
();
file
.read_to_string
(
&
mut
contents
)
.unwrap
();
...
...
@@ -28,8 +25,5 @@ pub fn test<C: MedalConnection>(conn: &mut C) {
/*else { // TODO: Show in high debug level only
println!("Found: {}. Already applied", path.path().display());
}*/
}
}
src/db_conn.rs
View file @
26effac5
use
db_objects
::
*
;
use
::
functions
;
use
std
::
path
::
{
Path
}
;
use
functions
;
use
std
::
path
::
Path
;
pub
trait
MedalConnection
{
fn
create
(
file
:
&
Path
)
->
Self
;
...
...
@@ -19,21 +19,24 @@ pub trait MedalConnection {
//fn login(&self, session: &SessionUser, username: String, password: String) -> Result<String,()>;
fn
login
(
&
self
,
session
:
Option
<&
str
>
,
username
:
&
str
,
password
:
&
str
)
->
Result
<
String
,()
>
;
fn
login_with_code
(
&
self
,
session
:
Option
<&
str
>
,
logincode
:
&
str
)
->
Result
<
String
,()
>
;
fn
login_foreign
(
&
self
,
session
:
Option
<&
str
>
,
foreign_id
:
u32
,
foreign_type
:
functions
::
UserType
,
firstname
:
&
str
,
lastname
:
&
str
)
->
Result
<
String
,()
>
;
fn
create_user_with_groupcode
(
&
self
,
session
:
Option
<&
str
>
,
groupcode
:
&
str
)
->
Result
<
String
,()
>
;
fn
login
(
&
self
,
session
:
Option
<&
str
>
,
username
:
&
str
,
password
:
&
str
)
->
Result
<
String
,
()
>
;
fn
login_with_code
(
&
self
,
session
:
Option
<&
str
>
,
logincode
:
&
str
)
->
Result
<
String
,
()
>
;
fn
login_foreign
(
&
self
,
session
:
Option
<&
str
>
,
foreign_id
:
u32
,
foreign_type
:
functions
::
UserType
,
firstname
:
&
str
,
lastname
:
&
str
)
->
Result
<
String
,
()
>
;
fn
create_user_with_groupcode
(
&
self
,
session
:
Option
<&
str
>
,
groupcode
:
&
str
)
->
Result
<
String
,
()
>
;
fn
logout
(
&
self
,
session
:
&
str
);
fn
load_submission
(
&
self
,
session
:
&
SessionUser
,
task
:
u32
,
subtask
:
Option
<&
str
>
)
->
Option
<
Submission
>
;
fn
submit_submission
(
&
self
,
submission
:
Submission
);
fn
get_grade_by_submission
(
&
self
,
submission_id
:
u32
)
->
Grade
;
fn
get_contest_groups_grades
(
&
self
,
session_id
:
u32
,
contest_id
:
u32
)
->
(
Vec
<
String
>
,
Vec
<
(
Group
,
Vec
<
(
UserInfo
,
Vec
<
Grade
>
)
>
)
>
);
fn
get_contest_groups_grades
(
&
self
,
session_id
:
u32
,
contest_id
:
u32
)
->
(
Vec
<
String
>
,
Vec
<
(
Group
,
Vec
<
(
UserInfo
,
Vec
<
Grade
>
)
>
)
>
);
fn
get_contest_user_grades
(
&
self
,
session
:
String
,
contest_id
:
u32
)
->
Vec
<
Grade
>
;
fn
get_contest_list
(
&
self
)
->
Vec
<
Contest
>
;
fn
get_contest_by_id
(
&
self
,
contest_id
:
u32
)
->
Contest
;
fn
get_contest_by_id_complete
(
&
self
,
contest_id
:
u32
)
->
Contest
;
fn
get_contest_by_id_complete
(
&
self
,
contest_id
:
u32
)
->
Contest
;
fn
get_participation
(
&
self
,
session
:
&
str
,
contest_id
:
u32
)
->
Option
<
Participation
>
;
fn
new_participation
(
&
self
,
session
:
&
str
,
contest_id
:
u32
)
->
Result
<
Participation
,
()
>
;
fn
get_task_by_id
(
&
self
,
task_id
:
u32
)
->
Task
;
...
...
@@ -48,7 +51,6 @@ pub trait MedalConnection {
fn
get_group_complete
(
&
self
,
group_id
:
u32
)
->
Option
<
Group
>
;
}
pub
trait
MedalObject
<
T
:
MedalConnection
>
{
fn
save
(
&
mut
self
,
conn
:
&
T
);
}
src/db_conn_sqlite.rs
View file @
26effac5
This diff is collapsed.
Click to expand it.
src/db_objects.rs
View file @
26effac5
extern
crate
time
;
use
self
::
time
::{
Timespec
,
Duration
};
use
self
::
time
::{
Duration
,
Timespec
};
#[derive(Clone)]
pub
struct
SessionUser
{
...
...
@@ -11,7 +10,7 @@ pub struct SessionUser {
pub
last_login
:
Option
<
Timespec
>
,
pub
last_activity
:
Option
<
Timespec
>
,
pub
permanent_login
:
bool
,
pub
username
:
Option
<
String
>
,
pub
password
:
Option
<
String
>
,
pub
salt
:
Option
<
String
>
,
...
...
@@ -51,7 +50,7 @@ pub struct Group {
pub
groupcode
:
String
,
pub
tag
:
String
,
pub
admin
:
u32
,
pub
members
:
Vec
<
SessionUser
>
pub
members
:
Vec
<
SessionUser
>
,
}
pub
struct
Contest
{
...
...
@@ -66,7 +65,6 @@ pub struct Contest {
pub
taskgroups
:
Vec
<
Taskgroup
>
,
}
pub
struct
Taskgroup
{
pub
id
:
Option
<
u32
>
,
pub
contest
:
u32
,
...
...
@@ -81,7 +79,6 @@ pub struct Task {
pub
stars
:
u8
,
}
pub
struct
Submission
{
pub
id
:
Option
<
u32
>
,
pub
session_user
:
u32
,
...
...
@@ -109,63 +106,78 @@ pub struct Participation {
pub
start
:
Timespec
,
}
pub
trait
HasId
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
;
fn
set_id
(
&
mut
self
,
id
:
u32
);
}
impl
HasId
for
Submission
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
{
self
.id
}
fn
set_id
(
&
mut
self
,
id
:
u32
)
{
self
.id
=
Some
(
id
);}
}
impl
HasId
for
Task
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
{
self
.id
}
fn
set_id
(
&
mut
self
,
id
:
u32
)
{
self
.id
=
Some
(
id
);}
}
impl
HasId
for
Taskgroup
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
{
self
.id
}
fn
set_id
(
&
mut
self
,
id
:
u32
)
{
self
.id
=
Some
(
id
);}
}
impl
HasId
for
Contest
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
{
self
.id
}
fn
set_id
(
&
mut
self
,
id
:
u32
)
{
self
.id
=
Some
(
id
);}
}
impl
HasId
for
Group
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
{
self
.id
}
fn
set_id
(
&
mut
self
,
id
:
u32
)
{
self
.id
=
Some
(
id
);}
}
pub
trait
HasId
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
;
fn
set_id
(
&
mut
self
,
id
:
u32
);
}
impl
HasId
for
Submission
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
{
self
.id
}
fn
set_id
(
&
mut
self
,
id
:
u32
)
{
self
.id
=
Some
(
id
);
}
}
impl
HasId
for
Task
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
{
self
.id
}
fn
set_id
(
&
mut
self
,
id
:
u32
)
{
self
.id
=
Some
(
id
);
}
}
impl
HasId
for
Taskgroup
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
{
self
.id
}
fn
set_id
(
&
mut
self
,
id
:
u32
)
{
self
.id
=
Some
(
id
);
}
}
impl
HasId
for
Contest
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
{
self
.id
}
fn
set_id
(
&
mut
self
,
id
:
u32
)
{
self
.id
=
Some
(
id
);
}
}
impl
HasId
for
Group
{
fn
get_id
(
&
self
)
->
Option
<
u32
>
{
self
.id
}
fn
set_id
(
&
mut
self
,
id
:
u32
)
{
self
.id
=
Some
(
id
);
}
}
impl
Contest
{
pub
fn
new
(
location
:
String
,
filename
:
String
,
name
:
String
,
duration
:
u32
,
public
:
bool
,
start
:
Option
<
Timespec
>
,
end
:
Option
<
Timespec
>
)
->
Self
{
Contest
{
id
:
None
,
location
:
location
,
filename
:
filenam
e
,
name
:
name
,
duration
:
duration
,
public
:
public
,
start
:
start
,
end
:
end
,
taskgroups
:
Vec
::
new
()
,
}
}
pub
fn
new
(
location
:
String
,
filename
:
String
,
name
:
String
,
duration
:
u32
,
public
:
bool
,
start
:
Option
<
Timespec
>
,
end
:
Option
<
Timespec
>
)
->
Self
{
Contest
{
id
:
Non
e
,
location
:
location
,
filename
:
filename
,
name
:
name
,
duration
:
duration
,
public
:
public
,
start
:
start
,
end
:
end
,
taskgroups
:
Vec
::
new
()
}
}
}
impl
SessionUser
{
pub
fn
minimal
(
id
:
u32
,
session_token
:
String
,
csrf_token
:
String
)
->
Self
{
SessionUser
{
id
:
id
,
session_token
:
Some
(
session_token
),
csrf_token
:
csrf_token
,
last_login
:
None
,
last_activity
:
None
,
// now?
// müssen die überhaupt außerhalb der datenbankabstraktion sichtbar sein?
permanent_login
:
false
,
username
:
None
,
password
:
None
,
salt
:
None
,
logincode
:
None
,
email
:
None
,
email_unconfirmed
:
None
,
email_confirmationcode
:
None
,
firstname
:
None
,
lastname
:
None
,
street
:
None
,
zip
:
None
,
city
:
None
,
nation
:
None
,
grade
:
0
,
is_teacher
:
false
,
managed_by
:
None
,
pms_id
:
None
,
pms_school_id
:
None
,
}
SessionUser
{
id
:
id
,
session_token
:
Some
(
session_token
),
csrf_token
:
csrf_token
,
last_login
:
None
,
last_activity
:
None
,
// now?
// müssen die überhaupt außerhalb der datenbankabstraktion sichtbar sein?
permanent_login
:
false
,
username
:
None
,
password
:
None
,
salt
:
None
,
logincode
:
None
,
email
:
None
,
email_unconfirmed
:
None
,
email_confirmationcode
:
None
,
firstname
:
None
,
lastname
:
None
,
street
:
None
,
zip
:
None
,
city
:
None
,
nation
:
None
,
grade
:
0
,
is_teacher
:
false
,
managed_by
:
None
,
pms_id
:
None
,
pms_school_id
:
None
}
}
pub
fn
ensure_alive
(
self
)
->
Option
<
Self
>
{
...
...
@@ -173,41 +185,26 @@ impl SessionUser {
let
now
=
time
::
get_time
();
if
now
-
self
.last_activity
?
<
duration
{
Some
(
self
)
}
else
{
}
else
{
None
}
}
}
pub
fn
ensure_logged_in
(
self
)
->
Option
<
Self
>
{
if
self
.password
.is_some
()
||
self
.logincode
.is_some
()
||
self
.pms_id
.is_some
()
{
self
.ensure_alive
()
}
else
{
}
else
{
None
}
}
}
impl
Taskgroup
{
pub
fn
new
(
name
:
String
)
->
Self
{
Taskgroup
{
id
:
None
,
contest
:
0
,
name
:
name
,
tasks
:
Vec
::
new
(),
}
}
pub
fn
new
(
name
:
String
)
->
Self
{
Taskgroup
{
id
:
None
,
contest
:
0
,
name
:
name
,
tasks
:
Vec
::
new
()
}
}
}
impl
Task
{
pub
fn
new
(
location
:
String
,
stars
:
u8
)
->
Self
{
Task
{
id
:
None
,
taskgroup
:
0
,
location
:
location
,
stars
:
stars
,
}
}
Task
{
id
:
None
,
taskgroup
:
0
,
location
:
location
,
stars
:
stars
}
}
}
src/functions.rs
View file @
26effac5
This diff is collapsed.
Click to expand it.
src/main.rs
View file @
26effac5
...
...
@@ -7,44 +7,44 @@ extern crate router;
#[macro_use]
extern
crate
serde_derive
;
extern
crate
structopt
;
extern
crate
rusqlite
;
extern
crate
handlebars_iron
;
extern
crate
iron_sessionstorage
;
extern
crate
urlencoded
;
extern
crate
time
;
extern
crate
persistent
;
extern
crate
rand
;
extern
crate
mount
;
extern
crate
staticfile
;
extern
crate
handlebars_iron
;
extern
crate
serde_json
;
extern
crate
params
;
extern
crate
persistent
;
extern
crate
rand
;
extern
crate
reqwest
;
extern
crate
rusqlite
;
extern
crate
serde_json
;
extern
crate
serde_yaml
;
extern
crate
staticfile
;
extern
crate
structopt
;
extern
crate
time
;
extern
crate
urlencoded
;
use
rusqlite
::
Connection
;
mod
db_apply_migrations
;
mod
db_conn_sqlite
;
mod
db_conn
;
mod
db_conn_sqlite
;
mod
db_objects
;
use
functions
::
SetPassword
;
// TODO: Refactor, so we don't need to take this from there!
use
db_conn
::{
MedalConnection
,
MedalObject
};
use
functions
::
SetPassword
;
// TODO: Refactor, so we don't need to take this from there!
use
db_objects
::
*
;
mod
webfw_iron
;
mod
configreader_yaml
;
mod
webfw_iron
;
use
webfw_iron
::
start_server
;
mod
functions
;
use
std
::
path
;
use
std
::
fs
;
use
std
::
path
;
use
std
::
path
::{
Path
,
PathBuf
};
use
std
::
path
::{
Path
,
PathBuf
};
use
structopt
::
StructOpt
;
#[derive(Serialize,
Deserialize,
Clone,
Default)]
...
...
@@ -65,7 +65,7 @@ fn read_config_from_file(file: &Path) -> Config {
println!
(
"Reading configuration file '{}'"
,
file
.to_str
()
.unwrap_or
(
"<Encoding error>"
));
let
mut
config
:
Config
=
if
let
Ok
(
mut
file
)
=
fs
::
File
::
open
(
file
)
{
let
mut
config
:
Config
=
if
let
Ok
(
mut
file
)
=
fs
::
File
::
open
(
file
)
{
let
mut
contents
=
String
::
new
();
file
.read_to_string
(
&
mut
contents
)
.unwrap
();
serde_json
::
from_str
(
&
contents
)
.unwrap
()
...
...
@@ -74,9 +74,15 @@ fn read_config_from_file(file: &Path) -> Config {
Default
::
default
()
};
if
config
.host
.is_none
()
{
config
.host
=
Some
(
"[::]"
.to_string
())}
if
config
.port
.is_none
()
{
config
.port
=
Some
(
8080
)}
if
config
.self_url
.is_none
()
{
config
.self_url
=
Some
(
"http://localhost:8080"
.to_string
())}
if
config
.host
.is_none
()
{
config
.host
=
Some
(
"[::]"
.to_string
())
}
if
config
.port
.is_none
()
{
config
.port
=
Some
(
8080
)
}
if
config
.self_url
.is_none
()
{
config
.self_url
=
Some
(
"http://localhost:8080"
.to_string
())
}
println!
(
"OAuth providers will be told to redirect to {}"
,
config
.self_url
.as_ref
()
.unwrap
());
...
...
@@ -103,8 +109,6 @@ struct Opt {
resetadminpw
:
bool
,
}
fn
read_contest
(
p
:
&
path
::
PathBuf
)
->
Option
<
Contest
>
{
use
std
::
fs
::
File
;
use
std
::
io
::
Read
;
...
...
@@ -113,7 +117,9 @@ fn read_contest(p: &path::PathBuf) -> Option<Contest> {
let
mut
contents
=
String
::
new
();
file
.read_to_string
(
&
mut
contents
)
.unwrap
();
configreader_yaml
::
parse_yaml
(
&
contents
,
p
.file_name
()
.to_owned
()
?
.to_str
()
?
,
&
format!
(
"{}/"
,
p
.parent
()
.unwrap
()
.to_str
()
?
))
configreader_yaml
::
parse_yaml
(
&
contents
,
p
.file_name
()
.to_owned
()
?
.to_str
()
?
,
&
format!
(
"{}/"
,
p
.parent
()
.unwrap
()
.to_str
()
?
))
}
fn
get_all_contest_info
(
task_dir
:
&
str
)
->
Vec
<
Contest
>
{
...
...
@@ -130,19 +136,20 @@ fn get_all_contest_info(task_dir: &str) -> Vec<Contest> {
};
};
let
mut
contests
=
Vec
::
new
();
match
fs
::
read_dir
(
task_dir
)
{
Err
(
why
)
=>
println!
(
"Error opening tasks directory! {:?}"
,
why
.kind
()),
Ok
(
paths
)
=>
for
path
in
paths
{
walk_me_recursively
(
&
path
.unwrap
()
.path
(),
&
mut
contests
);
},
Ok
(
paths
)
=>
{
for
path
in
paths
{
walk_me_recursively
(
&
path
.unwrap
()
.path
(),
&
mut
contests
);
}
}
};
contests
}
fn
refresh_all_contests
(
conn
:
&
mut
Connection
)
{
fn
refresh_all_contests
(
conn
:
&
mut
Connection
)
{
let
v
=
get_all_contest_info
(
"tasks/"
);
for
mut
contest_info
in
v
{
...
...
@@ -155,22 +162,25 @@ fn add_admin_user(conn: &mut Connection, resetpw: bool) {
None
=>
{
print!
(
"New Database. Creating new admin user with credentials 'admin':"
);
conn
.new_session
()
},
}
Some
(
user
)
=>
{
if
!
resetpw
{
return
return
;
}
print!
(
"Request to reset admin password. Set credentials 'admin':"
);
user
}
};
use
rand
::{
thread_rng
,
Rng
,
distributions
::
Alphanumeric
};
use
rand
::{
distributions
::
Alphanumeric
,
thread_rng
,
Rng
};
let
password
:
String
=
thread_rng
()
.sample_iter
(
&
Alphanumeric
)
.filter
(|
x
|
{
let
x
=
*
x
;
!
(
x
==
'l'
||
x
==
'I'
||
x
==
'1'
||
x
==
'O'
||
x
==
'o'
||
x
==
'0'
)})
.take
(
8
)
.collect
();
.filter
(|
x
|
{
let
x
=
*
x
;
!
(
x
==
'l'
||
x
==
'I'
||
x
==
'1'
||
x
==
'O'
||
x
==
'o'
||
x
==
'0'
)
})
.take
(
8
)
.collect
();
print!
(
"'{}' …"
,
&
password
);
admin
.username
=
Some
(
"admin"
.into
());
...
...
@@ -189,12 +199,22 @@ fn main() {
let
mut
config
=
read_config_from_file
(
&
opt
.configfile
);
if
opt
.databasefile
.is_some
()
{
config
.database_file
=
opt
.databasefile
;
}
if
opt
.port
.is_some
()
{
config
.port
=
opt
.port
;
}
if
opt
.databasefile
.is_some
()
{
config
.database_file
=
opt
.databasefile
;
}
if
opt
.port
.is_some
()
{
config
.port
=
opt
.port
;
}
let
mut
conn
=
match
config
.database_file
{
Some
(
ref
path
)
=>
{
println!
(
"Using database file {}"
,
&
path
.to_str
()
.unwrap_or
(
"<unprintable filename>"
));
Connection
::
create
(
path
)},
None
=>
{
println!
(
"Using default database file ./medal.db"
);
Connection
::
create
(
&
Path
::
new
(
"medal.db"
))},
Some
(
ref
path
)
=>
{
println!
(
"Using database file {}"
,
&
path
.to_str
()
.unwrap_or
(
"<unprintable filename>"
));
Connection
::
create
(
path
)
}
None
=>
{
println!
(
"Using default database file ./medal.db"
);
Connection
::
create
(
&
Path
::
new
(
"medal.db"
))
}
};
db_apply_migrations
::
test
(
&
mut
conn
);
...
...
@@ -205,22 +225,21 @@ fn main() {
match
start_server
(
conn
,
config
)
{
Ok
(
_
)
=>
println!
(
"Server started"
),
Err
(
_
)
=>
println!
(
"Error on server start …"
)
Err
(
_
)
=>
println!
(
"Error on server start …"
)
,
};
println!
(
"Could not run server. Is the port already in use?"
);
}
#[cfg(test)]
mod
tests
{
use
super
::
*
;
use
std
::
io
::
Read
;
fn
start_server_and_fn
<
F
>
(
port
:
u16
,
set_user
:
Option
<
(
String
,
String
)
>
,
f
:
F
)
where
F
:
FnOnce
()
{