mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-10 09:23:58 +08:00
Refactor workflow_image_generation and move to service class
This commit is contained in:
parent
686f10cbd0
commit
47cc6a9d10
4 changed files with 103 additions and 116 deletions
|
@ -221,123 +221,8 @@ class Experiment < ApplicationRecord
|
|||
true
|
||||
end
|
||||
|
||||
# This method generate the workflow image and saves it as
|
||||
# experiment attachment
|
||||
def generate_workflow_img
|
||||
require 'graphviz'
|
||||
|
||||
graph = GraphViz.new(:G,
|
||||
type: :digraph,
|
||||
use: :neato)
|
||||
|
||||
graph[:size] = '4,4'
|
||||
graph.node[color: Constants::COLOR_ALTO,
|
||||
style: :filled,
|
||||
fontcolor: Constants::COLOR_EMPEROR,
|
||||
shape: 'circle',
|
||||
fontname: 'Arial',
|
||||
fontsize: '16.0']
|
||||
|
||||
graph.edge[color: Constants::COLOR_ALTO]
|
||||
|
||||
label = ''
|
||||
subg = {}
|
||||
|
||||
# Draw orphan modules
|
||||
my_modules.without_group.each do |my_module|
|
||||
graph
|
||||
.subgraph(rank: 'same')
|
||||
.add_nodes("Orphan-#{my_module.id}",
|
||||
label: label,
|
||||
pos: "#{my_module.x / 10},-#{my_module.y / 10}!")
|
||||
end
|
||||
|
||||
# Draw grouped modules
|
||||
if my_module_groups.many?
|
||||
my_module_groups.each_with_index do |group, gindex|
|
||||
subgraph_name = "cluster-#{gindex}"
|
||||
subg[subgraph_name] = graph.subgraph(rank: 'same')
|
||||
group.ordered_modules.each_with_index do |my_module, index|
|
||||
if my_module.outputs.any?
|
||||
parent = subg[subgraph_name]
|
||||
.add_nodes("#{subgraph_name}-#{index}",
|
||||
label: label,
|
||||
pos: "#{my_module.x / 10},-#{my_module.y / 10}!")
|
||||
|
||||
my_module.outputs.each_with_index do |output, i|
|
||||
child_mod = MyModule.find_by_id(output.input_id)
|
||||
child_node = subg[subgraph_name]
|
||||
.add_nodes("#{subgraph_name}-O#{child_mod.id}-#{i}",
|
||||
label: label,
|
||||
pos: "#{child_mod.x / 10},-#{child_mod.y / 10}!")
|
||||
|
||||
subg[subgraph_name].add_edges(parent, child_node)
|
||||
end
|
||||
elsif my_module.inputs.any?
|
||||
parent = subg[subgraph_name]
|
||||
.add_nodes("#{subgraph_name}-#{index}",
|
||||
label: label,
|
||||
pos: "#{my_module.x / 10},-#{my_module.y / 10}!")
|
||||
|
||||
my_module.inputs.each_with_index do |input, i|
|
||||
child_mod = MyModule.find_by_id(input.output_id)
|
||||
child_node = subg[subgraph_name]
|
||||
.add_nodes("#{subgraph_name}-I#{child_mod.id}-#{i}",
|
||||
label: label,
|
||||
pos: "#{child_mod.x / 10},-#{child_mod.y / 10}!")
|
||||
|
||||
subg[subgraph_name].add_edges(child_node, parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
my_module_groups.each do |group|
|
||||
group.ordered_modules.each_with_index do |my_module, index|
|
||||
if my_module.outputs.any?
|
||||
parent = graph.add_nodes("N-#{index}",
|
||||
label: label,
|
||||
pos: "#{my_module.x / 10},-#{ my_module.y / 10}!")
|
||||
|
||||
my_module.outputs.each_with_index do |output, i|
|
||||
child_mod = MyModule.find_by_id(output.input_id)
|
||||
child_node = graph
|
||||
.add_nodes("N-O#{child_mod.id}-#{i}",
|
||||
label: label,
|
||||
pos: "#{child_mod.x / 10},-#{child_mod.y / 10}!")
|
||||
graph.add_edges(parent, child_node)
|
||||
end
|
||||
elsif my_module.inputs.any?
|
||||
parent = graph.add_nodes("N-#{index}",
|
||||
label: label,
|
||||
pos: "#{my_module.x / 10},-#{my_module.y / 10}!")
|
||||
my_module.inputs.each_with_index do |input, i|
|
||||
child_mod = MyModule.find_by_id(input.output_id)
|
||||
child_node = graph
|
||||
.add_nodes("N-I#{child_mod.id}-#{i}",
|
||||
label: label,
|
||||
pos: "#{child_mod.x / 10},-#{child_mod.y / 10}!")
|
||||
graph.add_edges(child_node, parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
file_location = Tempfile.open(['wimg', '.png'],
|
||||
Rails.root.join('tmp'))
|
||||
|
||||
graph.output(png: file_location.path)
|
||||
|
||||
begin
|
||||
file = File.open(file_location)
|
||||
self.workflowimg = file
|
||||
file.close
|
||||
save
|
||||
touch(:workflowimg_updated_at)
|
||||
rescue => ex
|
||||
logger.error ex.message
|
||||
end
|
||||
WorkflowImageGenerator.execute(experiment_id: id)
|
||||
end
|
||||
|
||||
# Clone this experiment to given project
|
||||
|
|
7
app/services/executable_service.rb
Normal file
7
app/services/executable_service.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ExecutableService
|
||||
def execute(*args)
|
||||
new(*args).execute
|
||||
end
|
||||
end
|
89
app/services/workflow_image_generator.rb
Normal file
89
app/services/workflow_image_generator.rb
Normal file
|
@ -0,0 +1,89 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class WorkflowImageGenerator
|
||||
extend ExecutableService
|
||||
require 'graphviz'
|
||||
|
||||
attr_reader :errors
|
||||
|
||||
def initialize(experiment_id:)
|
||||
@exp = Experiment.find experiment_id
|
||||
@graph = GraphViz.new(:G, type: :digraph, use: :neato)
|
||||
|
||||
@graph[:size] = '4,4'
|
||||
@graph.node[color: Constants::COLOR_ALTO,
|
||||
style: :filled,
|
||||
fontcolor: Constants::COLOR_EMPEROR,
|
||||
shape: 'circle',
|
||||
fontname: 'Arial',
|
||||
fontsize: '16.0']
|
||||
|
||||
@graph.edge[color: Constants::COLOR_ALTO]
|
||||
@errors = []
|
||||
end
|
||||
|
||||
def execute
|
||||
draw_diagram
|
||||
save_file
|
||||
self
|
||||
end
|
||||
|
||||
def succeed?
|
||||
@errors.none?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def draw_diagram
|
||||
# Draw orphan nodes
|
||||
@exp.my_modules.without_group.each do |my_module|
|
||||
@graph.subgraph(rank: 'same').add_nodes(
|
||||
"Orphan-#{my_module.id}",
|
||||
label: '',
|
||||
pos: "#{my_module.x / 10},-#{my_module.y / 10}!"
|
||||
)
|
||||
end
|
||||
|
||||
# Draw grouped modules
|
||||
subg = {}
|
||||
@exp.my_module_groups.each_with_index do |group, gindex|
|
||||
subgraph_id = "cluster-#{gindex}"
|
||||
subg[subgraph_id] = @graph.subgraph(rank: 'same')
|
||||
nodes = {}
|
||||
|
||||
group.my_modules.workflow_ordered.each_with_index do |my_module, index|
|
||||
# draw nodes
|
||||
node = subg[subgraph_id].add_nodes(
|
||||
"#{subgraph_id}-#{index}",
|
||||
label: '',
|
||||
pos: "#{my_module.x / 10},-#{my_module.y / 10}!"
|
||||
)
|
||||
nodes[my_module.id] = node
|
||||
end
|
||||
|
||||
# draw edges
|
||||
group.my_modules.workflow_ordered.each do |m|
|
||||
m.outputs.each do |output|
|
||||
parent_node = nodes[m.id]
|
||||
child_node = nodes[output.input_id]
|
||||
subg[subgraph_id].add_edges(parent_node, child_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def save_file
|
||||
t_file = Tempfile.open(%w(wimg .png), Rails.root.join('tmp'))
|
||||
@graph.output(png: t_file.path)
|
||||
|
||||
begin
|
||||
file = File.open(t_file)
|
||||
@exp.workflowimg = file
|
||||
file.close
|
||||
@exp.save
|
||||
@exp.touch(:workflowimg_updated_at)
|
||||
rescue StandardError => ex
|
||||
logger.error ex.message
|
||||
end
|
||||
end
|
||||
end
|
6
spec/services/workflow_image_generator_spec.rb
Normal file
6
spec/services/workflow_image_generator_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe WorkflowImageGenerator do
|
||||
end
|
Loading…
Reference in a new issue