pagiii 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d70f2977bee3d72cf6643ed1a34093612c20c754b85b089b256797d91124eaba
4
+ data.tar.gz: 98a77db5ba8d05143d015b9e07e52d73d1f3e671f77ee6508cc531dc08a142ee
5
+ SHA512:
6
+ metadata.gz: ccd0773591d3d0bd8eabf5cd8dbcadd169255ae0e7b529ef17c19c25673e00f85723445c602eb6279fda5f4f3db6d0d8d0a0657a43c2cbbe40ac0a40a637965a
7
+ data.tar.gz: b543b85fa75d1a7ead7043d763cb1ad82f6946eee4ab83a95ec95c51e290b443ddd430b2b3dde52b0577f7dfaf4815f97bedd44a0c18bb7d64572b510fd2f91c
data/bin/pagiii ADDED
@@ -0,0 +1,275 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pagiii'
3
+
4
+
5
+ require 'faraday'
6
+ require 'base64'
7
+ require 'filewatcher'
8
+ require 'commander/import'
9
+ require 'cgi'
10
+ require 'socket'
11
+
12
+ def root_api
13
+ return ENV['PAGIII_HOST'] if ENV['PAGIII_HOST']
14
+ "https://pagiii.duruxignition.com"
15
+ end
16
+
17
+ client_id = 'IuIwOC38m7acKuJRo-nkG22ZzeVpWLDPMPnoaoRzQp8'
18
+ secret_id = 'WlENailhg7KEbZqXXwX4Y470HYGL8-U2af_bOZGVWeQ'
19
+ redirect_uri = 'http://localhost:7654'
20
+ scope = 'read_theme write_theme delete_theme'
21
+
22
+ program :version, '0.0.7'
23
+ program :description, 'Pagiii CLI'
24
+
25
+
26
+
27
+ def get_current_site(token)
28
+ conn = Faraday.new(
29
+ url: "#{root_api}/api/v1/admin/sites/current",
30
+ params: {param: '1'},
31
+ headers: {
32
+ 'Content-Type' => 'application/json',
33
+ 'Authorization' => "Bearer #{token}"
34
+ }
35
+ )
36
+ response = conn.get
37
+ puts response.body
38
+ hash = JSON.parse(response.body)
39
+ end
40
+
41
+
42
+
43
+
44
+
45
+ def check_authorized(response)
46
+ if response.status == 401
47
+ say "Unauthorized. Please run theme:request to get access-token"
48
+ exit(false)
49
+ end
50
+ end
51
+
52
+ def update_config(site_name, token)
53
+ dir = "#{Dir.home}/.pagiii"
54
+ FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
55
+ file = File.join(dir, 'config.json')
56
+ hash = {}
57
+ if File.exists?(file)
58
+ hash = JSON.parse(IO.read(file))
59
+ end
60
+ hash[site_name] = token
61
+ File.open(file, 'w+') do |f|
62
+ f.write(hash.to_json)
63
+ end
64
+ end
65
+
66
+ def read_config(site_name)
67
+ dir = "#{Dir.home}/.pagiii"
68
+ return nil unless Dir.exists?(dir)
69
+ file = File.join(dir, 'config.json')
70
+ return nil unless File.exists?(file)
71
+ hash = JSON.parse(IO.read(file))
72
+ hash[site_name]
73
+ end
74
+
75
+ command :help do |c|
76
+ c.action do |args, options|
77
+ say "Help.... pagiii"
78
+ end
79
+ end
80
+
81
+
82
+ # bundle exec ruby pagiii.rb theme:sync --site=dokumentasi --theme=doc
83
+ command 'theme:sync' do |c|
84
+ c.option '--theme STRING', String, 'Theme name'
85
+ c.option '--site STRING', String, 'Site name'
86
+ c.action do |args, options|
87
+ if options.theme.nil?
88
+ say "please specify theme name using --theme option"
89
+ exit(false)
90
+ elsif options.site.nil?
91
+ say "please specify site name using --site option"
92
+ exit(false)
93
+ end
94
+ token = read_config(options.site)
95
+ theme = Pagiii::ThemeSync.new(token: token, root_api: root_api)
96
+ theme.sync_all(options.theme)
97
+ end
98
+ end
99
+
100
+ command 'theme:watch' do |c|
101
+ c.option '--site STRING', String, 'Site name'
102
+ c.option '--theme STRING', String, 'Theme name'
103
+ c.action do |args, options|
104
+ if options.theme.nil?
105
+ say "please specify theme name using --theme option"
106
+ exit(false)
107
+ elsif options.site.nil?
108
+ say "please specify site name using --site option"
109
+ exit(false)
110
+ end
111
+ token = read_config(options.site)
112
+ theme_sync = Pagiii::ThemeSync.new(token: token, root_api: root_api)
113
+ theme_sync.watch(options.theme)
114
+ end
115
+ end
116
+
117
+ command 'theme:create' do |c|
118
+ c.syntax = "theme:create [options]"
119
+ c.description = "Create theme"
120
+ c.option '--site STRING', String, 'Site name'
121
+ c.option '--theme STRING', String, 'Theme name'
122
+
123
+ c.action do |args, options|
124
+ token = read_config(options.site)
125
+ if options.theme.nil?
126
+ say "please specify theme name using --theme option"
127
+ else
128
+ say "Create theme #{options.theme}"
129
+ theme_sync = Pagiii::ThemeSync.new(token: token, root_api: root_api)
130
+ response = theme_sync.create_theme(options.theme)
131
+
132
+ if response.status == 200
133
+ say "theme created"
134
+ else
135
+ say response.body
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ command 'theme:pull' do |c|
142
+ c.syntax = "theme:pull [options]"
143
+ c.description = "Pull theme"
144
+ c.option '--site STRING', String, 'Site name'
145
+ c.option '--theme STRING', String, 'Theme name'
146
+ c.action do |args, options|
147
+ if options.theme.nil?
148
+ say "please specify theme name using --theme option"
149
+ elsif options.site.nil?
150
+ say "please provide site name"
151
+ else
152
+ token = read_config(options.site)
153
+ say "Pull theme #{options.theme}"
154
+ theme_sync = Pagiii::ThemeSync.new(token: token, root_api: root_api)
155
+ theme_sync.pull_theme(options.theme)
156
+ end
157
+ end
158
+ end
159
+
160
+ command 'theme:list' do |c|
161
+ c.syntax = "theme:list [options]"
162
+ c.description = "List theme"
163
+ c.option '--site STRING', String, 'Site name'
164
+ c.action do |args, options|
165
+ if options.site.nil?
166
+ say "please provide name using --site"
167
+ else
168
+ token = read_config(options.site)
169
+ theme_sync = Pagiii::ThemeSync.new(token: token, root_api: root_api)
170
+ theme_sync.list_themes
171
+ end
172
+ end
173
+ end
174
+
175
+ command 'theme:delete' do |c|
176
+ c.syntax = "theme:delete [options]"
177
+ c.description = "Delete theme"
178
+ c.option '--theme STRING', String, 'Theme name'
179
+ c.option '--site STRING', String, 'Site'
180
+ c.action do |args, options|
181
+ if options.theme.nil?
182
+ say "please specify theme name using --theme option"
183
+ elsif options.site.nil?
184
+ say "please provide site name using --site"
185
+ else
186
+ say "Delete theme #{options.theme}"
187
+ token = read_config(options.site)
188
+
189
+ theme_sync = Pagiii::ThemeSync.new(token: token, root_api: root_api)
190
+ theme_sync.delete_theme(options.theme)
191
+ end
192
+ end
193
+ end
194
+
195
+ command 'theme:set_current' do |c|
196
+ c.syntax = "theme:set_current [options]"
197
+ c.description = "Delete theme"
198
+ c.option '--theme STRING', String, 'Theme name'
199
+ c.option '--site STRING', String, 'site name'
200
+
201
+ c.action do |args, options|
202
+ if options.theme.nil?
203
+ say "please specify theme name using --theme option"
204
+ elsif options.site.nil?
205
+ say "please provide name using --site"
206
+ else
207
+ say "Set current theme of #{options.site} to #{options.theme}"
208
+ token = read_config(options.site)
209
+ theme_sync = Pagiii::ThemeSync.new(token: token, root_api: root_api)
210
+ theme_sync.set_current_theme(options.theme)
211
+ end
212
+ end
213
+ end
214
+
215
+ command 'theme:request' do |c|
216
+ c.syntax = "theme:request [options]"
217
+ c.description = "Create theme"
218
+ c.option '--site STRING', String, 'Site name'
219
+ c.action do |args, options|
220
+ if options.site.nil?
221
+ say "please specify site name using --site option"
222
+ else
223
+ say "Site Request access #{options.site}"
224
+ url = "#{root_api}/#{options.site}/oauth/authorize?client_id=#{client_id}&redirect_uri=#{CGI.escape(redirect_uri)}&response_type=code&scope=#{scope}"
225
+ say url
226
+ `open "#{url}"`
227
+ server = TCPServer.new 7654
228
+ say "please check browser"
229
+ while session = server.accept
230
+ request = session.gets
231
+ puts request
232
+
233
+ # session.print "HTTP/1.1 200\r\n" # 1
234
+ # session.print "Content-Type: text/html\r\n" # 2
235
+ # session.print "\r\n" # 3
236
+ # session.print "Tutup " #4
237
+ # session.close
238
+
239
+ output = "<html><head></head><body>#</body></html>"
240
+ headers = ["HTTP/1.1 302 Found",
241
+ "Location: #{root_api}\r\n\r\n",
242
+ "content-length: #\r\n\r\n"].join("\r\n")
243
+ session.puts headers
244
+ session.puts output
245
+ session.close
246
+
247
+ if request =~ /code=([a-zA-Z0-9\-_]+)/
248
+ authorization_code = $1
249
+ say "authozation code: #{authorization_code}"
250
+
251
+ conn = Faraday.new(
252
+ url: "#{root_api}/#{options.site}/oauth/token",
253
+ params: {param: '1'},
254
+ headers: {
255
+ 'Content-Type' => 'application/x-www-form-urlencoded'
256
+ }
257
+ )
258
+ response = conn.post do |req|
259
+ req.body = "grant_type=authorization_code&code=#{authorization_code}&redirect_uri=#{CGI.escape(redirect_uri)}&client_id=#{client_id}&client_secret=#{secret_id}"
260
+ end
261
+
262
+ if response.status == 200
263
+ access_token = JSON.parse(response.body)['access_token']
264
+ say "access token: #{access_token}"
265
+ update_config(options.site, access_token)
266
+ break
267
+ else
268
+ say "unable to get access token"
269
+ end
270
+ end
271
+
272
+ end
273
+ end
274
+ end
275
+ end
@@ -0,0 +1,8 @@
1
+ module Pagiii
2
+ module Info
3
+ def info
4
+ puts "Access Token: #{@token}"
5
+ puts "Root API: #{@root_api}"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,285 @@
1
+ require 'pagiii/info'
2
+
3
+ class Pagiii::ThemeSync
4
+ include Pagiii::Info
5
+
6
+ ALLOWED_DIRS = ['templates', 'sections', 'layout', 'assets', 'snippets']
7
+
8
+ def initialize(token:, root_api:)
9
+ @token = token
10
+ @root_api = root_api
11
+ end
12
+
13
+ def list_themes
14
+ conn = Faraday.new(
15
+ url: "#{root_api}/api/v1/admin/themes",
16
+ headers: {
17
+ 'Content-Type' => 'application/json',
18
+ 'Authorization' => "Bearer #{@token}"
19
+ }
20
+ )
21
+ response = conn.get
22
+ check_authorized(response)
23
+ if response.status == 200
24
+ hash = JSON.parse(response.body)
25
+ say "List themes at #{hash['site']['name']}"
26
+ say "--------------------------------------"
27
+ hash['themes'].each do |theme|
28
+ say " - #{theme['name']}"
29
+ end
30
+ else
31
+ say "error"
32
+ end
33
+ end
34
+
35
+
36
+ def sync_file(theme_name, file)
37
+ puts "sync #{file}"
38
+ conn = Faraday.new(
39
+ url: @root_api,
40
+ params: {param: '1'},
41
+ headers: {
42
+ 'Content-Type' => 'application/json',
43
+ 'Authorization' => "Bearer #{@token}"
44
+ }
45
+ )
46
+
47
+ data = ""
48
+
49
+ ext = File.extname(file)
50
+ if [".png", ".jpg", ".jpeg", ".gif"].include?(ext)
51
+ data = Base64.encode64(IO.read(file))
52
+ else
53
+ data = IO.read(file)
54
+ end
55
+ response = get_theme_by_name(name: theme_name)
56
+
57
+ check_authorized(response)
58
+ theme_id = JSON.parse(response.body)['theme']['id']
59
+
60
+ response = conn.post("/api/v1/admin/themes/#{theme_id}/assets") do |req|
61
+ req.params['limit'] = 100
62
+ req.body = {
63
+ key: get_asset_key(file),
64
+ data: data
65
+ }.to_json
66
+ end
67
+ end
68
+
69
+
70
+
71
+ def sync_delete(theme_name, file)
72
+ puts "deleteing #{file}"
73
+ response = get_theme_by_name(name: theme_name)
74
+ check_authorized(response)
75
+ theme_id = JSON.parse(response.body)['theme']['id']
76
+
77
+ conn = Faraday.new(
78
+ url: @root_api,
79
+ params: {param: '1'},
80
+ headers: {
81
+ 'Content-Type' => 'application/json',
82
+ 'Authorization' => "Bearer #{@token}"
83
+ }
84
+ )
85
+ response = conn.delete("/api/v1/admin/themes/#{theme_id}/assets?key=#{get_asset_key(file)}")
86
+ end
87
+
88
+ def delete_remote(theme, asset_key)
89
+ puts "deleting #{asset_key}"
90
+ response = get_theme_by_name(name: theme)
91
+ check_authorized(response)
92
+ theme_id = JSON.parse(response.body)['theme']['id']
93
+
94
+ conn = Faraday.new(
95
+ url: @root_api,
96
+ params: {param: '1'},
97
+ headers: {
98
+ 'Content-Type' => 'application/json',
99
+ 'Authorization' => "Bearer #{@token}"
100
+ }
101
+ )
102
+ response = conn.delete("/api/v1/admin/themes/#{theme_id}/assets?key=#{asset_key}")
103
+ end
104
+
105
+ def compare_and_delete(theme)
106
+ conn = Faraday.new(
107
+ url: @root_api,
108
+ params: {param: '1'},
109
+ headers: {
110
+ 'Content-Type' => 'application/json',
111
+ 'Authorization' => "Bearer #{@token}"
112
+ }
113
+ )
114
+ response = get_theme_by_name(name: theme)
115
+ check_authorized(response)
116
+ theme_id = JSON.parse(response.body)['theme']['id']
117
+ response = conn.get("/api/v1/admin/themes/#{theme_id}/assets")
118
+ remote_assets = JSON.parse(response.body)['assets'].map{|x| x['asset_key']}
119
+
120
+ local_assets = []
121
+
122
+ Dir.entries('.').each do |dir|
123
+ if ALLOWED_DIRS.include?(dir) && File.directory?(dir)
124
+ Dir.entries(dir).reject{|x| [".", ".."].include?(x)}.each do |file|
125
+ file_path = "#{dir}/#{file}"
126
+ local_assets << file_path
127
+ end
128
+ end
129
+ end
130
+
131
+ assets_to_be_deleted = remote_assets - local_assets
132
+ assets_to_be_deleted.each do |asset_key|
133
+ delete_remote(theme, asset_key)
134
+ end
135
+ end
136
+
137
+
138
+
139
+ def get_asset_key(file)
140
+ folder, file = File.split(file)
141
+ dir = File.split(folder).last
142
+ "#{dir}/#{file}"
143
+ end
144
+
145
+ def sync_all(theme)
146
+ compare_and_delete(theme)
147
+ Dir.entries('.').each do |dir|
148
+ if ALLOWED_DIRS.include?(dir) && File.directory?(dir)
149
+ puts "--#{dir}"
150
+ Dir.entries(dir).reject{|x| [".", ".."].include?(x)}.each do |file|
151
+ puts "----#{file}"
152
+ file_path = "./#{dir}/#{file}"
153
+ sync_file(theme, file_path)
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ def watch(theme_name)
160
+ Filewatcher.new(ALLOWED_DIRS).watch do |changes|
161
+ changes.each do |filename, event|
162
+ puts "#{filename} #{event}"
163
+ if event == :updated || event == :created
164
+ sync_file(theme_name, filename)
165
+ elsif event == :deleted
166
+ sync_delete(theme_name, filename)
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ def get_theme_by_name(name:)
173
+ conn = Faraday.new(
174
+ url: "#{@root_api}/api/v1/admin/themes/by_name?name=#{name}",
175
+ headers: {
176
+ 'Content-Type' => 'application/json',
177
+ 'Authorization' => "Bearer #{@token}"
178
+ }
179
+ )
180
+
181
+ response = conn.get
182
+ end
183
+
184
+
185
+
186
+ def pull_theme(name)
187
+ response = get_theme_by_name(name: name)
188
+ check_authorized(response)
189
+ parsed_response = JSON.parse(response.body)
190
+
191
+ conn = Faraday.new(
192
+ url: "#{root_api}/api/v1/admin/themes/#{parsed_response['theme']['id']}/pull",
193
+ params: {param: '1'},
194
+ headers: {
195
+ 'Content-Type' => 'application/json',
196
+ 'Authorization' => "Bearer #{@token}"
197
+ }
198
+ )
199
+ response = conn.get
200
+
201
+ assets = JSON.parse(response.body)['assets']
202
+
203
+ assets.each do |asset|
204
+ say "downloading #{asset['asset_key']}"
205
+ response = download_asset(theme_id: parsed_response['theme']['id'], key: asset['asset_key'])
206
+ path = File.split(asset['asset_key'])
207
+ FileUtils.mkdir(path.first) unless Dir.exists?(path.first)
208
+ File.open(asset['asset_key'], 'wb') do |f|
209
+ f.write(response.body)
210
+ end
211
+ end
212
+
213
+ if response.status == 200
214
+ say "theme created"
215
+ else
216
+ say response.body
217
+ end
218
+ end
219
+
220
+ def delete_theme(name)
221
+ response = get_theme_by_name(name: name)
222
+ check_authorized(response)
223
+ parsed_response = JSON.parse(response.body)
224
+ conn = Faraday.new(
225
+ url: "#{root_api}/api/v1/admin/themes/#{parsed_response['theme']['id']}",
226
+ params: {param: '1'},
227
+ headers: {
228
+ 'Content-Type' => 'application/json',
229
+ 'Authorization' => "Bearer #{@token}"
230
+ }
231
+ )
232
+ response = conn.delete
233
+ end
234
+
235
+ def create_theme(name)
236
+ conn = Faraday.new(
237
+ url: "#{root_api}/api/v1/admin/themes",
238
+ params: {param: '1'},
239
+ headers: {
240
+ 'Content-Type' => 'application/json',
241
+ 'Authorization' => "Bearer #{@token}"
242
+ }
243
+ )
244
+ response = conn.post do |req|
245
+ req.body = {
246
+ theme: {
247
+ name: name
248
+ }
249
+ }.to_json
250
+ end
251
+ end
252
+
253
+ def set_current_theme(name)
254
+ response = get_theme_by_name(name: name)
255
+ check_authorized(response)
256
+ parsed_response = JSON.parse(response.body)
257
+ conn = Faraday.new(
258
+ url: "#{root_api}/api/v1/admin/themes/#{parsed_response['theme']['id']}/set_current",
259
+ params: {param: '1'},
260
+ headers: {
261
+ 'Content-Type' => 'application/json',
262
+ 'Authorization' => "Bearer #{@token}"
263
+ }
264
+ )
265
+ response = conn.patch do |req|
266
+ req.body = {}.to_json
267
+ end
268
+ end
269
+
270
+ private
271
+
272
+ def download_asset(theme_id:, key:)
273
+ conn = Faraday.new(
274
+ url: "#{root_api}/api/v1/admin/themes/#{theme_id}/assets/download?key=#{key}",
275
+ params: {param: '1'},
276
+ headers: {
277
+ 'Content-Type' => 'application/json',
278
+ 'Authorization' => "Bearer #{@token}"
279
+ }
280
+ )
281
+ response = conn.get
282
+ end
283
+
284
+
285
+ end
data/lib/pagiii.rb ADDED
@@ -0,0 +1,5 @@
1
+
2
+ module Pagiii
3
+ end
4
+
5
+ require 'pagiii/theme_sync'
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pagiii
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.7
5
+ platform: ruby
6
+ authors:
7
+ - Sugiarto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-06-14 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: CLI to support themes on pagiii CMS
14
+ email:
15
+ - ugidmtest@gmail.com
16
+ executables:
17
+ - pagiii
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/pagiii
22
+ - lib/pagiii.rb
23
+ - lib/pagiii/info.rb
24
+ - lib/pagiii/theme_sync.rb
25
+ homepage: http://rubygems.org/gems/pagiii
26
+ licenses:
27
+ - MIT
28
+ metadata: {}
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubygems_version: 3.1.4
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: Pagiii CLI
48
+ test_files: []