Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
adc2019-system
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
adc2019
adc2019-system
Commits
a1c46b41
Commit
a1c46b41
authored
Jul 12, 2019
by
Kento HASEGAWA
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement host and solver function/GUIs
parent
839d7369
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
516 additions
and
345 deletions
+516
-345
adc2019system.py
adc2019system.py
+1
-0
main.py
main.py
+13
-2
host.py
roles/host.py
+178
-13
solver.py
roles/solver.py
+84
-0
main.py
solvers/SampleSolver/main.py
+6
-0
adc2019.css
static/css/adc2019.css
+20
-13
adc2019.js
static/js/adc2019.js
+78
-261
index.html
templates/index.html
+2
-26
part_question_status.html
templates/part_question_status.html
+43
-27
part_questions.html
templates/part_questions.html
+3
-3
part_system_summary.html
templates/part_system_summary.html
+43
-0
data.py
utils/data.py
+45
-0
No files found.
adc2019system.py
View file @
a1c46b41
...
@@ -33,6 +33,7 @@ def set_role(role_name, config_data):
...
@@ -33,6 +33,7 @@ def set_role(role_name, config_data):
def
call_api
(
method
,
cmd
,
params
):
def
call_api
(
method
,
cmd
,
params
):
print
(
f
'I: API Received: {cmd}'
)
if
role
is
not
None
:
if
role
is
not
None
:
return
role
.
call_api
(
method
,
cmd
,
params
)
return
role
.
call_api
(
method
,
cmd
,
params
)
else
:
else
:
...
...
main.py
View file @
a1c46b41
...
@@ -24,6 +24,14 @@ def webui_template_questions():
...
@@ -24,6 +24,14 @@ def webui_template_questions():
else
:
else
:
return
abort
(
404
)
return
abort
(
404
)
@
webui
.
route
(
'/template/system-summary'
)
def
webui_template_workers
():
if
(
adc2019system
.
role
is
not
None
)
and
(
adc2019system
.
role
.
type
==
'host'
):
workers
=
adc2019system
.
role
.
get_workers
()
return
render_template
(
'part_system_summary.html'
,
workers
=
workers
)
else
:
return
abort
(
404
)
@
webui
.
route
(
'/template/question/<name>'
)
@
webui
.
route
(
'/template/question/<name>'
)
def
webui_template_question_status
(
name
=
None
):
def
webui_template_question_status
(
name
=
None
):
...
@@ -31,8 +39,11 @@ def webui_template_question_status(name=None):
...
@@ -31,8 +39,11 @@ def webui_template_question_status(name=None):
return
abort
(
404
)
return
abort
(
404
)
if
(
adc2019system
.
role
is
not
None
)
and
(
adc2019system
.
role
.
type
==
'host'
):
if
(
adc2019system
.
role
is
not
None
)
and
(
adc2019system
.
role
.
type
==
'host'
):
questions
=
adc2019system
.
role
.
get_questions
()
question
=
adc2019system
.
role
.
get_question
(
name
)
return
render_template
(
'part_question_status.html'
,
questions
=
questions
)
if
question
is
None
:
return
abort
(
404
)
else
:
return
render_template
(
'part_question_status.html'
,
question
=
question
)
else
:
else
:
return
abort
(
404
)
return
abort
(
404
)
...
...
roles/host.py
View file @
a1c46b41
import
glob
import
glob
import
json
import
json
import
sys
import
threading
import
time
import
requests
import
requests
from
utils
import
Question
from
utils
import
Question
...
@@ -10,11 +13,13 @@ class Host(object):
...
@@ -10,11 +13,13 @@ class Host(object):
self
.
type
=
'host'
self
.
type
=
'host'
self
.
config
=
config
self
.
config
=
config
self
.
questions
=
[]
self
.
questions
=
dict
()
self
.
_load_questions
(
config
[
'question_path'
])
self
.
worker_manager
=
None
self
.
request
=
dict
()
self
.
processing_request
=
None
self
.
worker
=
dict
(
)
self
.
_load_questions
(
config
[
'question_path'
]
)
self
.
setup_workers
()
self
.
_
setup_workers
()
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"Host"
return
"Host"
...
@@ -28,39 +33,199 @@ class Host(object):
...
@@ -28,39 +33,199 @@ class Host(object):
for
v
in
questions_path
:
for
v
in
questions_path
:
question
=
Question
(
v
)
question
=
Question
(
v
)
_key
=
question
.
name
self
.
questions
.
append
(
question
)
self
.
questions
[
_key
]
=
question
def
setup_workers
(
self
):
def
_
setup_workers
(
self
):
self
.
worker_manager
=
WorkerManager
(
self
.
config
[
'address'
])
for
v
in
self
.
config
[
'worker'
]:
for
v
in
self
.
config
[
'worker'
]:
worker_name
=
v
[
'name'
]
self
.
worker_manager
.
add_worker
(
v
)
self
.
worker
[
worker_name
]
=
Worker
(
v
)
def
get_workers
(
self
):
return
self
.
worker_manager
.
get_workers
()
def
distribute_question
(
self
,
question_key
):
question
=
self
.
get_question
(
question_key
)
if
question
is
None
:
return
{
'status'
:
'key error'
}
else
:
request
=
Request
(
self
.
worker_manager
,
question
.
get_dict
())
request_id
=
request
.
get_id
()
self
.
request
[
request_id
]
=
request
request
.
broadcast
()
return
{
'status'
:
'processed'
,
'request_id'
:
request_id
,
'timeout'
:
request
.
timeout
}
def
get_questions
(
self
):
def
get_questions
(
self
):
return
self
.
questions
return
self
.
questions
def
get_question
(
self
,
_key
):
if
_key
in
self
.
questions
:
return
self
.
questions
[
_key
]
else
:
return
None
def
store_solution
(
self
,
solution
):
# request_idをチェックする機能もつくておく
request_id
=
solution
[
'request_id'
]
if
request_id
in
self
.
request
:
self
.
request
[
request_id
]
.
store_response
(
solution
)
else
:
print
(
f
'W: Unknown request_id: {request_id}'
)
question_key
=
solution
[
'question'
]
if
question_key
in
self
.
questions
:
self
.
questions
[
question_key
]
.
put_solution
(
solution
)
return
{
'status'
:
'registered'
}
else
:
return
{
'status'
:
'error'
}
def
get_request_status
(
self
,
request_id
):
if
request_id
in
self
.
request
:
return
self
.
request
[
request_id
]
.
get_status
()
else
:
return
{
'status'
:
'unknown request'
}
def
call_api
(
self
,
method
,
cmd
,
params
):
def
call_api
(
self
,
method
,
cmd
,
params
):
if
cmd
==
'role'
:
if
cmd
==
'role'
:
# サーバの役割確認
return
{
'role'
:
self
.
type
}
return
{
'role'
:
self
.
type
}
elif
cmd
==
'question/solve'
:
# params['question']に指定された問題をworkerに配信
question_key
=
params
[
'question'
]
return
self
.
distribute_question
(
question_key
)
elif
cmd
==
'question/solution'
:
self
.
store_solution
(
params
)
return
{
'status'
:
'received'
}
elif
cmd
==
'request/status'
:
request_id
=
float
(
params
[
'request_id'
])
return
self
.
get_request_status
(
request_id
)
else
:
else
:
return
None
return
None
class
WorkerManager
(
object
):
def
__init__
(
self
,
host_address
):
self
.
workers
=
dict
()
self
.
host
=
host_address
def
add_worker
(
self
,
conf
):
worker_conf
=
dict
()
worker_conf
.
update
(
conf
)
worker_conf
[
'host'
]
=
self
.
host
worker_address
=
worker_conf
[
'address'
]
self
.
workers
[
worker_address
]
=
Worker
(
worker_conf
)
def
get_workers
(
self
):
return
self
.
workers
def
broadcast
(
self
,
cmd
,
params
):
threads
=
[]
def
_sender
(
_worker
,
_cmd
,
_params
):
_worker
.
post
(
_cmd
,
_params
)
for
k
,
v
in
self
.
workers
.
items
():
_th
=
threading
.
Thread
(
name
=
v
.
address
,
target
=
_sender
,
args
=
(
v
,
cmd
,
params
),
daemon
=
True
)
_th
.
start
()
threads
.
append
(
_th
)
class
Worker
(
object
):
class
Worker
(
object
):
def
__init__
(
self
,
params
):
def
__init__
(
self
,
params
):
self
.
address
=
params
[
'address'
]
self
.
address
=
params
[
'address'
]
self
.
name
=
params
[
'name'
]
self
.
name
=
params
[
'name'
]
self
.
host
=
params
[
'host'
]
self
.
role
=
None
self
.
role
=
None
self
.
params
=
params
self
.
status
=
'Setting up'
self
.
set_role
(
params
[
'role'
])
self
.
set_role
(
params
[
'role'
])
def
post
(
self
,
path
,
data
):
def
post
(
self
,
path
,
data
):
response
=
requests
.
post
(
try
:
f
'http://{self.address}/api/{path}'
,
response
=
requests
.
post
(
json
.
dumps
(
data
),
f
'http://{self.address}/api/{path}'
,
headers
=
{
'Content-Type'
:
'application/json'
})
json
.
dumps
(
data
),
headers
=
{
'Content-Type'
:
'application/json'
},
timeout
=
2
)
print
(
f
"I: Post to {self.address}, API Cmd: {path}"
)
except
Exception
as
e
:
# sys.stderr.write(str(e) + "\n")
print
(
f
"W: Failed to connect {self.address}"
)
self
.
status
=
'Not connected'
response
=
None
return
response
return
response
def
set_role
(
self
,
role
):
def
set_role
(
self
,
role
):
r
=
self
.
post
(
'role'
,
{
'role'
:
role
})
r
=
self
.
post
(
'role'
,
self
.
params
)
class
Request
(
object
):
def
__init__
(
self
,
worker_manager
,
data
,
timeout
=
10
):
self
.
worker_manager
=
worker_manager
self
.
data
=
data
self
.
timeout
=
timeout
self
.
request_id
=
time
.
time
()
self
.
broadcast_time
=
None
self
.
response
=
dict
()
@
property
def
request_data
(
self
):
data
=
self
.
data
data
[
'request_id'
]
=
self
.
request_id
data
[
'timeout'
]
=
self
.
timeout
return
data
def
get_id
(
self
):
return
self
.
request_id
def
get_dict
(
self
):
return
self
.
request_data
def
store_response
(
self
,
data
):
# TODO: 1つのrequest_idに対し同一のworkerから2つ以上答えが返ってきた場合の例外処理
worker
=
data
[
'worker'
]
self
.
response
[
worker
]
=
data
def
get_status
(
self
):
all_workers
=
self
.
worker_manager
.
get_workers
()
.
keys
()
worker_count
=
0
response_count
=
0
for
v
in
all_workers
:
worker_count
+=
1
if
v
in
self
.
response
:
response_count
+=
1
status
=
''
if
worker_count
==
response_count
:
status
=
'done'
elif
time
.
time
()
-
self
.
broadcast_time
>
self
.
timeout
:
status
=
'timeout'
else
:
status
=
'processing'
return
{
'status'
:
status
,
'workers'
:
worker_count
,
'solutions'
:
response_count
}
def
broadcast
(
self
):
self
.
worker_manager
.
broadcast
(
'solve'
,
self
.
request_data
)
self
.
broadcast_time
=
time
.
time
()
roles/solver.py
View file @
a1c46b41
import
importlib
import
json
import
os
import
requests
import
sys
import
time
import
threading
class
StoppableThread
(
threading
.
Thread
):
def
__init__
(
self
,
target
,
args
=
()):
super
(
StoppableThread
,
self
)
.
__init__
(
target
=
target
,
args
=
args
)
self
.
_status
=
'running'
def
stop
(
self
):
if
self
.
_status
==
'running'
:
self
.
_status
=
'stopping'
def
stopped
(
self
):
self
.
_status
=
'stopped'
def
is_running
(
self
):
return
(
self
.
_status
==
'running'
)
def
is_stopping
(
self
):
return
(
self
.
_status
==
'stopping'
)
def
is_stopped
(
self
):
return
(
self
.
_status
==
'stopped'
)
class
Solver
(
object
):
class
Solver
(
object
):
def
__init__
(
self
,
config
):
def
__init__
(
self
,
config
):
self
.
type
=
'solver'
self
.
type
=
'solver'
self
.
host
=
config
[
'host'
]
self
.
address
=
config
[
'address'
]
self
.
name
=
config
[
'name'
]
self
.
solver
=
importlib
.
import_module
(
f
"solvers.{config['solver']}"
)
self
.
thread
=
None
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"Solver"
return
"Solver"
def
solve
(
self
,
params
):
start_time
=
time
.
time
()
solution
=
self
.
solver
.
solve
(
params
)
end_time
=
time
.
time
()
self
.
thread
.
stopped
()
elapsed_time
=
end_time
-
start_time
if
not
'elapsed_time'
in
solution
:
solution
[
'elapsed_time'
]
=
elapsed_time
self
.
submit_solution
(
params
,
solution
)
self
.
thread
=
None
return
True
def
post
(
self
,
path
,
data
):
response
=
requests
.
post
(
f
'http://{self.host}/api/{path}'
,
json
.
dumps
(
data
),
headers
=
{
'Content-Type'
:
'application/json'
})
print
(
f
"I: Post to {self.host}, API Cmd: {path}"
)
return
response
def
submit_solution
(
self
,
params
,
solution
):
data
=
{
'request_id'
:
params
[
'request_id'
],
'question'
:
params
[
'name'
],
'worker'
:
self
.
address
}
data
.
update
(
solution
)
self
.
post
(
'question/solution'
,
data
)
def
start_solver
(
self
,
params
):
if
self
.
thread
is
None
:
print
(
"I: Solver started"
)
self
.
thread
=
StoppableThread
(
target
=
self
.
solve
,
args
=
(
params
,
))
self
.
thread
.
start
()
return
{
'status'
:
'started'
}
else
:
return
{
'status'
:
'busy'
}
def
stop_solver
():
if
self
.
thread
is
not
None
:
if
self
.
thread
.
is_running
():
self
.
thread
.
stop
()
self
.
thread
.
join
()
self
.
thread
=
None
def
call_api
(
self
,
method
,
cmd
,
params
):
def
call_api
(
self
,
method
,
cmd
,
params
):
if
cmd
==
'role'
:
if
cmd
==
'role'
:
return
{
'role'
:
self
.
type
}
return
{
'role'
:
self
.
type
}
elif
cmd
==
'solve'
:
return
self
.
start_solver
(
params
)
else
:
else
:
return
None
return
None
solvers/SampleSolver/main.py
0 → 100644
View file @
a1c46b41
def
solve
(
params
):
print
(
"This is a sample solver."
)
return
{
'solution'
:
'aaa!'
}
def
main
(
params
):
solve
(
a
)
static/css/adc2019.css
View file @
a1c46b41
...
@@ -15,30 +15,30 @@ body{
...
@@ -15,30 +15,30 @@ body{
background-color
:
rgba
(
0
,
0
,
50
,
.5
);
background-color
:
rgba
(
0
,
0
,
50
,
.5
);
}
}
#question-
table-wrapp
er
{
#question-
list-contain
er
{
height
:
calc
(
100vh
-
50px
);
height
:
calc
(
100vh
-
50px
);
overflow-y
:
scroll
;
overflow-y
:
scroll
;
overflow-x
:
hidden
;
overflow-x
:
hidden
;
}
}
#question-
table-wrapp
er
th
.large-cell
,
#question-
list-contain
er
th
.large-cell
,
#question-
table-wrapp
er
td
.large-cell
{
#question-
list-contain
er
td
.large-cell
{
width
:
24%
;
width
:
24%
;
}
}
#question-
table-wrapp
er
th
.small-cell
,
#question-
list-contain
er
th
.small-cell
,
#question-
table-wrapp
er
td
.small-cell
{
#question-
list-contain
er
td
.small-cell
{
width
:
14%
;
width
:
14%
;
}
}
#question-
table-wrapp
er
tr
.question-row
,
#question-
list-contain
er
tr
.question-row
,
#question-
table-wrapp
er
tr
.question-row
td
{
#question-
list-contain
er
tr
.question-row
td
{
cursor
:
pointer
;
cursor
:
pointer
;
}
}
#question-
table-wrapp
er
tr
.question-row.q-selected
{
#question-
list-contain
er
tr
.question-row.q-selected
{
background-color
:
rgba
(
200
,
100
,
100
,
.3
);
background-color
:
rgba
(
200
,
100
,
100
,
.3
);
}
}
#question-
table-wrapp
er
tr
.question-row
:hover
{
#question-
list-contain
er
tr
.question-row
:hover
{
background-color
:
rgba
(
200
,
100
,
100
,
.15
);
background-color
:
rgba
(
200
,
100
,
100
,
.15
);
}
}
...
@@ -60,16 +60,23 @@ body{
...
@@ -60,16 +60,23 @@ body{
display
:
inline-block
;
display
:
inline-block
;
}
}
#client-control-pane
tr
.
answer
-detail-row
,
#client-control-pane
tr
.
solution
-detail-row
,
#client-control-pane
tr
.
answer
-detail-row
td
{
#client-control-pane
tr
.
solution
-detail-row
td
{
cursor
:
pointer
;
cursor
:
pointer
;
}
}
#client-control-pane
tr
.
answer
-detail-row
:hover
{
#client-control-pane
tr
.
solution
-detail-row
:hover
{
background-color
:
rgba
(
200
,
100
,
100
,
.15
);
background-color
:
rgba
(
200
,
100
,
100
,
.15
);
}
}
#client-control-pane
tr
.
answer
-detail-row.submit-answer
{
#client-control-pane
tr
.
solution
-detail-row.submit-answer
{
background-color
:
rgba
(
100
,
200
,
100
,
.3
);
background-color
:
rgba
(
100
,
200
,
100
,
.3
);
}
}
#content-left
h3
{
display
:
inline-block
;
}
#content-right
h4
.inline-heading
{
display
:
inline-block
;
}
static/js/adc2019.js
View file @
a1c46b41
This diff is collapsed.
Click to expand it.
templates/index.html
View file @
a1c46b41
...
@@ -12,30 +12,6 @@
...
@@ -12,30 +12,6 @@
<script
src=
"/static/js/bootstrap.bundle.min.js"
></script>
<script
src=
"/static/js/bootstrap.bundle.min.js"
></script>
<script
src=
"/static/js/d3.min.js"
></script>
<script
src=
"/static/js/d3.min.js"
></script>
<script
src=
"/static/js/adc2019.js"
></script>
<script
src=
"/static/js/adc2019.js"
></script>
<style>
.axis
path
{
display
:
none
;
}
.axis
line
{
stroke-opacity
:
0.3
;
shape-rendering
:
crispEdges
;
}
input
[
type
=
"range"
]
{
right
:
0
;
top
:
0
;
position
:
absolute
;
}
svg
,
#chart-container
{
width
:
100%
;
height
:
100vh
;
display
:
block
;
}
#content-left
h3
{
display
:
inline-block
;
}
</style>
</head>
</head>
<body>
<body>
...
@@ -44,7 +20,7 @@ svg,
...
@@ -44,7 +20,7 @@ svg,
<div
id=
"content-wrapper"
class=
"container-fluid"
>
<div
id=
"content-wrapper"
class=
"container-fluid"
>
<div
id=
"content-row"
class=
"row"
>
<div
id=
"content-row"
class=
"row"
>
<div
class=
"col-
4
"
id=
"content-left"
>
<div
class=
"col-
5
"
id=
"content-left"
>
<h3>
問題一覧
</h3>
<h3>
問題一覧
</h3>
<span><a
href=
"/#"
id=
"view-server-status-button"
>
システム状況
</a></span>
<span><a
href=
"/#"
id=
"view-server-status-button"
>
システム状況
</a></span>
<div
id=
"question-list-container"
>
<div
id=
"question-list-container"
>
...
@@ -52,7 +28,7 @@ svg,
...
@@ -52,7 +28,7 @@ svg,
</div>
</div>
</div>
</div>
<div
class=
"col-
8
"
id=
"content-right"
>
<div
class=
"col-
7
"
id=
"content-right"
>
<div
id=
"status-container"
>
<div
id=
"status-container"
>
</div>
</div>
...
...
templates/part_question_status.html
View file @
a1c46b41
<div
class=
"row"
>
<div>
<div
class=
"col-4"
>
<!-- <div class="col-4"> -->
<h3>
【{{qname}}】
</h3>
<h3>
【{{question.name}}】
</h3>
{#% # if localmode %#}
{#% # if localmode %#}
<p>
<p>
<button
class=
"btn btn-primary btn-lg start-button"
type=
"button"
data-qname=
"{{qname}}"
>
Start
</button>
<button
class=
"btn btn-primary btn-lg start-button"
type=
"button"
data-qname=
"{{question.name}}"
>
Start
</button>
<button
class=
"btn btn-danger btn-lg stop-button"
type=
"button"
data-qname=
"all"
>
Stop
</button>
<button
class=
"btn btn-danger btn-lg stop-button"
type=
"button"
data-qname=
"all"
>
Stop
</button>
</p>
<button
class=
"btn btn-info btn-lg save-button"
type=
"button"
data-qname=
"{{question.name}}"
>
Save
</button>
<p>
<button
class=
"btn btn-success btn-lg submit-button"
type=
"button"
data-qname=
"{{question.name}}"
>
Up
</button>
<button
class=
"btn btn-info btn-lg save-button"
type=
"button"
data-qname=
"{{qname}}"
>
Save
</button>
</p>
<button
class=
"btn btn-success btn-lg submit-button"
type=
"button"
data-qname=
"{{qname}}"
>
Up
</button>
{#% else %#}
</p>
<!-- [View Only] -->
{#% else %#}
{#% endif %#}
<!-- [View Only] -->
<!-- <div class="col-8">
{#% endif %#}
</div>
<div
class=
"col-8"
>
<p>処理結果</p>
<p>処理結果</p>
<table class="table table-bordered">
<table class="table table-bordered">
<tr>
<tr>
<th>Client (Solver)</th>
<th>Client (Solver)</th>
<th>Status</th>
<th>Status</th>
</tr>
</tr>
<!--
{% for c in solvers %}
{% for c in solvers %}
<tr>
<tr>
<td>
<td>
{% if c|length > 3 %}
{% if c|length > 3 %}
...
@@ -34,9 +31,9 @@
...
@@ -34,9 +31,9 @@
</td>
</td>
<td>{{qdata.solver[c[0]]}}</td>
<td>{{qdata.solver[c[0]]}}</td>
</tr>
</tr>
{% endfor %}
-->
{% endfor %}
</table>
</table>
</div>
</div>
-->
</div>
</div>
<div>
<div>
...
@@ -47,23 +44,42 @@
...
@@ -47,23 +44,42 @@
<th>
Client
</th>
<th>
Client
</th>
<th>
Score
</th>
<th>
Score
</th>
</tr>
</tr>
<!-- {#% for k, v in qdata.answers.items() %#
}
{% for k, v in question.get_solutions().items() %
}
{#% if (qdata.best_json == k) and (v.answer != "") %#}
{#% if (qdata.best_json == k) and (v.answer != "") %#}
<
tr class="answer-detail-row submit-answer" data-json="{#{k}#}" data-qname="{#{qname}#}"
>
<
!-- <tr class="answer-detail-row submit-answer" data-json="{#{k}#}" data-qname="{#{qname}#}"> --
>
{#% else %#}
{#% else %#}
<tr class="
answer-detail-row" data-json="{#{k}#}" data-qname="{#{qname}#
}">
<tr
class=
"
solution-detail-row"
data-json=
"{{k}}"
data-qname=
"{{question.name}
}"
>
{#% endif %#}
{#% endif %#}
<td>{
#{v.timestamp}#
}</td>
<td>
{
{v.timestamp_str}
}
</td>
<td>{
#{v.solver}#
}</td>
<td>
{
{v.worker}
}
</td>
<td>
<td>
{#% if v.nlcheck == -1 %#}
{#% if v.nlcheck == -1 %#}
Not solved
<!-- Not solved -->
{#% else %#}
{#% else %#}
{#{v.nlcheck}#}
{#{v.nlcheck}#}
{#% endif %#}
{#% endif %#}
</td>
</td>
</tr>
</tr>
{
#% endfor %#} -->
{
% endfor %}
</table>
</table>
</div>
</div>
<div
class=
"modal fade"
id=
"solver-processing-modal"
tabindex=
"-1"
role=
"dialog"
aria-labelledby=
"solver-processing-modal-title"
aria-hidden=
"true"
>
<div
class=
"modal-dialog modal-dialog-centered modal-lg"
role=
"document"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
id=
"solver-processing-modal-title"
>
{{question.name}}
</h5>
<button
type=
"button"
class=
"close"
data-dismiss=
"modal"
aria-label=
"Close"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
処理中...
</div>
<div
class=
"modal-footer"
>
<button
type=
"button"
class=
"btn btn-secondary"
data-dismiss=
"modal"
>
Close
</button>
<button
type=
"button"
class=
"btn btn-primary"
>
Save changes
</button>
</div>
</div>
</div>
</div>
templates/part_questions.html
View file @
a1c46b41
...
@@ -2,16 +2,16 @@
...
@@ -2,16 +2,16 @@
<thead>
<thead>
<tr>
<tr>
<th
class=
"large-cell"
>
File Name
</th>
<th
class=
"large-cell"
>
File Name
</th>
<th
class=
"
large
-cell"
>
Size
</th>
<th
class=
"
small
-cell"
>
Size
</th>
<th
class=
"small-cell"
>
#Blocks
</th>
<th
class=
"small-cell"
>
#Blocks
</th>
<th
class=
"large-cell"
>
Status
</th>
<th
class=
"large-cell"
>
Status
</th>
</tr>
</tr>
</thead>
</thead>
<tbody>
<tbody>
{% for
v in questions
%}
{% for
k, v in questions.items()
%}
<tr
class=
"question-row"
data-qname=
"{{v.name}}"
>
<tr
class=
"question-row"
data-qname=
"{{v.name}}"
>
<td
class=
"large-cell"
>
{{v.name}}
</td>
<td
class=
"large-cell"
>
{{v.name}}
</td>
<td
class=
"
large
-cell"
>
{{v.size_str}}
</td>
<td
class=
"
small
-cell"
>
{{v.size_str}}
</td>
<td
class=
"small-cell"
>
{{v.block_num}}
</td>
<td
class=
"small-cell"
>
{{v.block_num}}
</td>
<td
class=
"large-cell"
>
{{v.status}}
</td>
<td
class=
"large-cell"
>
{{v.status}}
</td>
</tr>
</tr>
...
...
templates/part_system_summary.html
0 → 100644
View file @
a1c46b41
<h3>
システム状況
</h3>
<div
class=
"summary-section"
>
<h4
class=
'inline-heading'
>
動作モード
</h4>
<span>
{#% if local_mode %#}
Normal Mode
{#% else %#}
<!-- Viewer Mode -->
{#% endif %#}
</span>
</div>
<div
class=
"summary-section"
>
{#% if local_mode %#}
<h4
class=
'inline-heading'
>
自動運営システム
</h4>
<button
type=
"button"
class=
"btn btn-primary"
id=
"adccli-login-button"
>
Login
</button>
<button
type=
"button"
class=
"btn btn-light"
id=
"adccli-logout-button"
>
Logout
</button>
<button
type=
"button"
class=
"btn btn-info"
id=
"adccli-get-all-q"
>
問題DL
</button>
<span
id=
"adccli-status"
></span>
{#% endif %#}
</div>
<div
class=
"summary-section"
>
<h4>
Worker
</h4>
<table
class=
"table table-bordered"
id=
"workers-table"
>
<tr>
<th
class=
""
>
Worker
</th>
<th
class=
""
>
Role
</th>
<th
class=
""
>
Status
</th>
</tr>
{% for k, w in workers.items() %}
<tr
class=
"worker-status-row"
data-cname=
"{{w.name}}"
>
<td
class=
"worker-status-name"
>
{{w.name}} ({{w.address}})
</td>
<td
class=
""
>
{{w.role}}
</td>
<td
class=
"worker-status-value"
>
{{w.status}}
</td>
</tr>
{% endfor %}
</table>
</div>
utils/data.py
View file @
a1c46b41
import
datetime
import
os
import
os
import
time
import
uuid
class
Question
(
object
):
class
Question
(
object
):
...
@@ -9,6 +12,7 @@ class Question(object):
...
@@ -9,6 +12,7 @@ class Question(object):
self
.
size
=
(
0
,
0
)
self
.
size
=
(
0
,
0
)
self
.
block_num
=
0
self
.
block_num
=
0
self
.
status
=
'Ready'
self
.
status
=
'Ready'
self
.
solutions
=
dict
()
self
.
_load_question
(
path
)
self
.
_load_question
(
path
)
...
@@ -37,3 +41,44 @@ class Question(object):
...
@@ -37,3 +41,44 @@ class Question(object):
self
.
block_num
=
block_num
self
.
block_num
=
block_num
self
.
name
=
name
self
.
name
=
name
self
.
status
=
'Ready'
self
.
status
=
'Ready'
def
get_dict
(
self
):
return
{
'name'
:
self
.
name
,
'size'
:
self
.
size
,
'size_str'
:
self
.
size_str
,
'block_num'
:
self
.
block_num
,
'status'
:
self
.
status
}
def
put_solution
(
self
,
data
):
solution
=
Solution
(
data
)
solution_id
=
solution
.
get_id
()
print
(
f
'I: Put a solution: {solution_id}'
)
self
.
solutions
[
solution_id
]
=
solution
def
get_solutions
(
self
):
return
self
.
solutions
class
Solution
(
object
):
def
__init__
(
self
,
data
):
self
.
question
=
data
[
'question'
]
self
.
request_id
=
data
[
'request_id'
]
self
.
worker
=
data
[
'worker'
]
self
.
elapsed_time
=
data
[
'elapsed_time'
]
self
.
solution
=
data
[
'solution'
]
self
.
timestamp
=
time
.
time
()
self
.
_id
=
str
(
uuid
.
uuid4
())
def
get_id
(
self
):
return
self
.
_id
@
property
def
timestamp_str
(
self
):
dt
=
datetime
.
datetime
.
fromtimestamp
(
self
.
timestamp
,
datetime
.
timezone
(
datetime
.
timedelta
(
hours
=
9
)))
return
dt
.
strftime
(
'
%
H:
%
M:
%
S.
%
f'
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment