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
You need to sign in or sign up before continuing.
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