solutus 0.0.8 → 0.0.9
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/lib/solutus.rb +169 -92
- data/resources/404.html +27 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4aeee0bf89def35ee1d8f9ef1679c8922068575c9804df2be0a2bc9a077f4aec
|
4
|
+
data.tar.gz: f0a0ea1447c199be711a07834bfee3ddd02cb0bbaad75f627527648dc92c3948
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd52de693cd3915faf620286dbdaeabfafa5dc47a7fb82cfac1cb72ecc0b48ccdc100d70712a0150217803b3392a1de8520a27df1399d434fa509e63fd396a00
|
7
|
+
data.tar.gz: 180770a7761f4368ec9c842aec46ee6b29ba28020995af4633ee39c3b8a198524878a433cbdab0de8f3f22380ba3ad5878934675627e2a8abffe14de0a6acdc5
|
data/lib/solutus.rb
CHANGED
@@ -7,22 +7,27 @@ require 'json'
|
|
7
7
|
require 'nokogiri'
|
8
8
|
|
9
9
|
class Solutus
|
10
|
+
ARCHIVE = "archive"
|
10
11
|
DEFAULT_TEMPLATE = "default"
|
11
12
|
BLOG_TEMPLATE = "post"
|
12
13
|
BUILD_PATH = "deploy"
|
13
14
|
SITE_PATH = File.join(BUILD_PATH, "site")
|
14
|
-
BLOG_BUILD_PATH = File.join(SITE_PATH,
|
15
|
+
BLOG_BUILD_PATH = File.join(SITE_PATH, ARCHIVE)
|
15
16
|
STATIC_PATH = "static"
|
16
17
|
TEMPLATES_PATH = "templates"
|
17
18
|
SITE_PAGES_PATH = File.join("pages", "site-pages")
|
18
19
|
POSTS_PATH = File.join("pages", "posts")
|
19
20
|
BLOG_DATE_FORMAT = "%b %e, %Y"
|
20
21
|
SETTINGS_FILE = "settings.yml"
|
22
|
+
CACHE = ".solutus-cache"
|
21
23
|
DAY_ENDINGS = ["th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "st"]
|
22
24
|
|
23
25
|
@@blog_urls = Hash.new
|
24
26
|
@@page_urls = Array.new
|
25
27
|
|
28
|
+
class SolutusStache < Mustache
|
29
|
+
end
|
30
|
+
|
26
31
|
def self.load_settings
|
27
32
|
begin
|
28
33
|
yml_text = ""
|
@@ -33,7 +38,7 @@ class Solutus
|
|
33
38
|
f.close
|
34
39
|
YAML.load(yml_text)
|
35
40
|
rescue
|
36
|
-
puts "settings.yml not found"
|
41
|
+
puts "Not a Solutus Project (yet) --- settings.yml not found"
|
37
42
|
end
|
38
43
|
end
|
39
44
|
|
@@ -114,11 +119,35 @@ class Solutus
|
|
114
119
|
"saved post @ #{path}"
|
115
120
|
end
|
116
121
|
|
122
|
+
get "/:page" do
|
123
|
+
path = File.join(settings.public_folder, params['page'], 'index.html')
|
124
|
+
if File.file?(path)
|
125
|
+
send_file path
|
126
|
+
else
|
127
|
+
send_404
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
get "/archive/:year/:month/:day/:title" do
|
132
|
+
path = File.join(settings.public_folder, ARCHIVE,
|
133
|
+
params['year'], params["month"], params["day"], params["title"],
|
134
|
+
'index.html')
|
135
|
+
if File.file?(path)
|
136
|
+
send_file path
|
137
|
+
else
|
138
|
+
send_404
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def send_404
|
143
|
+
send_file File.join(path_to_resources, "404.html")
|
144
|
+
end
|
145
|
+
|
117
146
|
def path_to_resources
|
118
147
|
File.join(File.dirname(File.expand_path(__FILE__)), '../resources')
|
119
148
|
end
|
120
149
|
|
121
|
-
class ServerStache < Mustache
|
150
|
+
class ServerStache < Mustache
|
122
151
|
end
|
123
152
|
|
124
153
|
def render_edit_page(path)
|
@@ -147,6 +176,7 @@ class Solutus
|
|
147
176
|
page_html = Solutus.render_page(Solutus.templates, settings.global_settings, data)
|
148
177
|
parser = Nokogiri::HTML(page_html)
|
149
178
|
parser.at_css("#solutus-content")['contenteditable'] = true
|
179
|
+
parser.at_css("#solutus-content")['style'] = "border: 1px black dashed"
|
150
180
|
result[:everything] = parser.at_css("#solutus-everything")
|
151
181
|
result.render
|
152
182
|
end
|
@@ -159,8 +189,8 @@ class Solutus
|
|
159
189
|
end
|
160
190
|
f.close
|
161
191
|
|
162
|
-
|
163
|
-
result =
|
192
|
+
SolutusStache.template = template
|
193
|
+
result = SolutusStache.new
|
164
194
|
|
165
195
|
f = File.open(path, "r")
|
166
196
|
file_contents = ""
|
@@ -184,8 +214,8 @@ class Solutus
|
|
184
214
|
template += line
|
185
215
|
end
|
186
216
|
f.close
|
187
|
-
|
188
|
-
result =
|
217
|
+
SolutusStache.template = template
|
218
|
+
result = SolutusStache.new
|
189
219
|
settings.global_settings.each do |key, val|
|
190
220
|
result[key.to_sym] = val
|
191
221
|
end
|
@@ -239,15 +269,18 @@ class Solutus
|
|
239
269
|
if args.length >= 1
|
240
270
|
if args[0] == "deploy"
|
241
271
|
deploy
|
242
|
-
elsif args[0] == "
|
272
|
+
elsif args[0] == "build"
|
243
273
|
build
|
274
|
+
elsif args[0] == "serve"
|
275
|
+
build #right now, the server won't werve unless its built.
|
276
|
+
#consider serializing data in cache to save time.
|
277
|
+
#TODO: Stress test the build for speed.
|
244
278
|
serve
|
245
279
|
return
|
246
|
-
elsif args[0] == "
|
280
|
+
elsif args[0] == "start"
|
281
|
+
build
|
247
282
|
serve
|
248
283
|
return
|
249
|
-
elsif args[0] == "build"
|
250
|
-
build
|
251
284
|
elsif args[0] == "publish"
|
252
285
|
build
|
253
286
|
deploy
|
@@ -270,7 +303,7 @@ class Solutus
|
|
270
303
|
end
|
271
304
|
end
|
272
305
|
else
|
273
|
-
puts "Unknown command"
|
306
|
+
puts "Unknown command."
|
274
307
|
return
|
275
308
|
end
|
276
309
|
end
|
@@ -278,20 +311,22 @@ class Solutus
|
|
278
311
|
|
279
312
|
end_time = Time.now
|
280
313
|
diff = end_time - start_time
|
281
|
-
puts "
|
314
|
+
puts "Completed in #{diff} seconds."
|
282
315
|
end
|
283
316
|
|
284
317
|
def self.deploy
|
318
|
+
puts "Solutus is deploying"
|
285
319
|
system load_settings["deploy-command"]
|
286
320
|
end
|
287
321
|
|
288
322
|
def self.serve
|
289
|
-
|
290
|
-
puts "http://localhost:4567/
|
323
|
+
puts "Solutus is serving"
|
324
|
+
puts "View at http://localhost:4567/"
|
291
325
|
Solutus_Server.run!
|
292
326
|
end
|
293
327
|
|
294
328
|
def self.build
|
329
|
+
puts "Solutus is building the static site"
|
295
330
|
settings_data = load_settings
|
296
331
|
|
297
332
|
if File.directory?(BUILD_PATH)
|
@@ -316,30 +351,7 @@ class Solutus
|
|
316
351
|
end
|
317
352
|
end
|
318
353
|
|
319
|
-
|
320
|
-
Dir.entries(SITE_PAGES_PATH).each do |entry|
|
321
|
-
next if entry == "." || entry == ".."
|
322
|
-
puts "Rendering page #{entry}"
|
323
|
-
path = File.join(SITE_PAGES_PATH, entry)
|
324
|
-
if File.file?(path)
|
325
|
-
yml_text = ""
|
326
|
-
f = File.open(path, "r")
|
327
|
-
f.each_line do |line|
|
328
|
-
yml_text += line
|
329
|
-
end
|
330
|
-
data = YAML.load(yml_text)
|
331
|
-
html = render_page(@@templates, settings_data, data, false)
|
332
|
-
new_path = File.join(SITE_PATH, entry.split(".")[0] + ".html")
|
333
|
-
f = File.new(new_path, "w")
|
334
|
-
puts "Created #{new_path}"
|
335
|
-
f.write(html)
|
336
|
-
f.close
|
337
|
-
@@page_urls.push({
|
338
|
-
"title" => data["title"],
|
339
|
-
"file_path" => path
|
340
|
-
})
|
341
|
-
end
|
342
|
-
end
|
354
|
+
yaml_data = Hash.new
|
343
355
|
|
344
356
|
@@blog_urls = Hash.new
|
345
357
|
Dir.entries(POSTS_PATH).each do |entry|
|
@@ -351,27 +363,46 @@ class Solutus
|
|
351
363
|
contents += line
|
352
364
|
end
|
353
365
|
f.close
|
366
|
+
|
367
|
+
yaml_data[entry] = contents
|
354
368
|
data = YAML.load(contents)
|
355
|
-
markdown_parsed = render_markdown(contents.split("---")[-1])
|
356
|
-
data["content"] = markdown_parsed
|
357
369
|
date = data["date"]
|
358
|
-
|
359
|
-
puts "Rendering blog post #{entry}"
|
360
|
-
html = render_page(@@templates, settings_data, data, true)
|
361
|
-
|
362
|
-
relative_dir = File.join(date.year.to_s, date.month.to_s, date.day.to_s)
|
363
|
-
root_url = File.join("archive", relative_dir, entry.split(".")[0] + ".html")
|
364
|
-
|
370
|
+
relative_dir = File.join(date.year.to_s, date.month.to_s, date.day.to_s, entry.split(".")[0])
|
365
371
|
year = date.year.to_s
|
366
372
|
if !@@blog_urls.key?(year)
|
367
373
|
@@blog_urls[year] = Array.new
|
368
374
|
end
|
369
375
|
@@blog_urls[year].push({
|
370
376
|
"title" => data["title"],
|
371
|
-
"url" =>
|
377
|
+
"url" => File.join(ARCHIVE, relative_dir),
|
372
378
|
"file_path" => path,
|
373
379
|
"date" => date
|
374
380
|
})
|
381
|
+
end
|
382
|
+
|
383
|
+
recents_count = 3
|
384
|
+
recents = ""
|
385
|
+
get_recents(recents_count).reverse.each do |post|
|
386
|
+
url = post["url"]
|
387
|
+
title = post["title"]
|
388
|
+
recents += "<div class=\"solutus-recent-posts\"><a href=\"#{url}\">#{title}</a></div>"
|
389
|
+
end
|
390
|
+
|
391
|
+
yaml_data.each do |entry, contents|
|
392
|
+
path = File.join(POSTS_PATH, entry)
|
393
|
+
data = YAML.load(contents)
|
394
|
+
markdown_parsed = render_markdown(contents.split("---")[-1])
|
395
|
+
data["content"] = markdown_parsed
|
396
|
+
data["recents"] = recents
|
397
|
+
date = data["date"]
|
398
|
+
|
399
|
+
puts "Rendering blog post #{entry}"
|
400
|
+
html = render_page(@@templates, settings_data, data, true)
|
401
|
+
|
402
|
+
relative_dir = File.join(date.year.to_s, date.month.to_s, date.day.to_s, entry.split(".")[0])
|
403
|
+
root_url = File.join(ARCHIVE, relative_dir, "index.html")
|
404
|
+
|
405
|
+
year = date.year.to_s
|
375
406
|
|
376
407
|
dir_path = File.join(BLOG_BUILD_PATH, relative_dir)
|
377
408
|
if !File.directory?(dir_path)
|
@@ -382,9 +413,43 @@ class Solutus
|
|
382
413
|
f = File.new(file_path, "w")
|
383
414
|
f.write(html)
|
384
415
|
f.close()
|
385
|
-
end
|
416
|
+
end
|
386
417
|
|
387
|
-
|
418
|
+
@@page_urls = Array.new
|
419
|
+
Dir.entries(SITE_PAGES_PATH).each do |entry|
|
420
|
+
next if entry == "." || entry == ".."
|
421
|
+
puts "Rendering page #{entry}"
|
422
|
+
path = File.join(SITE_PAGES_PATH, entry)
|
423
|
+
if File.file?(path)
|
424
|
+
yml_text = ""
|
425
|
+
f = File.open(path, "r")
|
426
|
+
f.each_line do |line|
|
427
|
+
yml_text += line
|
428
|
+
end
|
429
|
+
data = YAML.load(yml_text)
|
430
|
+
data["recents"] = recents
|
431
|
+
html = render_page(@@templates, settings_data, data, false)
|
432
|
+
new_dir = File.join(SITE_PATH, entry.split(".")[0])
|
433
|
+
if ["error", "index"].include? entry.split(".")[0]
|
434
|
+
new_path = File.join(SITE_PATH, entry.split(".")[0] + ".html")
|
435
|
+
else
|
436
|
+
if !File.directory?(new_dir)
|
437
|
+
FileUtils.mkdir_p(new_dir)
|
438
|
+
end
|
439
|
+
new_path = File.join(new_dir, "index.html")
|
440
|
+
end
|
441
|
+
f = File.new(new_path, "w")
|
442
|
+
puts "Created #{new_path}"
|
443
|
+
f.write(html)
|
444
|
+
f.close
|
445
|
+
@@page_urls.push({
|
446
|
+
"title" => data["title"],
|
447
|
+
"file_path" => path
|
448
|
+
})
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
# Create blog archive page
|
388
453
|
content = ""
|
389
454
|
@@blog_urls.each do |yr, arr|
|
390
455
|
sorted = arr.sort_by {|k| k["date"]} .reverse
|
@@ -400,16 +465,18 @@ class Solutus
|
|
400
465
|
content += "</div>"
|
401
466
|
end
|
402
467
|
end
|
403
|
-
path = File.join(SITE_PATH, "
|
468
|
+
path = File.join(SITE_PATH, ARCHIVE, "index.html")
|
404
469
|
data = Hash.new
|
405
470
|
data["title"] = "Archive"
|
406
471
|
data["content"] = content
|
472
|
+
data["recents"] = recents
|
407
473
|
html = render_page(@@templates, settings_data, data, false)
|
408
474
|
f = File.new(path, "w")
|
409
475
|
f.write(html)
|
410
476
|
f.close
|
411
477
|
puts "Created blog archive @ #{path}"
|
412
478
|
|
479
|
+
# Mirror build
|
413
480
|
if settings_data["mirror"]
|
414
481
|
dir_path = settings_data["mirror"]
|
415
482
|
FileUtils.rm_rf("#{dir_path}/.", secure: true)
|
@@ -417,6 +484,28 @@ class Solutus
|
|
417
484
|
end
|
418
485
|
end
|
419
486
|
|
487
|
+
def self.render_page(templates, default_data, data, blog=false)
|
488
|
+
if data.key?("template")
|
489
|
+
SolutusStache.template = templates[data["template"]]
|
490
|
+
else
|
491
|
+
SolutusStache.template = templates[DEFAULT_TEMPLATE]
|
492
|
+
end
|
493
|
+
result = SolutusStache.new
|
494
|
+
default_data.each do |key, val|
|
495
|
+
result[key.to_sym] = val
|
496
|
+
end
|
497
|
+
data.each do |key, val|
|
498
|
+
next if key == "template"
|
499
|
+
if key != "title"
|
500
|
+
val = wrap_element(key, val)
|
501
|
+
end
|
502
|
+
result[key.to_sym] = val
|
503
|
+
end
|
504
|
+
result[:blog] = blog
|
505
|
+
result[:year] = Time.now.year
|
506
|
+
result.render
|
507
|
+
end
|
508
|
+
|
420
509
|
def self.new_page(title)
|
421
510
|
file_title = title.gsub(/\s+/, "")
|
422
511
|
path = File.join(SITE_PAGES_PATH, file_title + ".yml")
|
@@ -440,10 +529,6 @@ HERE
|
|
440
529
|
puts "Created new site page #{title} at #{path}"
|
441
530
|
end
|
442
531
|
|
443
|
-
def self.correct_time(time)
|
444
|
-
time.utc.localtime("+05:30")
|
445
|
-
end
|
446
|
-
|
447
532
|
def self.new_post(title)
|
448
533
|
i = 1
|
449
534
|
new_title = title.gsub(/\s+/, "")
|
@@ -475,38 +560,6 @@ HERE
|
|
475
560
|
path
|
476
561
|
end
|
477
562
|
|
478
|
-
def self.render_page(templates, default_data, data, blog=false)
|
479
|
-
if data.key?("template")
|
480
|
-
Mustache.template = templates[data["template"]]
|
481
|
-
else
|
482
|
-
Mustache.template = templates[DEFAULT_TEMPLATE]
|
483
|
-
end
|
484
|
-
result = Mustache.new
|
485
|
-
default_data.each do |key, val|
|
486
|
-
result[key.to_sym] = val
|
487
|
-
end
|
488
|
-
data.each do |key, val|
|
489
|
-
next if key == "template"
|
490
|
-
if key != "title"
|
491
|
-
val = wrap_element(key, val)
|
492
|
-
end
|
493
|
-
result[key.to_sym] = val
|
494
|
-
end
|
495
|
-
result[:blog] = blog
|
496
|
-
result.render
|
497
|
-
end
|
498
|
-
|
499
|
-
def self.wrap_element(key, content)
|
500
|
-
if content.is_a?(Time)
|
501
|
-
content = correct_time(content).strftime(BLOG_DATE_FORMAT)
|
502
|
-
end
|
503
|
-
result = ""
|
504
|
-
result += "<div id=\"solutus-#{key}\">\n"
|
505
|
-
result += content
|
506
|
-
result += "</div>"
|
507
|
-
result
|
508
|
-
end
|
509
|
-
|
510
563
|
def self.copy_static
|
511
564
|
Dir.entries(STATIC_PATH).each do |entry|
|
512
565
|
next if entry == "." || entry == ".."
|
@@ -521,10 +574,33 @@ HERE
|
|
521
574
|
end
|
522
575
|
end
|
523
576
|
|
577
|
+
def self.get_recents(count)
|
578
|
+
res = Array.new
|
579
|
+
@@blog_urls.each do |yr, arr|
|
580
|
+
res = res + arr.sort_by {|k| k["date"]}
|
581
|
+
end
|
582
|
+
res.last(count)
|
583
|
+
end
|
584
|
+
|
585
|
+
def self.correct_time(time)
|
586
|
+
time.utc.localtime("+05:30")
|
587
|
+
end
|
588
|
+
|
524
589
|
def self.render_markdown(markdown)
|
525
590
|
Redcarpet::Markdown.new(Redcarpet::Render::HTML.new).render(markdown)
|
526
591
|
end
|
527
592
|
|
593
|
+
def self.wrap_element(key, content)
|
594
|
+
if content.is_a?(Time)
|
595
|
+
content = correct_time(content).strftime(BLOG_DATE_FORMAT)
|
596
|
+
end
|
597
|
+
result = ""
|
598
|
+
result += "<div id=\"solutus-#{key}\">\n"
|
599
|
+
result += content
|
600
|
+
result += "</div>"
|
601
|
+
result
|
602
|
+
end
|
603
|
+
|
528
604
|
def self.new_project(name)
|
529
605
|
if File.directory?(name)
|
530
606
|
puts "Invalid name, already a folder with that name"
|
@@ -539,7 +615,7 @@ HERE
|
|
539
615
|
Dir.mkdir(name)
|
540
616
|
|
541
617
|
paths = Array.new
|
542
|
-
["deploy", "static", "templates", "pages"].each do |dir|
|
618
|
+
["deploy", "static", "templates", "pages", CACHE].each do |dir|
|
543
619
|
paths.push(File.join(name, dir))
|
544
620
|
end
|
545
621
|
["css", "js", "imgs"].each do |dir|
|
@@ -560,12 +636,13 @@ domain: www.yoursite.tld
|
|
560
636
|
deploy-command: aws s3 sync --acl public-read --sse --delete deploy/site/ s3://www.yoursite.tld
|
561
637
|
watermark: |
|
562
638
|
<p style="text-align: center;">
|
563
|
-
<small>Powered by <a href="https://
|
639
|
+
<small>Powered by <a href="https://github.com/jeromew21/solutus">Solutus</a></small>
|
564
640
|
</p>
|
565
641
|
stylesheets: |
|
566
642
|
<link rel="stylesheet" type="text/css" href="/css/styles.css" />
|
567
643
|
scripts: |
|
568
|
-
<script></script>
|
644
|
+
<script></script>
|
645
|
+
recents-count: 3
|
569
646
|
HERE
|
570
647
|
|
571
648
|
styles_file = <<HERE
|
@@ -587,7 +664,7 @@ HERE
|
|
587
664
|
{{{date}}}
|
588
665
|
{{/blog}}
|
589
666
|
{{{content}}}
|
590
|
-
<small style="display: block; text-align: center;">© {{author}}</small>
|
667
|
+
<small style="display: block; text-align: center;">© {{year}} {{author}}</small>
|
591
668
|
{{{watermark}}}
|
592
669
|
</div>
|
593
670
|
{{{scripts}}}
|
data/resources/404.html
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<head>
|
3
|
+
<title>Error 404</title>
|
4
|
+
<style type="text/css">
|
5
|
+
body {
|
6
|
+
margin:40px auto;
|
7
|
+
background-color: #eeeeee;
|
8
|
+
max-width:650px;
|
9
|
+
line-height:1.6;
|
10
|
+
font-size:18px;
|
11
|
+
color:#444;
|
12
|
+
padding:0 10px;
|
13
|
+
font-family: "Segoe UI", sans-serif;
|
14
|
+
}
|
15
|
+
|
16
|
+
h1, h2, h3 {
|
17
|
+
line-height:1.2
|
18
|
+
}
|
19
|
+
</style>
|
20
|
+
</head>
|
21
|
+
|
22
|
+
<body>
|
23
|
+
<h1>Error 404: Page Not Found</h1>
|
24
|
+
<p><a href="/">Back to site</a></p>
|
25
|
+
<p><a href="/edit">Back to edit</a></p>
|
26
|
+
</body>
|
27
|
+
</html>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solutus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jerome Wei
|
@@ -75,6 +75,7 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- bin/solutus
|
77
77
|
- lib/solutus.rb
|
78
|
+
- resources/404.html
|
78
79
|
- resources/editBlog.html
|
79
80
|
- resources/editPage.html
|
80
81
|
- resources/index.html
|