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
         |