solutus 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []