solutus 0.0.1

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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/bin/solutus +4 -0
  3. data/lib/solutus.rb +342 -0
  4. metadata +46 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 726e73c608c5ee52e178eb44a2b8c49b4c045c91691931a060fdea8c4d5eb4b0
4
+ data.tar.gz: e596ad97cc3e985b693d0836f80a10cd48545457e0aacb668b97599b4ac96d44
5
+ SHA512:
6
+ metadata.gz: 740a22d2d1054ff79d0a5458ceeea692e752b49cb7f20ec228592842acb2901464c09ef88e66b34ceecd1d479063be53b3006c7c19af40062900df450acd2de7
7
+ data.tar.gz: 5c6844b88e67dec102939d105f369bd65420e096e5af6d543480f594a18b504bc298cc6041f697d26a49c574f281de63b9ae9250fa7e54b3f5da7365d54d8297
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solutus'
4
+ Solutus.command(*ARGV)
@@ -0,0 +1,342 @@
1
+ require 'fileutils'
2
+ require 'yaml'
3
+ require 'sinatra/base'
4
+ require 'mustache'
5
+ require 'redcarpet'
6
+
7
+ class Solutus
8
+ DEFAULT_TEMPLATE = "default"
9
+ BLOG_TEMPLATE = "post"
10
+ BUILD_PATH = "deploy"
11
+ SITE_PATH = File.join(BUILD_PATH, "site")
12
+ STATIC_PATH = "static"
13
+ TEMPLATES_PATH = "templates"
14
+ SITE_PAGES_PATH = File.join("pages", "site-pages")
15
+ POSTS_PATH = File.join("pages", "posts")
16
+ BLOG_DATE_FORMAT = "%b %-d, %Y"
17
+
18
+ class Solutus_Server < Sinatra::Base
19
+ set :public_folder, SITE_PATH
20
+
21
+ get "/" do
22
+ send_file File.join(settings.public_folder, 'index.html')
23
+ end
24
+
25
+ get "/edit" do
26
+ redirect '/edit/'
27
+ end
28
+
29
+ get "/edit/?" do
30
+ "Edit your site!"
31
+ end
32
+ end
33
+
34
+ def self.command(*args)
35
+ start_time = Time.now
36
+
37
+ if args.length >= 1
38
+ if args[0] == "start"
39
+ build
40
+ serve
41
+ return
42
+ elsif args[0] == "serve"
43
+ serve
44
+ return
45
+ elsif args[0] == "build"
46
+ build
47
+ else
48
+ if args.length >= 2
49
+ if args[0] == "create"
50
+ new_project(args[1])
51
+ else
52
+ if args.length >= 3
53
+ if args[0] == "new"
54
+ if args[1] == "page"
55
+ new_page(args[2])
56
+ elsif args[1] == "post"
57
+ new_post(args[2])
58
+ end
59
+ end
60
+ else
61
+ puts "Unknown command"
62
+ end
63
+ end
64
+ else
65
+ puts "Not enough arguments"
66
+ end
67
+ end
68
+ end
69
+
70
+ end_time = Time.now
71
+ diff = end_time - start_time
72
+ puts "Finished in #{diff} seconds."
73
+ end
74
+
75
+ def self.serve
76
+ #TODO: RESTART THE SERVER WHEN LOCAL CHANGES ARE MADE! REBUILD ERRYTHANG
77
+ puts "http://localhost:4567/site/"
78
+ Solutus_Server.run!
79
+ end
80
+
81
+ def self.build
82
+ if File.directory?(BUILD_PATH)
83
+ FileUtils.remove_dir(BUILD_PATH)
84
+ end
85
+ Dir.mkdir(BUILD_PATH)
86
+ Dir.mkdir(SITE_PATH)
87
+ copy_static
88
+
89
+ templates = Hash.new
90
+ Dir.entries(TEMPLATES_PATH).each do |entry|
91
+ next if entry == "." || entry == ".."
92
+ puts "Loading template #{entry}"
93
+ path = File.join(TEMPLATES_PATH, entry)
94
+ if File.file?(path)
95
+ contents = ""
96
+ f = File.open(path, "r")
97
+ f.each_line do |line|
98
+ contents += line
99
+ end
100
+ templates[entry.split(".")[0]] = contents
101
+ end
102
+ end
103
+
104
+ Dir.entries(SITE_PAGES_PATH).each do |entry|
105
+ next if entry == "." || entry == ".."
106
+ puts "Rendering page #{entry}"
107
+ path = File.join(SITE_PAGES_PATH, entry)
108
+ if File.file?(path)
109
+ yml_text = ""
110
+ f = File.open(path, "r")
111
+ f.each_line do |line|
112
+ yml_text += line
113
+ end
114
+ data = YAML.load(yml_text)
115
+ html = render_page(templates, data, false)
116
+ new_path = File.join(SITE_PATH, entry.split(".")[0] + ".html")
117
+ f = File.new(new_path, "w")
118
+ puts "Created #{new_path}"
119
+ f.write(html)
120
+ f.close
121
+ end
122
+ end
123
+
124
+ Dir.entries(POSTS_PATH).each do |entry|
125
+ next if entry == "." || entry == ".."
126
+ path = File.join(POSTS_PATH, entry)
127
+ f = File.open(path, "r")
128
+ contents = ""
129
+ f.each_line do |line|
130
+ contents += line
131
+ end
132
+ f.close
133
+ data = YAML.load(contents)
134
+ markdown_parsed = render_markdown(contents.split("---")[-1])
135
+ data["content"] = markdown_parsed
136
+ date = data["date"]
137
+
138
+ puts "Rendering blog post #{entry}"
139
+ html = render_page(templates, data, true)
140
+
141
+ dir_path = File.join(SITE_PATH, date.year.to_s, date.month.to_s, date.day.to_s)
142
+ if !File.directory?(dir_path)
143
+ FileUtils.mkdir_p(dir_path)
144
+ end
145
+ file_path = File.join(dir_path, entry.split(".")[0] + ".html")
146
+ puts "Created #{file_path}"
147
+ f = File.new(file_path, "w")
148
+ f.write(html)
149
+ f.close()
150
+ end
151
+ #TODO: CREATE SOME FCUKIN BLOG NAVIGATION HTML PAGES
152
+
153
+ end
154
+
155
+ def self.new_page(title)
156
+ file_title = title.gsub(/\s+/, "")
157
+ path = File.join(SITE_PAGES_PATH, file_title + ".yml")
158
+ if File.file?(path)
159
+ puts "Page with that name already exists."
160
+ return
161
+ end
162
+
163
+ text = <<HERE
164
+ template: default
165
+ title: #{title}
166
+ content: |
167
+ <h1>#{title}</h1>
168
+ <p>
169
+ Some Content
170
+ </p>
171
+ HERE
172
+ f = File.new(path, "w")
173
+ f.write(text)
174
+ f.close
175
+ puts "Created new site page #{title} at #{path}"
176
+ end
177
+
178
+ def self.new_post(title)
179
+ i = 1
180
+ new_title = title.gsub(/\s+/, "")
181
+ while true
182
+ path = File.join(POSTS_PATH, new_title + ".md")
183
+ if File.file?(path)
184
+ new_title = title + "#{i}"
185
+ i += 1
186
+ else
187
+ break
188
+ end
189
+ end
190
+ date = Time.now.strftime("%Y-%m-%e %I:%M:%S")
191
+ text = <<HERE
192
+ ---
193
+ title: #{title}
194
+ date: #{date}
195
+ ---
196
+ *This is a test blog post page!*
197
+ HERE
198
+ f = File.new(path, "w")
199
+ f.write(text)
200
+ f.close
201
+ puts "Created new blog post #{title} at #{path}"
202
+ end
203
+
204
+ def self.render_page(templates, data, blog)
205
+ if data.key?("template")
206
+ Mustache.template = templates[data["template"]]
207
+ else
208
+ Mustache.template = templates[DEFAULT_TEMPLATE]
209
+ end
210
+ result = Mustache.new
211
+ data.each do |key, val|
212
+ next if key == "template"
213
+ if key != "title"
214
+ val = wrap_element(key, val)
215
+ end
216
+ result[key.to_sym] = val
217
+ end
218
+ result[:blog] = blog
219
+ result.render
220
+ end
221
+
222
+ def self.wrap_element(key, content)
223
+ if content.is_a?(Time)
224
+ content = content.strftime(BLOG_DATE_FORMAT)
225
+ end
226
+ result = ""
227
+ result += "<div id=\"solutus-#{key}\">\n"
228
+ result += content
229
+ result += "</div>"
230
+ result
231
+ end
232
+
233
+ def self.copy_static
234
+ Dir.entries(STATIC_PATH).each do |entry|
235
+ next if entry == "." || entry == ".."
236
+ path = File.join(STATIC_PATH, entry)
237
+ if File.file?(path)
238
+ puts "Copying static file #{path}"
239
+ FileUtils.copy(path, File.join(SITE_PATH, entry))
240
+ elsif File.directory?(path)
241
+ puts "Recursively copying static dir #{path}"
242
+ FileUtils.copy_entry(path, File.join(SITE_PATH, entry))
243
+ end
244
+ end
245
+ end
246
+
247
+ def self.render_markdown(markdown)
248
+ Redcarpet::Markdown.new(Redcarpet::Render::HTML.new).render(markdown)
249
+ end
250
+
251
+ def self.new_project(name)
252
+ if File.directory?(name)
253
+ puts "Invalid name, already a folder with that name"
254
+ print "Overwrite? [Y/n]"
255
+ if STDIN.gets.chomp == "Y"
256
+ FileUtils.remove_dir(name)
257
+ else
258
+ return
259
+ end
260
+ end
261
+
262
+ Dir.mkdir(name)
263
+
264
+ paths = Array.new
265
+ ["deploy", "static", "server", "templates", "pages"].each do |dir|
266
+ paths.push(File.join(name, dir))
267
+ end
268
+ ["css", "js", "imgs"].each do |dir|
269
+ paths.push(File.join(name, "static", dir))
270
+ end
271
+ ["posts", "site-pages"].each do |dir|
272
+ paths.push(File.join(name, "pages", dir))
273
+ end
274
+
275
+ paths.each do |path|
276
+ Dir.mkdir(path)
277
+ end
278
+
279
+ settings_file = <<HERE
280
+ name: #{name}
281
+ author: Your Name
282
+ HERE
283
+
284
+ styles_file = <<HERE
285
+ body {
286
+ background-color: grey;
287
+ }
288
+ HERE
289
+
290
+ default_file = <<HERE
291
+ <!DOCTYPE html>
292
+ <head>
293
+ <title>{{title}}</title>
294
+ <link rel="stylesheet" type="text/css" href="/css/styles.css" />
295
+ </head>
296
+ <body>
297
+ <div id="solutus-everything">
298
+ {{#blog}}
299
+ <h1>{{title}}</h1>
300
+ {{date}}
301
+ {{/blog}}
302
+ {{{content}}}
303
+ </div>
304
+ </body>
305
+ </html>
306
+ HERE
307
+
308
+ test_file = <<HERE
309
+ title: Example Blog Post
310
+ date: 2018-05-10 03:43:20
311
+ ---
312
+ *This is an example blog post page!*
313
+ HERE
314
+
315
+ index_file = <<HERE
316
+ template: default
317
+ title: Home page
318
+ content: |
319
+ <h1>Hello World!</h1>
320
+ <p>
321
+ this is a test
322
+ </p>
323
+ HERE
324
+
325
+ files = {
326
+ File.join(name, "settings.yml") => settings_file,
327
+ File.join(name, "static", "css", "styles.css") => styles_file,
328
+ File.join(name, "templates", "default.html") => default_file,
329
+ File.join(name, "pages", "posts", "test.md") => test_file,
330
+ File.join(name, "pages", "site-pages", "index.yml") => index_file,
331
+ }
332
+
333
+ files.each do |filename, contents|
334
+ puts "Created #{filename}"
335
+ f = File.new(filename, "w")
336
+ f.write(contents)
337
+ f.close
338
+ end
339
+
340
+ puts "Created new project #{name}"
341
+ end
342
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: solutus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jerome Wei
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-05-15 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A miminal static site generator
14
+ email: jeromew@berkeley.edu
15
+ executables:
16
+ - solutus
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/solutus
21
+ - lib/solutus.rb
22
+ homepage: https://github.com/jeromew21/solutus
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.7.6
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: A miminal static site generator
46
+ test_files: []