perilune 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/config/perilune_manifest.js +1 -0
- data/app/assets/stylesheets/perilune/application.css +15 -0
- data/app/controllers/perilune/application_controller.rb +6 -0
- data/app/controllers/perilune/home_controller.rb +7 -0
- data/app/controllers/perilune/tasks_controller.rb +48 -0
- data/app/helpers/perilune/application_helper.rb +22 -0
- data/app/jobs/perilune/application_job.rb +6 -0
- data/app/jobs/perilune/tasks/executor_job.rb +37 -0
- data/app/mailers/perilune/application_mailer.rb +8 -0
- data/app/models/perilune/application_record.rb +7 -0
- data/app/models/perilune/task.rb +23 -0
- data/app/operations/perilune/tasks/create_operation.rb +51 -0
- data/app/operations/perilune/tasks/exports/create_operation.rb +44 -0
- data/app/operations/perilune/tasks/find_operation.rb +7 -0
- data/app/operations/perilune/tasks/search_operation.rb +8 -0
- data/app/serializers/perilune/tasks/serializer.rb +18 -0
- data/app/views/kaminari/_first_page.html.haml +5 -0
- data/app/views/kaminari/_gap.html.haml +1 -0
- data/app/views/kaminari/_last_page.html.haml +5 -0
- data/app/views/kaminari/_next_page.html.haml +5 -0
- data/app/views/kaminari/_page.html.haml +4 -0
- data/app/views/kaminari/_paginator.html.haml +11 -0
- data/app/views/kaminari/_prev_page.html.haml +5 -0
- data/app/views/layouts/perilune/application.html.haml +66 -0
- data/app/views/perilune/home/index.html.haml +19 -0
- data/app/views/perilune/tasks/index.html.haml +43 -0
- data/app/views/perilune/tasks/show.html.haml +44 -0
- data/config/routes.rb +6 -0
- data/lib/perilune/engine.rb +7 -0
- data/lib/perilune/tasks/mixin.rb +64 -0
- data/lib/perilune/version.rb +5 -0
- data/lib/perilune.rb +8 -0
- data/lib/tasks/perilune_tasks.rake +5 -0
- metadata +186 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fb116ba6c86f1c24f6981261f9c69335e2b152c1167708c411c41a408dd43893
|
4
|
+
data.tar.gz: ad39ec022a048edde5c3e18df3e3e62dd5eb75a117ce8a5103dab4c4516876ae
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 70f2a6f2fcf043f114818939c498fd85a14e183dd78bd3bdb91a2a32608ad94a5fea982c193b912e82530b9f66c95005ca662ca493370265e822d70146d65851
|
7
|
+
data.tar.gz: c271e506ffd1642a4de1f11e2e81c7abcdbe7566d285e3b67bcee169b52491e67a9c48514b4c1ae8170440c4404faa41bd4af7decd3db48c44727f48c2ebc9a9
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Perilune
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem "perilune"
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install perilune
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets/perilune .css
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perilune
|
4
|
+
class TasksController < Perilune::ApplicationController
|
5
|
+
before_action :set_resources, only: %i[index]
|
6
|
+
before_action :set_resource, only: %i[show]
|
7
|
+
|
8
|
+
def index; end
|
9
|
+
|
10
|
+
def show; end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def set_resources
|
15
|
+
resource_search_operation.perform
|
16
|
+
raise resource_search_operation.result.error unless resource_search_operation.success?
|
17
|
+
|
18
|
+
@resources = resource_search_operation.result.value
|
19
|
+
end
|
20
|
+
|
21
|
+
def resource_search_operation
|
22
|
+
@resource_search_operation ||= Perilune::Tasks::SearchOperation.new(
|
23
|
+
query: {},
|
24
|
+
limit: {},
|
25
|
+
includes: [],
|
26
|
+
order: 'id DESC',
|
27
|
+
page: params[:page] || 1,
|
28
|
+
per: 25,
|
29
|
+
domain: :perilune
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_resource
|
34
|
+
resource_find_operation.perform
|
35
|
+
raise resource_find_operation.result.error unless resource_find_operation.success?
|
36
|
+
|
37
|
+
@resource = resource_find_operation.result.value
|
38
|
+
end
|
39
|
+
|
40
|
+
def resource_find_operation
|
41
|
+
@resource_find_operation ||= Perilune::Tasks::FindOperation.new(
|
42
|
+
id: params[:id],
|
43
|
+
limit: {},
|
44
|
+
domain: :perilune
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perilune
|
4
|
+
module ApplicationHelper
|
5
|
+
def task_state(task) # rubocop:disable Metrics/MethodLength
|
6
|
+
case task.state.to_sym
|
7
|
+
when :draft
|
8
|
+
content_tag(:div, task.state,
|
9
|
+
class: 'inline-flex items-center px-2.5 py-0.5 rounded-sm text-sm font-medium uppercase bg-gray-500 text-gray-50') # rubocop:disable Layout/LineLength
|
10
|
+
when :uploaded
|
11
|
+
content_tag(:div, task.state,
|
12
|
+
class: 'inline-flex items-center px-2.5 py-0.5 rounded-sm text-sm font-medium uppercase bg-yellow-500 text-yellow-50') # rubocop:disable Layout/LineLength
|
13
|
+
when :processed
|
14
|
+
content_tag(:div, task.state,
|
15
|
+
class: 'inline-flex items-center px-2.5 py-0.5 rounded-sm text-sm font-medium uppercase bg-blue-500 text-blue-50') # rubocop:disable Layout/LineLength
|
16
|
+
when :failed
|
17
|
+
content_tag(:div, task.state,
|
18
|
+
class: 'inline-flex items-center px-2.5 py-0.5 rounded-sm text-sm font-medium uppercase bg-red-500 text-red-50') # rubocop:disable Layout/LineLength
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perilune
|
4
|
+
module Tasks
|
5
|
+
class ExecutorJob < ApplicationJob
|
6
|
+
queue_as :default
|
7
|
+
|
8
|
+
class UndefinedTaskKlass < StandardError; end
|
9
|
+
|
10
|
+
def perform(task_id)
|
11
|
+
@task_id = task_id
|
12
|
+
executor.execute
|
13
|
+
executor.success? ? success : failure
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def task
|
19
|
+
@task ||= Perilune::Task.find(@task_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def success
|
23
|
+
task.update(state: 'processed')
|
24
|
+
end
|
25
|
+
|
26
|
+
def failure
|
27
|
+
task.update(state: 'failed', error_data: { executor_error: executor.errors })
|
28
|
+
end
|
29
|
+
|
30
|
+
def executor
|
31
|
+
raise UndefinedTaskKlass unless Object.const_defined?(task.task_klass)
|
32
|
+
|
33
|
+
@executor ||= task.task_klass.constantize.new(file: task.file.download, task: task)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perilune
|
4
|
+
class Task < ApplicationRecord
|
5
|
+
self.table_name = 'perilune_tasks'
|
6
|
+
validates :state, inclusion: {
|
7
|
+
in: %w[draft uploaded processed failed],
|
8
|
+
message: '%<value>s is not a valid state'
|
9
|
+
}
|
10
|
+
validates :task_klass, presence: true
|
11
|
+
has_one_attached :file
|
12
|
+
|
13
|
+
def file_name
|
14
|
+
file.filename.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def file_url
|
18
|
+
file.url
|
19
|
+
rescue StandardError
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perilune
|
4
|
+
module Tasks
|
5
|
+
class CreateOperation
|
6
|
+
include LedgerSync::Domains::Operation::Mixin
|
7
|
+
|
8
|
+
class Contract < LedgerSync::Ledgers::Contract
|
9
|
+
params do
|
10
|
+
required(:file).maybe(type?: File)
|
11
|
+
required(:file).maybe(type?: Tempfile)
|
12
|
+
required(:task_klass).filled(:string)
|
13
|
+
optional(:tags).filled(:array)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def operate
|
20
|
+
attach!
|
21
|
+
if task.save
|
22
|
+
Perilune::Tasks::ExecutorJob.perform_later(task.id)
|
23
|
+
success(true)
|
24
|
+
else
|
25
|
+
failure(task.errors.full_messages)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def task
|
30
|
+
@task ||= Perilune::Task.new(
|
31
|
+
state: 'draft',
|
32
|
+
task_klass: params[:task_klass],
|
33
|
+
tags: params[:tags]
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def attach!
|
38
|
+
task.file.attach(
|
39
|
+
io: params[:file],
|
40
|
+
key: "perilune/#{ActiveStorage::Blob.generate_unique_secure_token}",
|
41
|
+
filename: "#{params[:task_klass]}_#{Time.zone.now.to_i}"
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
# override to use common serializer for all domain
|
46
|
+
def serializer_for(*)
|
47
|
+
Perilune::Tasks::Serializer.new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perilune
|
4
|
+
module Tasks
|
5
|
+
module Exports
|
6
|
+
class CreateOperation
|
7
|
+
include LedgerSync::Domains::Operation::Mixin
|
8
|
+
|
9
|
+
class Contract < LedgerSync::Ledgers::Contract
|
10
|
+
params do
|
11
|
+
required(:task_klass).filled(:string)
|
12
|
+
required(:attrs).filled(:hash)
|
13
|
+
optional(:tags).filled(:array)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def operate
|
20
|
+
if task.save
|
21
|
+
Perilune::Tasks::ExecutorJob.perform_later(task.id)
|
22
|
+
success(true)
|
23
|
+
else
|
24
|
+
failure(task.errors.full_messages)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def task
|
29
|
+
@task ||= Perilune::Task.new(
|
30
|
+
state: 'draft',
|
31
|
+
task_klass: params[:task_klass],
|
32
|
+
attrs: params[:attrs],
|
33
|
+
tags: params[:tags]
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
# override to use common serializer for all domain
|
38
|
+
def serializer_for(*)
|
39
|
+
Perilune::Tasks::Serializer.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perilune
|
4
|
+
module Tasks
|
5
|
+
class Serializer < LedgerSync::Domains::Serializer
|
6
|
+
attribute :id
|
7
|
+
attribute :task_klass
|
8
|
+
attribute :attrs
|
9
|
+
attribute :state
|
10
|
+
attribute :tags
|
11
|
+
attribute :error_data
|
12
|
+
attribute :created_at
|
13
|
+
attribute :updated_at
|
14
|
+
attribute :file_name
|
15
|
+
attribute :file_url
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
- unless current_page.first?
|
2
|
+
= link_to url, remote: remote, class: 'relative inline-flex items-center px-2 py-2. rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50' do
|
3
|
+
%span.sr-only= raw(t 'views.pagination.first')
|
4
|
+
%svg.h-4.w-4{:fill => "none", :stroke => "currentColor", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
5
|
+
%path{:d => "M11 19l-7-7 7-7m8 14l-7-7 7-7", "stroke-linecap" => "round", "stroke-linejoin" => "round", "stroke-width" => "2"}
|
@@ -0,0 +1 @@
|
|
1
|
+
= link_to raw(t 'views.pagination.truncate'), '#', class: 'relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700'
|
@@ -0,0 +1,5 @@
|
|
1
|
+
- unless current_page.last?
|
2
|
+
= link_to url, remote: remote, class: 'relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50' do
|
3
|
+
%span.sr-only= raw(t 'views.pagination.last')
|
4
|
+
%svg.h-4.w-4{:fill => "none", :stroke => "currentColor", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
5
|
+
%path{:d => "M13 5l7 7-7 7M5 5l7 7-7 7", "stroke-linecap" => "round", "stroke-linejoin" => "round", "stroke-width" => "2"}
|
@@ -0,0 +1,5 @@
|
|
1
|
+
- unless current_page.last?
|
2
|
+
= link_to url, rel: 'next', remote: remote, class: 'relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50' do
|
3
|
+
%span.sr-only= raw(t 'views.pagination.next')
|
4
|
+
%svg.h-4.w-4{:fill => "none", :stroke => "currentColor", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
5
|
+
%path{:d => "M9 5l7 7-7 7", "stroke-linecap" => "round", "stroke-linejoin" => "round", "stroke-width" => "2"}
|
@@ -0,0 +1,4 @@
|
|
1
|
+
- if page.current?
|
2
|
+
= link_to page, url, remote: remote, rel: page.rel, class: 'hidden md:inline-flex relative items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50'
|
3
|
+
- else
|
4
|
+
= link_to page, url, remote: remote, rel: page.rel, class: 'hidden md:inline-flex relative items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
= paginator.render do
|
2
|
+
%nav.relative.z-0.inline-flex.shadow-sm.-space-x-px{"aria-label" => "Pagination"}
|
3
|
+
= first_page_tag unless current_page.first?
|
4
|
+
= prev_page_tag unless current_page.first?
|
5
|
+
- each_page do |page|
|
6
|
+
- if page.left_outer? || page.right_outer? || page.inside_window?
|
7
|
+
= page_tag page
|
8
|
+
- elsif !page.was_truncated?
|
9
|
+
= gap_tag
|
10
|
+
= next_page_tag unless current_page.last?
|
11
|
+
= last_page_tag unless current_page.last?
|
@@ -0,0 +1,5 @@
|
|
1
|
+
- unless current_page.first?
|
2
|
+
= link_to url, rel: 'prev', remote: remote, class: 'relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50' do
|
3
|
+
%span.sr-only= raw(t 'views.pagination.previous')
|
4
|
+
%svg.h-4.w-4{:fill => "none", :stroke => "currentColor", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
5
|
+
%path{:d => "M15 19l-7-7 7-7", "stroke-linecap" => "round", "stroke-linejoin" => "round", "stroke-width" => "2"}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%meta{:charset => "utf-8"}/
|
5
|
+
%meta{:content => "width=device-width, initial-scale=1.0", :name => "viewport"}/
|
6
|
+
%meta{:content => "IE=edge", "http-equiv" => "X-UA-Compatible"}/
|
7
|
+
%title= content_for?(:page_title) ? sanitize(yield(:page_title), tags: []) : "Perilune"
|
8
|
+
= csrf_meta_tags
|
9
|
+
= csp_meta_tag
|
10
|
+
%link{:href => "https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700&display=swap", :rel => "stylesheet"}/
|
11
|
+
/ Favicons
|
12
|
+
%link{:rel => 'apple-touch-icon', :sizes => '180x180', :href => "#{main_app.root_url}favicons/apple-touch-icon.png"}
|
13
|
+
%link{:rel => 'icon', :sizes => '16x16', :href => "#{main_app.root_url}perilune/favicons/favicon-16x16.png"}
|
14
|
+
%link{:rel => 'icon', :sizes => '32x32', :href => "#{main_app.root_url}perilune/favicons/favicon-32x32.png"}
|
15
|
+
%link{:rel => 'icon', :sizes => '48x48', :href => "#{main_app.root_url}perilune/favicons/favicon.ico"}
|
16
|
+
%link{:rel => 'mask-icon', :href => "#{main_app.root_url}perilune/favicons/safari-pinned-tab.svg"}
|
17
|
+
%link{:rel => 'manifest', :href => "#{main_app.root_url}perilune/favicons/site.webmanifest"}
|
18
|
+
%meta{:content => "#{main_app.root_url}perilune/favicons/ms-tile-150x150.png", :name => "msapplication-TileImage"}/
|
19
|
+
= action_cable_meta_tag
|
20
|
+
|
21
|
+
%script{:src => "https://cdn.tailwindcss.com"}
|
22
|
+
|
23
|
+
%body
|
24
|
+
- if user_signed_in?
|
25
|
+
%input{id: 'user_locale', type: 'hidden', value: current_user.full_time_zone}
|
26
|
+
.min-h-screen.bg-gray-100
|
27
|
+
%nav.bg-white.shadow-sm{'x-data' => "{ isMobileVisible: false }"}
|
28
|
+
/ Desktop menu
|
29
|
+
.max-w-7xl.mx-auto.px-4.sm:px-6.lg:px-8
|
30
|
+
.flex.justify-between.h-16
|
31
|
+
.flex
|
32
|
+
.flex-shrink-0.flex.items-center.px-6
|
33
|
+
= link_to perilune.root_path, class: 'h-8 w-auto font-mono' do
|
34
|
+
%span.bg-clip-text.text-transparent.bg-gradient-to-r.bg-blue-200.from-blue-300.to-purple-400.text-2xl.font-bold Perilune
|
35
|
+
.hidden.sm:-my-px.sm:ml-6.sm:flex.sm:space-x-8
|
36
|
+
= link_to perilune.root_path, class: "border-transparent text-gray-500 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium hover:text-gray-700 hover:text-gray-300" do
|
37
|
+
Dashboard
|
38
|
+
= link_to perilune.tasks_path, class: "border-transparent text-gray-500 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium hover:text-gray-700 hover:text-gray-300" do
|
39
|
+
Tasks
|
40
|
+
|
41
|
+
/ Mobile menu, show/hide based on menu state.
|
42
|
+
#mobile-menu.sm:hidden{':class' => "isMobileVisible ? 'visible' : 'hidden'"}
|
43
|
+
.pt-2.pb-3.space-y-1
|
44
|
+
= link_to perilune.root_path, class: "text-gray-600 border-transparent block pl-3 pr-4 py-2 border-l-4 text-base font-medium hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800" do
|
45
|
+
Dashboard
|
46
|
+
= link_to perilune.tasks_path, class: "text-gray-600 border-transparent block pl-3 pr-4 py-2 border-l-4 text-base font-medium hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800" do
|
47
|
+
Tasks
|
48
|
+
|
49
|
+
|
50
|
+
.py-10
|
51
|
+
%main
|
52
|
+
.max-w-7xl.mx-auto.sm:px-6.lg:px-8
|
53
|
+
.mt-2.mx-6
|
54
|
+
- flash.each do |type, message|
|
55
|
+
- case type
|
56
|
+
- when :error
|
57
|
+
%div.p-4.mb-4.rounded-md.text-sm.font-medium.bg-red-100.text-red-800=message
|
58
|
+
- when :alert
|
59
|
+
%div.p-4.mb-4.rounded-md.text-sm.font-medium.bg-yellow-100.text-yellow-800=message
|
60
|
+
- when :notice
|
61
|
+
%div.p-4.mb-4.rounded-md.text-sm.font-medium.bg-indigo-100.text-indigo-800=message
|
62
|
+
- else
|
63
|
+
%div.p-4.mb-4.rounded-md.text-sm.font-medium.bg-indigo-100.text-indigo-800=message
|
64
|
+
= yield
|
65
|
+
|
66
|
+
= yield :javascript
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
.bg-white.overflow-hidden.shadow.rounded-lg
|
4
|
+
.px-4.py-5.sm:p-6
|
5
|
+
%div.mb-4
|
6
|
+
%span.text-2xl.font-bold perilune
|
7
|
+
[
|
8
|
+
= succeed '-i-loon' do
|
9
|
+
%span.font-bold per
|
10
|
+
]
|
11
|
+
%hr
|
12
|
+
%div.mt-4
|
13
|
+
.italic noun
|
14
|
+
%div.mt-2.ml-8
|
15
|
+
%span.text-gray-400 1
|
16
|
+
%span.ml-2 the point in a lunar orbit that is nearest to the moon.
|
17
|
+
%div.mt-2.ml-8
|
18
|
+
%span.text-gray-400 2
|
19
|
+
%span.ml-2 that thing that processes your files and makes your life a bit easier.
|
@@ -0,0 +1,43 @@
|
|
1
|
+
.flex.flex-col
|
2
|
+
.-my-2.overflow-x-auto.sm:-mx-6.lg:-mx-8
|
3
|
+
.py-2.align-middle.inline-block.min-w-full.sm:px-6.lg:px-8
|
4
|
+
.shadow.overflow-hidden.border-b.border-gray-200.sm:rounded-lg
|
5
|
+
%table.min-w-full.divide-y.divide-gray-200
|
6
|
+
%thead.bg-gray-50
|
7
|
+
%tr
|
8
|
+
%th.px-6.py-3.text-left.text-xs.font-medium.text-gray-500.uppercase.tracking-wider{:scope => "col"} ID
|
9
|
+
%th.px-6.py-3.text-left.text-xs.font-medium.text-gray-500.uppercase.tracking-wider{:scope => "col"} Task
|
10
|
+
%th.px-6.py-3.text-left.text-xs.font-medium.text-gray-500.uppercase.tracking-wider{:scope => "col"} State
|
11
|
+
%th.px-6.py-3.text-left.text-xs.font-medium.text-gray-500.uppercase.tracking-wider{:scope => "col"} Tags
|
12
|
+
%th.px-6.py-3.text-left.text-xs.font-medium.text-gray-500.uppercase.tracking-wider{:scope => "col"} Created At
|
13
|
+
%th.relative.px-6.py-3{:scope => "col"}
|
14
|
+
%span.sr-only Edit
|
15
|
+
%tbody
|
16
|
+
- @resources.each do |resource|
|
17
|
+
%tr.bg-white
|
18
|
+
%td.px-6.py-4.whitespace-nowrap.text-sm.font-medium.text-gray-600
|
19
|
+
= link_to resource.id, perilune.task_path(resource), class: 'text-indigo-400 hover:text-indigo-900'
|
20
|
+
%td.px-6.py-4.whitespace-nowrap.text-sm.text-gray-500
|
21
|
+
.rounded-sm.font-mono.text-sm.px-2.w-auto.max-w-max.break-normal.text-purple-500.bg-blue-100= resource.task_klass
|
22
|
+
%td.px-6.py-4.whitespace-nowrap.text-sm.text-gray-500= task_state(resource)
|
23
|
+
%td.px-6.py-4.whitespace-nowrap.text-sm.text-gray-500
|
24
|
+
- resource.tags.each do |tag|
|
25
|
+
%span.inline-flex.items-center.px-3.py-0.5.rounded-full.text-sm.font-medium.bg-blue-100.text-blue-800= tag
|
26
|
+
%td.px-6.py-4.whitespace-nowrap.text-sm.text-gray-500= resource.created_at.to_s
|
27
|
+
%td.px-6.py-4.whitespace-nowrap.text-right.text-sm.font-medium
|
28
|
+
= link_to perilune.task_path(resource) do
|
29
|
+
%svg.h-6.w-6.text-indigo-400.hover:text-indigo-900{:fill => "none", :stroke => "currentColor", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
30
|
+
%path{:d => "M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z", "stroke-linecap" => "round", "stroke-linejoin" => "round", "stroke-width" => "2"}
|
31
|
+
|
32
|
+
.mt-2
|
33
|
+
.flex-1.flex.items-center.justify-between
|
34
|
+
%div.hidden.sm:block
|
35
|
+
%p.text-sm.text-gray-400
|
36
|
+
- unless @resources.total_count.zero?
|
37
|
+
Showing
|
38
|
+
%span.font-medium= (@resources.current_page - 1) * @resources.limit_value + 1
|
39
|
+
to
|
40
|
+
%span.font-medium= [(@resources.current_page - 1) * @resources.limit_value + @resources.limit_value, @resources.total_count].min
|
41
|
+
of
|
42
|
+
= pluralize(@resources.total_count, 'task')
|
43
|
+
= paginate @resources
|
@@ -0,0 +1,44 @@
|
|
1
|
+
.bg-white.shadow.overflow-hidden.sm:rounded-lg
|
2
|
+
.px-4.py-5.sm:px-6
|
3
|
+
%h3.text-lg.leading-6.font-medium.text-gray-900 Task ##{@resource.id}
|
4
|
+
.border-t.border-gray-200.px-4.py-5.sm:p-0
|
5
|
+
%dl.sm:divide-y.sm:divide-gray-200
|
6
|
+
.py-4.sm:py-5.sm:grid.sm:grid-cols-3.sm:gap-4.sm:px-6
|
7
|
+
%dt.text-sm.font-medium.text-gray-500 Task Klass
|
8
|
+
%dd.mt-1.text-sm.text-gray-900.sm:mt-0.sm:col-span-2
|
9
|
+
.rounded-sm.font-mono.text-sm.px-2.w-auto.max-w-max.break-normal.text-purple-500.bg-blue-100 #{@resource.task_klass}
|
10
|
+
.py-4.sm:py-5.sm:grid.sm:grid-cols-3.sm:gap-4.sm:px-6
|
11
|
+
%dt.text-sm.font-medium.text-gray-500 Task Attributes
|
12
|
+
%dd.mt-1.text-sm.text-gray-900.sm:mt-0.sm:col-span-2
|
13
|
+
%code #{@resource.attrs}
|
14
|
+
.py-4.sm:py-5.sm:grid.sm:grid-cols-3.sm:gap-4.sm:px-6
|
15
|
+
%dt.text-sm.font-medium.text-gray-500 State
|
16
|
+
%dd.mt-1.text-sm.text-gray-900.sm:mt-0.sm:col-span-2 #{task_state(@resource)}
|
17
|
+
.py-4.sm:py-5.sm:grid.sm:grid-cols-3.sm:gap-4.sm:px-6
|
18
|
+
%dt.text-sm.font-medium.text-gray-500 Tags
|
19
|
+
%dd.mt-1.text-sm.text-gray-900.sm:mt-0.sm:col-span-2
|
20
|
+
- @resource.tags.each do |tag|
|
21
|
+
%span.inline-flex.items-center.px-3.py-0.5.rounded-full.text-sm.font-medium.bg-blue-100.text-blue-800= tag
|
22
|
+
.py-4.sm:py-5.sm:grid.sm:grid-cols-3.sm:gap-4.sm:px-6
|
23
|
+
%dt.text-sm.font-medium.text-gray-500 Created At
|
24
|
+
%dd.mt-1.text-sm.text-gray-900.sm:mt-0.sm:col-span-2 #{@resource.created_at.to_s}
|
25
|
+
.py-4.sm:py-5.sm:grid.sm:grid-cols-3.sm:gap-4.sm:px-6
|
26
|
+
%dt.text-sm.font-medium.text-gray-500 Updated At
|
27
|
+
%dd.mt-1.text-sm.text-gray-900.sm:mt-0.sm:col-span-2 #{@resource.updated_at.to_s}
|
28
|
+
- if @resource.state.to_sym == :failed
|
29
|
+
.py-4.sm:py-5.sm:grid.sm:grid-cols-3.sm:gap-4.sm:px-6
|
30
|
+
%dt.text-sm.font-medium.text-gray-500 Error
|
31
|
+
%dd.mt-1.text-sm.text-gray-900.sm:mt-0.sm:col-span-2
|
32
|
+
%code #{@resource.error_data}
|
33
|
+
.py-4.sm:py-5.sm:grid.sm:grid-cols-3.sm:gap-4.sm:px-6
|
34
|
+
%dt.text-sm.font-medium.text-gray-500 Attachment
|
35
|
+
%dd.mt-1.text-sm.text-gray-900.sm:mt-0.sm:col-span-2
|
36
|
+
%ul.border.border-gray-200.rounded-md.divide-y.divide-gray-200{:role => "list"}
|
37
|
+
%li.pl-3.pr-4.py-3.flex.items-center.justify-between.text-sm
|
38
|
+
.w-0.flex-1.flex.items-center
|
39
|
+
/ Heroicon name: solid/paper-clip
|
40
|
+
%svg.flex-shrink-0.h-5.w-5.text-gray-400{"aria-hidden" => "true", :fill => "currentColor", :viewbox => "0 0 20 20", :xmlns => "http://www.w3.org/2000/svg"}
|
41
|
+
%path{"clip-rule" => "evenodd", :d => "M8 4a3 3 0 00-3 3v4a5 5 0 0010 0V7a1 1 0 112 0v4a7 7 0 11-14 0V7a5 5 0 0110 0v4a3 3 0 11-6 0V7a1 1 0 012 0v4a1 1 0 102 0V7a3 3 0 00-3-3z", "fill-rule" => "evenodd"}
|
42
|
+
%span.ml-2.flex-1.w-0.truncate #{@resource.file_name}
|
43
|
+
.ml-4.flex-shrink-0
|
44
|
+
= link_to 'Download', @resource.file_url, class: 'font-medium text-indigo-400 hover:text-indigo-900'
|
data/config/routes.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perilune
|
4
|
+
module Tasks
|
5
|
+
module Mixin
|
6
|
+
def self.included(base)
|
7
|
+
base.include InstanceMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
module InstanceMethods
|
11
|
+
attr_reader :file, :task, :errors
|
12
|
+
|
13
|
+
delegate :trace, to: :tracer
|
14
|
+
|
15
|
+
def initialize(file:, task:)
|
16
|
+
@file = file
|
17
|
+
@task = task
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute
|
21
|
+
operate
|
22
|
+
rescue StandardError => e
|
23
|
+
failure(e.message)
|
24
|
+
end
|
25
|
+
|
26
|
+
def tags
|
27
|
+
task.tags
|
28
|
+
end
|
29
|
+
|
30
|
+
def failure(message)
|
31
|
+
@errors = message
|
32
|
+
end
|
33
|
+
|
34
|
+
def success?
|
35
|
+
errors.blank?
|
36
|
+
end
|
37
|
+
|
38
|
+
def operate(*)
|
39
|
+
raise StandardError, 'operate function is not defined'
|
40
|
+
end
|
41
|
+
|
42
|
+
def tracer_config
|
43
|
+
@tracer_config ||= Trifle::Logger::Configuration.new
|
44
|
+
@tracer_config.on(:wrapup) do |tracer|
|
45
|
+
entry = Perilune::Task.find_by(id: tracer.reference)
|
46
|
+
next if entry.nil?
|
47
|
+
|
48
|
+
entry.update(
|
49
|
+
tracer_data: tracer.data,
|
50
|
+
state: tracer.state
|
51
|
+
)
|
52
|
+
end
|
53
|
+
@tracer_config
|
54
|
+
end
|
55
|
+
|
56
|
+
def tracer
|
57
|
+
@tracer ||= Trifle::Logger.tracer = Trifle::Logger::Tracer::Hash.new(
|
58
|
+
key: task.id, reference: task.id, config: tracer_config
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/perilune.rb
ADDED
metadata
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: perilune
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kartavya Pareek
|
8
|
+
- Jozef Vaclavik
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2022-03-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ledger_sync-domains
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 1.1.1
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 1.1.1
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rails
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 7.0.0
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 7.0.0.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - "~>"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 7.0.0
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 7.0.0.0
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: trifle-logger
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: dotenv-rails
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
type: :development
|
70
|
+
prerelease: false
|
71
|
+
version_requirements: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: factory_bot_rails
|
78
|
+
requirement: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: pg
|
92
|
+
requirement: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
type: :development
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: rspec-rails
|
106
|
+
requirement: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
type: :development
|
112
|
+
prerelease: false
|
113
|
+
version_requirements: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
description: Description of Perilune.
|
119
|
+
email:
|
120
|
+
- hi@dropbot.sh
|
121
|
+
executables: []
|
122
|
+
extensions: []
|
123
|
+
extra_rdoc_files: []
|
124
|
+
files:
|
125
|
+
- README.md
|
126
|
+
- Rakefile
|
127
|
+
- app/assets/config/perilune_manifest.js
|
128
|
+
- app/assets/stylesheets/perilune/application.css
|
129
|
+
- app/controllers/perilune/application_controller.rb
|
130
|
+
- app/controllers/perilune/home_controller.rb
|
131
|
+
- app/controllers/perilune/tasks_controller.rb
|
132
|
+
- app/helpers/perilune/application_helper.rb
|
133
|
+
- app/jobs/perilune/application_job.rb
|
134
|
+
- app/jobs/perilune/tasks/executor_job.rb
|
135
|
+
- app/mailers/perilune/application_mailer.rb
|
136
|
+
- app/models/perilune/application_record.rb
|
137
|
+
- app/models/perilune/task.rb
|
138
|
+
- app/operations/perilune/tasks/create_operation.rb
|
139
|
+
- app/operations/perilune/tasks/exports/create_operation.rb
|
140
|
+
- app/operations/perilune/tasks/find_operation.rb
|
141
|
+
- app/operations/perilune/tasks/search_operation.rb
|
142
|
+
- app/serializers/perilune/tasks/serializer.rb
|
143
|
+
- app/views/kaminari/_first_page.html.haml
|
144
|
+
- app/views/kaminari/_gap.html.haml
|
145
|
+
- app/views/kaminari/_last_page.html.haml
|
146
|
+
- app/views/kaminari/_next_page.html.haml
|
147
|
+
- app/views/kaminari/_page.html.haml
|
148
|
+
- app/views/kaminari/_paginator.html.haml
|
149
|
+
- app/views/kaminari/_prev_page.html.haml
|
150
|
+
- app/views/layouts/perilune/application.html.haml
|
151
|
+
- app/views/perilune/home/index.html.haml
|
152
|
+
- app/views/perilune/tasks/index.html.haml
|
153
|
+
- app/views/perilune/tasks/show.html.haml
|
154
|
+
- config/routes.rb
|
155
|
+
- lib/perilune.rb
|
156
|
+
- lib/perilune/engine.rb
|
157
|
+
- lib/perilune/tasks/mixin.rb
|
158
|
+
- lib/perilune/version.rb
|
159
|
+
- lib/tasks/perilune_tasks.rake
|
160
|
+
homepage: https://engineering.dropbot.sh
|
161
|
+
licenses:
|
162
|
+
- MIT
|
163
|
+
metadata:
|
164
|
+
homepage_uri: https://engineering.dropbot.sh
|
165
|
+
source_code_uri: https://github.com/sandbite/perilune
|
166
|
+
changelog_uri: https://github.com/sandbite/perilune/blob/main/CHANGELOG.md
|
167
|
+
post_install_message:
|
168
|
+
rdoc_options: []
|
169
|
+
require_paths:
|
170
|
+
- lib
|
171
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '2.7'
|
176
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
requirements: []
|
182
|
+
rubygems_version: 3.2.9
|
183
|
+
signing_key:
|
184
|
+
specification_version: 4
|
185
|
+
summary: Summary of Perilune.
|
186
|
+
test_files: []
|