sibyl 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +24 -10
- data/app/assets/images/old_moon/old_moon.png +0 -0
- data/app/assets/images/old_moon/old_moon_@2X.jpg +0 -0
- data/app/assets/images/old_moon/readme.txt +8 -0
- data/app/assets/images/ui-bg_diagonals-thick_15_0b3e6f_40x40.png +0 -0
- data/app/assets/images/ui-bg_dots-medium_30_0b58a2_4x4.png +0 -0
- data/app/assets/images/ui-bg_dots-small_20_333333_2x2.png +0 -0
- data/app/assets/images/ui-bg_dots-small_30_a32d00_2x2.png +0 -0
- data/app/assets/images/ui-bg_dots-small_40_00498f_2x2.png +0 -0
- data/app/assets/images/ui-bg_gloss-wave_20_111111_500x100.png +0 -0
- data/app/assets/images/ui-icons_00498f_256x240.png +0 -0
- data/app/assets/images/ui-icons_98d2fb_256x240.png +0 -0
- data/app/assets/images/ui-icons_9ccdfc_256x240.png +0 -0
- data/app/assets/images/ui-icons_ffffff_256x240.png +0 -0
- data/app/assets/javascripts/jquery-ui.js +18706 -0
- data/app/assets/javascripts/jquery-ui.min.js +13 -0
- data/app/assets/javascripts/jquery.min.js +5 -0
- data/app/assets/javascripts/sibyl/application.js +2 -0
- data/app/assets/javascripts/sibyl/editor.js +218 -2
- data/app/assets/stylesheets/atelier-seaside-dark.css +1 -0
- data/app/assets/stylesheets/default.css +1 -0
- data/app/assets/stylesheets/jquery-ui.css +1312 -0
- data/app/assets/stylesheets/jquery-ui.min.css +7 -0
- data/app/assets/stylesheets/jquery-ui.structure.css +886 -0
- data/app/assets/stylesheets/jquery-ui.structure.min.css +5 -0
- data/app/assets/stylesheets/jquery-ui.theme.css +443 -0
- data/app/assets/stylesheets/jquery-ui.theme.min.css +5 -0
- data/app/assets/stylesheets/sibyl/application.css +9 -0
- data/app/assets/stylesheets/sibyl/editor.css +148 -4
- data/app/controllers/sibyl/editor_controller.rb +81 -3
- data/app/views/layouts/sibyl/application.html.erb +3 -2
- data/app/views/sibyl/editor/create_scaffold.html.erb +0 -0
- data/app/views/sibyl/editor/edit.html.erb +83 -1
- data/app/views/sibyl/editor/index.html.erb +28 -2
- data/app/views/sibyl/editor/index_task.html.erb +25 -0
- data/app/views/sibyl/editor/new_scaffold.html.erb +35 -0
- data/config/routes.rb +10 -2
- data/lib/generators/sibyl/form/USAGE +8 -0
- data/lib/generators/sibyl/form/form_generator.rb +34 -0
- data/lib/generators/sibyl/install/USAGE +8 -0
- data/lib/generators/sibyl/install/install_generator.rb +17 -0
- data/lib/generators/sibyl/install/templates/sibyl.rb +1 -0
- data/lib/generators/sibyl/model/USAGE +8 -0
- data/lib/generators/sibyl/model/model_generator.rb +29 -0
- data/lib/sibyl/base.rb +101 -0
- data/lib/sibyl/engine.rb +7 -0
- data/lib/sibyl/form.rb +43 -0
- data/lib/sibyl/task.rb +123 -0
- data/lib/sibyl/version.rb +1 -1
- data/lib/sibyl.rb +2 -0
- data/lib/tasks/sibyl_tasks.rake +19 -4
- metadata +123 -2
@@ -1,12 +1,90 @@
|
|
1
1
|
require_dependency "sibyl/application_controller"
|
2
|
+
require 'launchy'
|
2
3
|
|
3
4
|
module Sibyl
|
4
5
|
class EditorController < ApplicationController
|
5
|
-
|
6
|
-
|
6
|
+
protect_from_forgery :except => :save_form
|
7
|
+
|
8
|
+
def index
|
9
|
+
@tasks = Sibyl::Base.tasks
|
10
|
+
end
|
11
|
+
|
12
|
+
def list_task
|
13
|
+
@filesystem_bag = Sibyl::Base.forms(params[:task])
|
14
|
+
render json: @filesystem_bag
|
15
|
+
end
|
16
|
+
|
17
|
+
def index_task
|
18
|
+
@filesystem_bag = Sibyl::Base.forms(params[:task])
|
19
|
+
@task = params[:task]
|
20
|
+
render "index_task"
|
21
|
+
end
|
22
|
+
|
23
|
+
def index_form
|
24
|
+
@pages = Sibyl::Base.pages(params[:task], params[:form])
|
25
|
+
render json: @pages
|
26
|
+
end
|
27
|
+
|
28
|
+
def save_form
|
29
|
+
filesystem_bag = {}
|
30
|
+
dir = Rails.root.join("app", "sibyl", params[:task], params[:form])
|
31
|
+
json_file = dir.to_s.gsub(/$/, ".json")
|
32
|
+
STDERR.puts "Writing: #{json_file}"
|
33
|
+
File.open(json_file, "w") do |f|
|
34
|
+
f.write params[:json].to_json
|
35
|
+
end
|
36
|
+
head :ok
|
37
|
+
end
|
38
|
+
|
39
|
+
def create
|
40
|
+
logger.info "Got request: #{params[:task]} -> #{params[:form]}"
|
41
|
+
task = params[:task]
|
42
|
+
form = params[:form]
|
43
|
+
@errors = []
|
44
|
+
@errors.push ["Task name '#{task}' is not a valid ruby class name."] unless task =~ /^[A-Z]\w+/
|
45
|
+
@errors.push ["Form name '#{form}' is not a valid ruby class name."] unless form =~ /^[A-Z]\w+/
|
46
|
+
task = task.underscore.downcase
|
47
|
+
form = form.underscore.downcase
|
48
|
+
|
49
|
+
unless @errors.length == 0 and (@errors = Sibyl::Form.create_form(task, form, params[:pdf])).length == 0
|
50
|
+
redirect_to "/sibyl/editor/edit/#{task}/#{form}"
|
51
|
+
else
|
52
|
+
logger.info "Errors: #{@errors}"
|
53
|
+
rendeer 'create_error'
|
54
|
+
end
|
55
|
+
end
|
7
56
|
|
8
57
|
def edit
|
9
|
-
|
58
|
+
@task = params[:task]
|
59
|
+
@form = params[:form]
|
60
|
+
@pages = Sibyl::Base.pages(@task, @form)
|
10
61
|
end
|
62
|
+
|
63
|
+
def new_scaffold
|
64
|
+
@task = params[:task]
|
65
|
+
@forms = Sibyl::Base.forms(@task)
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_scaffold
|
69
|
+
@task = params[:task]
|
70
|
+
@columns = params[:columns]
|
71
|
+
columns = @columns.map {|k,v| "#{k}:#{v}"}
|
72
|
+
force = ''
|
73
|
+
if params[:force] == 'on'
|
74
|
+
force == '--force'
|
75
|
+
end
|
76
|
+
args = [Rails.root.join("bin", "rails").to_s, "generate", "scaffold", @task.titleize.to_s, *columns, "--migration", "--timestamps", force]
|
77
|
+
logger.info("args: #{args.join(' ')}")
|
78
|
+
system(*args)
|
79
|
+
args = [Rails.root.join("bin", "rake").to_s, "db:migrate"]
|
80
|
+
system(*args)
|
81
|
+
redirect_to "/#{@task}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def open_image
|
85
|
+
logger.info("params: " +params.inspect)
|
86
|
+
logger.info("image: #{Rails.root.join("app", "sibyl", params[:task], params[:form], params[:page]).to_s}")
|
87
|
+
Launchy.open(Rails.root.join("app", "sibyl", params[:task], params[:form], params[:page]).to_s)
|
88
|
+
end
|
11
89
|
end
|
12
90
|
end
|
@@ -4,8 +4,9 @@
|
|
4
4
|
<title>Sibyl</title>
|
5
5
|
<%= stylesheet_link_tag "sibyl/application", media: "all" %>
|
6
6
|
<%= javascript_include_tag "sibyl/application" %>
|
7
|
-
|
8
|
-
|
7
|
+
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/hybrid.min.css">
|
8
|
+
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab" rel="stylesheet">
|
9
|
+
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/highlight.min.js"></script>
|
9
10
|
<body>
|
10
11
|
|
11
12
|
<%= yield %>
|
File without changes
|
@@ -1 +1,83 @@
|
|
1
|
-
<
|
1
|
+
<style>
|
2
|
+
body {
|
3
|
+
background-image: none;
|
4
|
+
margin: 0;
|
5
|
+
padding: 0;
|
6
|
+
}
|
7
|
+
</style>
|
8
|
+
|
9
|
+
<script>
|
10
|
+
window.data = <%= raw @pages.to_json %>
|
11
|
+
$(document).ready(sibylEditor);
|
12
|
+
</script>
|
13
|
+
|
14
|
+
<div class="tiles">
|
15
|
+
<div class="controls">
|
16
|
+
<button id="close" type="button" class="ui-button ui-corner-all ui-widget ui-button-icon-only ui-dialog-titlebar-close" title="Close"><span class="ui-button-icon ui-icon ui-icon-closethick"></span><span class="ui-button-icon-space"> </span>Close</button>
|
17
|
+
<div id="title">Sibyl Editor</div>
|
18
|
+
<div id="current_labels">
|
19
|
+
Task: <span id="task"></span><br /><br />
|
20
|
+
Form: <span id="form"></span>
|
21
|
+
</div>
|
22
|
+
<input type="button" id="save_form" class="ui-button ui-widget ui-corner-all" value="Save Form" title="Save data for form" />
|
23
|
+
<input type="button" id="open_image" class="ui-button ui-widget ui-corner-all" value="Open Image" title="Open image in default editor" />
|
24
|
+
<a href="/sibyl/editor/scaffold/<%= @task %>" class="ui-button ui-widget ui-corner-all" id="scaffold" title="Create scaffold for task">Create Scaffold</a>
|
25
|
+
<select id="page_number"></select>
|
26
|
+
<div id="page_buttons">
|
27
|
+
<input type="button" value="Previous" id="previous_page" class="ui-button ui-widget ui-corner-all" title="Go to previous page" />
|
28
|
+
<input type="button" value="Next" id="next_page" class="ui-button ui-widget ui-corner-all" title="Go to next page" />
|
29
|
+
</div>
|
30
|
+
<div id="tabs">
|
31
|
+
<ul>
|
32
|
+
<li id="new_field"><a href="#tabs-1" title="Current element">Element</a></li>
|
33
|
+
<li id="elements"><a href="#tabs-2" title="List of elements">List</a></li>
|
34
|
+
<li id="jsonTab"><a href="#tabs-3" title="JSON View">JSON</a></li>
|
35
|
+
</ul>
|
36
|
+
<div id="tabs-1">
|
37
|
+
<p>Element Name</p>
|
38
|
+
<select id="select_element_name" class="element_text" title="Select an existing element name from the task">
|
39
|
+
<option value="custom">Custom Element Name</option>
|
40
|
+
</select>
|
41
|
+
<div id="task"></div>
|
42
|
+
<input type="text" id="custom_element_name" class="element_text" placeholder="Element Name" />
|
43
|
+
<div id="position_controls">
|
44
|
+
Select XY
|
45
|
+
<div class="box">
|
46
|
+
X: <input type="text" id="dx" class="xy_select" placeholder="X" /><br />
|
47
|
+
Y: <input type="text" id="dy" class="xy_select" placeholder="Y" /><br />
|
48
|
+
<input type="button" id="locate" value="Locate Element" class="ui-button ui-widget ui-corner-all" title="Find element location on the page" />
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
<label for="column">Column?</label>
|
52
|
+
<input type="checkbox" checked="checked" name="column" id="column" title="Should this element be a database column?" />
|
53
|
+
<label for="font_size">Font Size</label>
|
54
|
+
<select name="font_size" id="font_size" title="Font size on the page">
|
55
|
+
<%= 1.upto(48).each do |i| %>
|
56
|
+
<option value="<%= i %>" <%= i == 18 ? 'selected="selected"' : '' %>><%= i %></option>
|
57
|
+
<% end %>
|
58
|
+
</select>
|
59
|
+
<br /><br />
|
60
|
+
<label for="default_element_content">Default Element Content</label>
|
61
|
+
<input type="text" class="element_text" id="default_element_content" name="default_element_content" title="What is the default content?" />
|
62
|
+
<input type="button" id="save_element" class="ui-button ui-widget ui-corner-all" value="Save Element" title="Save element and go to list" />
|
63
|
+
</div>
|
64
|
+
<div id="tabs-2">
|
65
|
+
<div class="scrollContainer">
|
66
|
+
<table id="elements_list">
|
67
|
+
</table>
|
68
|
+
</div>
|
69
|
+
</div>
|
70
|
+
<div id="tabs-3">
|
71
|
+
<div class="scrollContainer">
|
72
|
+
<div id="jsonView" class="code apache hljs">
|
73
|
+
</div>
|
74
|
+
</div>
|
75
|
+
<div id="json" style="display: none">
|
76
|
+
{}
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
</div>
|
80
|
+
</div>
|
81
|
+
<div class="tile">
|
82
|
+
</div>
|
83
|
+
</div>
|
@@ -1,2 +1,28 @@
|
|
1
|
-
<h1>
|
2
|
-
<
|
1
|
+
<h1>Sibyl Tasks</h1>
|
2
|
+
<ol>
|
3
|
+
<%- @tasks.each do |task| %>
|
4
|
+
<li><%= link_to task, "/sibyl/editor/index/#{task}" %></li>
|
5
|
+
<% end %>
|
6
|
+
</ol>
|
7
|
+
|
8
|
+
<br />
|
9
|
+
|
10
|
+
<div class="sibyl_form">
|
11
|
+
<h2>New Task</h2>
|
12
|
+
<%= form_tag "/sibyl/editor/create", :method => :post, :multipart => true do %>
|
13
|
+
<%= label_tag :for => 'task' do %>
|
14
|
+
Task Name
|
15
|
+
<% end %>
|
16
|
+
<%= text_field_tag 'task', nil, placeholder: "Task" %><br />
|
17
|
+
<%= label_tag :for => 'form' do %>
|
18
|
+
Form Name
|
19
|
+
<% end %>
|
20
|
+
<%= text_field_tag 'form', nil, placeholder: "Form" %><br /><br />
|
21
|
+
<%= label_tag :for => 'pdf' do %>
|
22
|
+
PDF File
|
23
|
+
<% end %>
|
24
|
+
<%= file_field_tag 'pdf', :accept => ".pdf" %><br />
|
25
|
+
<br />
|
26
|
+
<%= submit_tag "Create", :class => 'ui-button ui-widget ui-corner-all' %>
|
27
|
+
<% end %>
|
28
|
+
</div>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<h1>Forms for: <%= @task %></h1>
|
2
|
+
|
3
|
+
<ol>
|
4
|
+
<%- @filesystem_bag['forms'].each do |form| %>
|
5
|
+
<li><%= link_to form, "/sibyl/editor/edit/#{@task}/#{form}" %></li>
|
6
|
+
<%- end %>
|
7
|
+
</ol>
|
8
|
+
<br />
|
9
|
+
|
10
|
+
<div class="sibyl_form">
|
11
|
+
<h2>New Form</h2>
|
12
|
+
<%= form_tag "/sibyl/editor/create", :method => :post, :multipart => true do %>
|
13
|
+
<%= hidden_field_tag 'task', nil, :value => @task %>
|
14
|
+
<%= label_tag :for => 'form' do %>
|
15
|
+
Form Name
|
16
|
+
<% end %>
|
17
|
+
<%= text_field_tag 'form', nil, placeholder: "Form" %><br /><br />
|
18
|
+
<%= label_tag :for => 'pdf' do %>
|
19
|
+
PDF File
|
20
|
+
<% end %>
|
21
|
+
<%= file_field_tag 'pdf', :accept => ".pdf" %><br />
|
22
|
+
<br />
|
23
|
+
<%= submit_tag "Create", :class => 'ui-button ui-widget ui-corner-all' %>
|
24
|
+
<% end %>
|
25
|
+
</div>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<h1>Generate scaffold for: <%= @task %></h1>
|
2
|
+
|
3
|
+
<%= form_tag "/sibyl/editor/scaffold/#{@task}", :method => :post do %>
|
4
|
+
<table style="width: 400px">
|
5
|
+
<thead>
|
6
|
+
<tr>
|
7
|
+
<th>Model Attribute</th>
|
8
|
+
<th>Data Type</th>
|
9
|
+
</tr>
|
10
|
+
</thead>
|
11
|
+
<tbody>
|
12
|
+
<% if @forms.has_key? 'columns' %>
|
13
|
+
<% @forms['columns'].each_key do |col| %>
|
14
|
+
<tr>
|
15
|
+
<td><%= col %></td>
|
16
|
+
<td>
|
17
|
+
<select name="columns[<%= col %>]">
|
18
|
+
<% [:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |type| %>
|
19
|
+
<option><%= type %></option>
|
20
|
+
<% end %>
|
21
|
+
</select>
|
22
|
+
</td>
|
23
|
+
</tr>
|
24
|
+
<% end %>
|
25
|
+
<% end %>
|
26
|
+
</tbody>
|
27
|
+
</table>
|
28
|
+
<br />
|
29
|
+
<label for="force">
|
30
|
+
Force
|
31
|
+
</label>
|
32
|
+
<input type="checkbox" checked="checked" name="force" /><br />
|
33
|
+
<br />
|
34
|
+
<%= submit_tag 'Create', :class =>"ui-button ui-widget ui-corner-all" %>
|
35
|
+
<% end %>
|
data/config/routes.rb
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
Sibyl::Engine.routes.draw do
|
2
|
-
get
|
3
|
-
|
2
|
+
get "editor/edit/:task/:form", to: "editor#edit"
|
3
|
+
get "editor/index", to: "editor#index"
|
4
|
+
get "editor/open_image", to: "editor#open_image"
|
5
|
+
post "editor/create", to: "editor#create"
|
6
|
+
get "editor/scaffold/:task", to: "editor#new_scaffold"
|
7
|
+
post "editor/scaffold/:task", to: "editor#create_scaffold"
|
8
|
+
get "editor/index/:task(?)", to: "editor#index_task"
|
9
|
+
get "editor/list/:task(?)", to: "editor#list_task"
|
10
|
+
get "editor/index/:task/:form(?)", to: "editor#index_form"
|
11
|
+
put "editor/save/:task/:form(?)", to: "editor#save_form"
|
4
12
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
|
4
|
+
module Sibyl
|
5
|
+
class FormGenerator < ActiveRecord::Generators::Base
|
6
|
+
desc "Creates a new form from a PDF"
|
7
|
+
argument :task, type: :string
|
8
|
+
argument :form, type: :string
|
9
|
+
argument :file, type: :string
|
10
|
+
|
11
|
+
def create_png_pages
|
12
|
+
STDERR.puts "Task: #{task}"
|
13
|
+
STDERR.puts "Form: #{form}"
|
14
|
+
STDERR.puts "File: #{file}"
|
15
|
+
unless task =~ /^[a-zA-Z0-9_-]+$/
|
16
|
+
STDERR.puts "Error: Task must not contain whitespace or invalid characters."
|
17
|
+
Sibyl::Form.usage
|
18
|
+
end
|
19
|
+
unless form =~ /^[a-zA-Z0-9_-]+$/
|
20
|
+
STDERR.puts "Error: Form must not contain whitespace or invalid characters."
|
21
|
+
Sibyl::Form.usage
|
22
|
+
end
|
23
|
+
unless File.exists? file
|
24
|
+
STDERR.puts "Error: File does not exist: #{file}"
|
25
|
+
Sibyl::Form.usage
|
26
|
+
end
|
27
|
+
|
28
|
+
dir = Rails.root.join("app", "sibyl", task, form)
|
29
|
+
FileUtils.mkdir_p dir
|
30
|
+
|
31
|
+
Sibyl::Form.convert_to_pdf(dir, file)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module Sibyl
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
desc "Installs sibyl on a fresh Rails project"
|
6
|
+
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
8
|
+
|
9
|
+
def copy_initializer
|
10
|
+
template 'sibyl.rb', 'config/initializers/sibyl.rb'
|
11
|
+
end
|
12
|
+
|
13
|
+
def mount_engine
|
14
|
+
route 'mount Sibyl::Engine => "/sibyl"'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Sibyl::Base.load
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module Sibyl
|
4
|
+
class ModelGenerator < ActiveRecord::Generators::Base
|
5
|
+
desc "Prepare Sibyl model and views"
|
6
|
+
argument :task, type: :string
|
7
|
+
|
8
|
+
def inject_into_model
|
9
|
+
file = Rails.root.join("app", "models", "#{task.classify.underscore}.rb")
|
10
|
+
inject_into_file file, after: "class #{task.classify} < ApplicationRecord" do
|
11
|
+
"\n include Sibyl::Task\n"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def modify_controller
|
16
|
+
file = Rails.root.join("app", "controllers", "#{task}_controller.rb")
|
17
|
+
gsub_file file, /def show *(\r?\n)\s*end/, "def show\n respond_to do |format|\n format.html\n format.zip { send_file @#{task.classify.underscore}.zip_path }\n end\n end"
|
18
|
+
end
|
19
|
+
|
20
|
+
def modify_view
|
21
|
+
file = Rails.root.join("app", "views", task, "index.html.erb")
|
22
|
+
gsub_file file, "<th colspan=\"3\"></th>", "<th colspan=\"4\"></th>"
|
23
|
+
inject_into_file file, after: "<td><%= link_to 'Show', #{task.classify.underscore} %></td>" do
|
24
|
+
"\n <td><%= link_to 'Download', #{task.classify.underscore}_path(#{task.classify.underscore})+'.zip' %></td>"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/lib/sibyl/base.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require File.expand_path("../task.rb", __FILE__)
|
3
|
+
|
4
|
+
module Sibyl
|
5
|
+
class Base
|
6
|
+
def self.load
|
7
|
+
self.tasks.each do |task|
|
8
|
+
Dir[Rails.root.join("app", "sibyl", task, "*.rb").to_s].each do |rb|
|
9
|
+
STDERR.puts "Requiring: #{rb}"
|
10
|
+
require rb
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.tasks
|
16
|
+
tasks = []
|
17
|
+
Dir[Rails.root.join("app", "sibyl", "*").to_s].each do |file|
|
18
|
+
if File.directory? file
|
19
|
+
tasks.push(Pathname.new(file).basename)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
tasks
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.list_columns(task)
|
26
|
+
columns = {}
|
27
|
+
Dir[Rails.root.join("app", "sibyl", task, "*.json").to_s].each do |json_file|
|
28
|
+
json = JSON.parse(File.read(json_file))
|
29
|
+
json.each_key do |page|
|
30
|
+
if json[page].has_key? 'elements'
|
31
|
+
json[page]['elements'].each_key do |name|
|
32
|
+
if json[page]['elements'][name].has_key? 'column' and json[page]['elements'][name]['column'].to_s == "true"
|
33
|
+
columns[name] = true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
return columns
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.list_defaults(task)
|
43
|
+
defaults = {}
|
44
|
+
Dir[Rails.root.join("app", "sibyl", task, "*.json").to_s].each do |json_file|
|
45
|
+
json = JSON.parse(File.read(json_file))
|
46
|
+
json.each_key do |page|
|
47
|
+
if json[page].has_key? 'elements'
|
48
|
+
json[page]['elements'].each_key do |name|
|
49
|
+
if json[page]['elements'][name].has_key? 'default'
|
50
|
+
defaults[name] = json[page]['elements'][name]['default']
|
51
|
+
else
|
52
|
+
defaults[name] = "Default #{name}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
return defaults
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.forms(task)
|
62
|
+
dir = Rails.root.join("app", "sibyl", task)
|
63
|
+
filesystem_bag = {}
|
64
|
+
entries = Dir.entries(dir).select {|entry| File.directory? File.join(dir,entry) and !(entry =='.' || entry == '..') }
|
65
|
+
entries.each do |form|
|
66
|
+
name = form.split(/\//).last
|
67
|
+
filesystem_bag['forms'] = [] unless filesystem_bag.has_key? 'forms'
|
68
|
+
filesystem_bag['forms'].push name
|
69
|
+
end
|
70
|
+
begin
|
71
|
+
filesystem_bag['defaults'] = self.list_defaults(task)
|
72
|
+
filesystem_bag['columns'] = self.list_columns(task)
|
73
|
+
rescue Exception => e
|
74
|
+
STDERR.puts "Exception: #{e}: #{e.backtrace}"
|
75
|
+
end
|
76
|
+
return filesystem_bag
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.pages(task, form)
|
80
|
+
filesystem_bag = {}
|
81
|
+
dir = Rails.root.join("app", "sibyl", task, form)
|
82
|
+
json_file = dir.to_s.gsub(/$/, ".json")
|
83
|
+
STDERR.puts "Reading: #{json_file}"
|
84
|
+
begin
|
85
|
+
filesystem_bag = JSON.parse(File.read(json_file))
|
86
|
+
rescue Exception => e
|
87
|
+
STDERR.puts("Exception: #{e}: #{e.backtrace}")
|
88
|
+
Dir[dir.join("*")].each do |form|
|
89
|
+
name = form.split(/\//).last
|
90
|
+
unless filesystem_bag.has_key? name
|
91
|
+
filesystem_bag[name] = {}
|
92
|
+
end
|
93
|
+
img = Magick::Image.ping( form ).first
|
94
|
+
filesystem_bag[name]['width'] = img.columns
|
95
|
+
filesystem_bag[name]['height'] = img.rows
|
96
|
+
end
|
97
|
+
end
|
98
|
+
return filesystem_bag
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/sibyl/engine.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
module Sibyl
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
isolate_namespace Sibyl
|
4
|
+
initializer "static assets" do |app|
|
5
|
+
app.middleware.insert_before(::ActionDispatch::Static, ::ActionDispatch::Static, Rails.root.join("app", "sibyl").to_s)
|
6
|
+
end
|
7
|
+
def self.open
|
8
|
+
require 'launchy'
|
9
|
+
Launchy.open("http://localhost:3000/sibyl/editor/index")
|
10
|
+
end
|
4
11
|
end
|
5
12
|
end
|
data/lib/sibyl/form.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'RMagick'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Sibyl
|
5
|
+
class Form
|
6
|
+
def self.usage
|
7
|
+
STDERR.puts <<EOT
|
8
|
+
Usage: bin/rails generate siblform <task name> <form name> <pdffile>
|
9
|
+
Task name and form name must be valid file names. Task name is a general
|
10
|
+
category for all forms that relate to a particular task. This is just for
|
11
|
+
organization purposes. Both task and form name should be alphanumeric and
|
12
|
+
not contain any whitespace.
|
13
|
+
EOT
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
def self.create_form(task,form,file)
|
17
|
+
dir = Rails.root.join("app", "sibyl", task, form)
|
18
|
+
pdf_file = dir.to_s.gsub(/$/, '.pdf')
|
19
|
+
STDERR.puts "Dir: #{dir}"
|
20
|
+
STDERR.puts "Saving: #{pdf_file}"
|
21
|
+
STDERR.puts "Creating: #{dir}"
|
22
|
+
FileUtils.mkdir_p dir
|
23
|
+
File.open(pdf_file, 'wb') do |f|
|
24
|
+
f.write(file.read)
|
25
|
+
end
|
26
|
+
STDERR.puts "Done"
|
27
|
+
convert_to_pdf(dir,pdf_file)
|
28
|
+
end
|
29
|
+
def self.convert_to_pdf(folder, pdf)
|
30
|
+
im = Magick::ImageList.new(pdf) {
|
31
|
+
self.density = '300'
|
32
|
+
self.background_color = "none"
|
33
|
+
}
|
34
|
+
im.reverse.each_with_index do |img, i|
|
35
|
+
filename = sprintf "page%03d.png", i
|
36
|
+
out = folder.join(filename)
|
37
|
+
STDERR.puts "writing: #{out}"
|
38
|
+
xr = img.write(out)
|
39
|
+
p xr
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|