runeblog 0.2.99 → 0.3.05
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/bin/blog +24 -18
- data/data/features.txt +18 -0
- data/data/global.lt3 +6 -24
- data/data/universal.lt3 +2 -5
- data/empty_view/remote/banner/navbar/GIT_IS_DUMB +0 -0
- data/empty_view/settings/features.txt +18 -0
- data/empty_view/settings/publish.txt +5 -0
- data/empty_view/settings/recent.txt +11 -0
- data/empty_view/settings/view.txt +4 -0
- data/empty_view/themes/standard/banner/top.lt3 +2 -2
- data/lib/helpers-blog.rb +26 -20
- data/lib/helpers-repl.rb +3 -41
- data/lib/liveblog.rb +11 -11
- data/lib/lowlevel.rb +9 -0
- data/lib/publish.rb +2 -0
- data/lib/repl.rb +104 -177
- data/lib/runeblog.rb +106 -48
- data/lib/runeblog_version.rb +1 -1
- data/lib/view.rb +6 -0
- data/runeblog.gemspec +1 -1
- data/test/austin.rb +15 -18
- metadata +12 -8
- data/empty_view/themes/standard/global.lt3 +0 -32
- data/empty_view/themes/standard/recent.txt +0 -6
data/lib/runeblog.rb
CHANGED
@@ -40,7 +40,7 @@ class RuneBlog
|
|
40
40
|
end
|
41
41
|
|
42
42
|
attr_reader :views, :sequence
|
43
|
-
attr_accessor :root, :editor
|
43
|
+
attr_accessor :root, :editor, :features
|
44
44
|
attr_accessor :view # overridden
|
45
45
|
|
46
46
|
attr_accessor :post_views, :post_tags, :dirty_views
|
@@ -75,15 +75,6 @@ class RuneBlog
|
|
75
75
|
|
76
76
|
end
|
77
77
|
|
78
|
-
def _tmp_error(err) # FIXME move to helpers
|
79
|
-
out = "/tmp/blog#{rand(100)}.txt"
|
80
|
-
File.open(out, "w") do |f|
|
81
|
-
f.puts err
|
82
|
-
f.puts err.backtrace.join("\n")
|
83
|
-
end
|
84
|
-
puts "Error: See #{out}"
|
85
|
-
end
|
86
|
-
|
87
78
|
def self.create_new_blog_repo(root_rel = ".blogs")
|
88
79
|
log!(enter: __method__, args: [root_rel])
|
89
80
|
raise ArgumentError unless root_rel.is_a?(String) && ! root_rel.empty?
|
@@ -120,8 +111,9 @@ class RuneBlog
|
|
120
111
|
self.class.blog = self # Weird. Like a singleton - dumbass circular dependency?
|
121
112
|
|
122
113
|
@root = Dir.pwd/root_rel
|
123
|
-
write_repo_config(root: @root)
|
114
|
+
write_repo_config(root: @root) # ?? FIXME
|
124
115
|
get_repo_config
|
116
|
+
read_features # top level
|
125
117
|
@views = retrieve_views
|
126
118
|
self.view = File.read(@root/"data/VIEW").chomp
|
127
119
|
md = Dir.pwd.match(%r[.*/views/(.*?)/])
|
@@ -134,16 +126,67 @@ class RuneBlog
|
|
134
126
|
@post_tags = []
|
135
127
|
end
|
136
128
|
|
129
|
+
def complete_file(name, vars, hash)
|
130
|
+
debugging = vars.nil?
|
131
|
+
return if hash.empty?
|
132
|
+
text = File.read(name)
|
133
|
+
if vars.nil? # FIXME dumbest hack ever?
|
134
|
+
vars = {}
|
135
|
+
hash.values.each {|val| vars[val] = val }
|
136
|
+
end
|
137
|
+
|
138
|
+
hash.each_pair {|key, var| text.gsub!(key, vars[var]) }
|
139
|
+
File.write(name, text)
|
140
|
+
end
|
141
|
+
|
142
|
+
def _generate_settings(view = nil)
|
143
|
+
vars = read_vars("#@root/data/universal.lt3")
|
144
|
+
hash = {/AUTHOR/ => "view.author",
|
145
|
+
/SITE/ => "view.site",
|
146
|
+
/FONT/ => "font.family",
|
147
|
+
/CHARSET/ => :charset,
|
148
|
+
/LOCALE/ => :locale}
|
149
|
+
|
150
|
+
# rubytext.txt - LATER
|
151
|
+
# complete_file(settings/"rubytext.txt", {}
|
152
|
+
|
153
|
+
if view
|
154
|
+
settings = @root/view/"settings"
|
155
|
+
### ??? Where to get hash of view-specific vars?
|
156
|
+
|
157
|
+
# features.txt - handle specially
|
158
|
+
fname = settings/"features.txt"
|
159
|
+
|
160
|
+
# view.txt
|
161
|
+
complete_file(settings/"view.txt",
|
162
|
+
/AUTHOR/ => "view.author",
|
163
|
+
/TITLE/ => "view.title",
|
164
|
+
/SUBTITLE/ => "view.subtitle",
|
165
|
+
/SITE/ => "view.site")
|
166
|
+
|
167
|
+
# publish.txt
|
168
|
+
complete_file(settings/"publish.txt",
|
169
|
+
/USER/ => "publish.user",
|
170
|
+
/SERVER/ => "publish.server",
|
171
|
+
/DOCROOT/ => "publish.docroot",
|
172
|
+
/PATH/ => "publish.path",
|
173
|
+
/PROTO/ => "publish.proto")
|
174
|
+
|
175
|
+
# recent.txt - SKIP THIS?
|
176
|
+
complete_file(settings/"recent.txt", {})
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
137
180
|
def _generate_global
|
138
181
|
vars = read_vars("#@root/data/universal.lt3")
|
139
182
|
gfile = "#@root/data/global.lt3"
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
183
|
+
hash = {/AUTHOR/ => "univ.author",
|
184
|
+
/SITE/ => "univ.site",
|
185
|
+
/FONT/ => "font.family",
|
186
|
+
/CHARSET/ => :charset,
|
187
|
+
/LOCALE/ => :locale}
|
188
|
+
complete_file(gfile, vars, hash)
|
189
|
+
_generate_settings
|
147
190
|
end
|
148
191
|
|
149
192
|
def _deploy_local(dir)
|
@@ -151,10 +194,7 @@ class RuneBlog
|
|
151
194
|
Dir.chdir(dir) do
|
152
195
|
views = _retrieve_metadata(:views)
|
153
196
|
views.each do |v|
|
154
|
-
unless
|
155
|
-
puts "#{fx("Warning:", :red)} #{fx(v, :bold)} is not a view"
|
156
|
-
next
|
157
|
-
end
|
197
|
+
next unless _check_view?(v)
|
158
198
|
system!("cp *html #@root/views/#{v}/remote", show: true)
|
159
199
|
end
|
160
200
|
end
|
@@ -162,6 +202,8 @@ class RuneBlog
|
|
162
202
|
_tmp_error(err)
|
163
203
|
end
|
164
204
|
|
205
|
+
# FIXME reconcile with _get_draft data
|
206
|
+
|
165
207
|
def _retrieve_metadata(key)
|
166
208
|
key = key.to_s
|
167
209
|
lines = File.readlines("metadata.txt")
|
@@ -244,11 +286,15 @@ class RuneBlog
|
|
244
286
|
@view = nil
|
245
287
|
when RuneBlog::View
|
246
288
|
@view = arg
|
289
|
+
read_features(@view)
|
290
|
+
@view.get_globals
|
247
291
|
_set_publisher
|
248
292
|
when String
|
249
293
|
new_view = str2view(arg)
|
250
294
|
raise NoSuchView(arg) if new_view.nil?
|
251
295
|
@view = new_view
|
296
|
+
read_features(@view)
|
297
|
+
@view.get_globals
|
252
298
|
_set_publisher
|
253
299
|
else
|
254
300
|
raise CantAssignView(arg.class.to_s)
|
@@ -324,6 +370,7 @@ class RuneBlog
|
|
324
370
|
add_view(view_name)
|
325
371
|
mark_last_published("Initial creation")
|
326
372
|
system("cp #@root/data/global.lt3 #@root/views/#{view_name}/themes/standard/global.lt3")
|
373
|
+
@view.get_globals
|
327
374
|
rescue => err
|
328
375
|
_tmp_error(err)
|
329
376
|
end
|
@@ -404,16 +451,18 @@ class RuneBlog
|
|
404
451
|
return posts[0..19] # return 20 at most
|
405
452
|
end
|
406
453
|
|
407
|
-
def collect_recent_posts(file)
|
454
|
+
def collect_recent_posts(file = "recent.html")
|
408
455
|
log!(enter: __method__, args: [file], level: 3)
|
456
|
+
vars = self.view.globals
|
409
457
|
text = <<-HTML
|
410
458
|
<html>
|
411
459
|
<head><link rel="stylesheet" href="etc/blog.css"></head>
|
412
|
-
<body>
|
460
|
+
<body style="background-color: #{vars["recent.bgcolor"]}">
|
413
461
|
HTML
|
414
462
|
posts = _sorted_posts
|
415
463
|
if posts.size > 0
|
416
|
-
|
464
|
+
# estimate how many we want
|
465
|
+
wanted = [vars["recent.count"].to_i, posts.size].min
|
417
466
|
enum = posts.each
|
418
467
|
entries = []
|
419
468
|
wanted.times do
|
@@ -485,7 +534,7 @@ class RuneBlog
|
|
485
534
|
log!(enter: __method__, args: [view], pwd: true, dir: true)
|
486
535
|
raise ArgumentError unless view.is_a?(String) || view.is_a?(RuneBlog::View)
|
487
536
|
@vdir = @root/:views/view
|
488
|
-
num = collect_recent_posts
|
537
|
+
num = collect_recent_posts
|
489
538
|
return num
|
490
539
|
rescue => err
|
491
540
|
_tmp_error(err)
|
@@ -506,7 +555,7 @@ class RuneBlog
|
|
506
555
|
call: ".nopara"
|
507
556
|
copy!("#{vdir}/themes/standard/banner/*", "#{vdir}/remote/banner/") # includes navbar/
|
508
557
|
copy("#{vdir}/assets/*", "#{vdir}/remote/assets/")
|
509
|
-
# rebuild widgets
|
558
|
+
# rebuild widgets?
|
510
559
|
copy_widget_html(view)
|
511
560
|
rescue => err
|
512
561
|
STDERR.puts err
|
@@ -514,6 +563,27 @@ class RuneBlog
|
|
514
563
|
# _tmp_error(err)
|
515
564
|
end
|
516
565
|
|
566
|
+
def _get_draft_data(num, sym)
|
567
|
+
tag = prefix(num)
|
568
|
+
front = @blog.root/:drafts/tag
|
569
|
+
files = Dir[front + "*"]
|
570
|
+
raise "No draft #{num} found" if files.empty?
|
571
|
+
raise "Too many files found for #{num}!" if files.size > 1
|
572
|
+
file = files.first
|
573
|
+
lines = File.readlines(file)
|
574
|
+
case sym
|
575
|
+
when :views
|
576
|
+
view_line = lines.grep(/^.views /)
|
577
|
+
raise "More than one .views call in #{draft}" if view_line.size > 1
|
578
|
+
raise "No .views call in #{draft}" if view_line.size < 1
|
579
|
+
view_line = view_line.first
|
580
|
+
views = view_line[7..-1].split
|
581
|
+
return views.uniq
|
582
|
+
else
|
583
|
+
raise "Unknown symbol #{sym.inspect}"
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
517
587
|
def _get_views(draft)
|
518
588
|
log!(enter: __method__, args: [draft], level: 2)
|
519
589
|
# FIXME dumb code
|
@@ -603,6 +673,8 @@ class RuneBlog
|
|
603
673
|
log!(enter: __method__, args: [draft, view_name], level: 2)
|
604
674
|
# break into separate methods?
|
605
675
|
|
676
|
+
return unless _check_view?(view_name)
|
677
|
+
|
606
678
|
fname = File.basename(draft) # 0001-this-is-a-post.lt3
|
607
679
|
nslug = fname.sub(/.lt3$/, "") # 0001-this-is-a-post
|
608
680
|
aslug = nslug.sub(/\d\d\d\d-/, "") # this-is-a-post
|
@@ -632,30 +704,16 @@ class RuneBlog
|
|
632
704
|
_tmp_error(err)
|
633
705
|
end
|
634
706
|
|
707
|
+
def _check_view?(view)
|
708
|
+
flag = self.view?(view)
|
709
|
+
puts " Warning: '#{view}' is not a view" unless flag
|
710
|
+
flag
|
711
|
+
end
|
712
|
+
|
635
713
|
def generate_post(draft, force = false)
|
636
714
|
log!(enter: __method__, args: [draft], level: 1)
|
637
715
|
views = _get_views(draft)
|
638
|
-
views.each
|
639
|
-
unless self.view?(view)
|
640
|
-
puts "Warning: '#{view}' is not a view"
|
641
|
-
next
|
642
|
-
end
|
643
|
-
_handle_post(draft, view)
|
644
|
-
end
|
645
|
-
rescue => err
|
646
|
-
_tmp_error(err)
|
647
|
-
end
|
648
|
-
|
649
|
-
def rebuild_post(file)
|
650
|
-
log!(enter: __method__, args: [file])
|
651
|
-
raise "Doesn't currently work"
|
652
|
-
debug "Called rebuild_post(#{file.inspect})"
|
653
|
-
raise ArgumentError unless file.is_a?(String)
|
654
|
-
meta = process_post(file)
|
655
|
-
@views_dirty ||= []
|
656
|
-
@views_dirty << meta.views
|
657
|
-
@views_dirty.flatten!
|
658
|
-
@views_dirty.uniq!
|
716
|
+
views.each {|view| _handle_post(draft, view) }
|
659
717
|
rescue => err
|
660
718
|
_tmp_error(err)
|
661
719
|
end
|
data/lib/runeblog_version.rb
CHANGED
data/lib/view.rb
CHANGED
@@ -14,7 +14,13 @@ class RuneBlog::View
|
|
14
14
|
@publisher = RuneBlog::Publishing.new(name)
|
15
15
|
@can_publish = true # FIXME
|
16
16
|
@blog.view = self
|
17
|
+
get_globals
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_globals
|
17
21
|
gfile = @blog.root/"views/#{name}/themes/standard/global.lt3"
|
22
|
+
return unless File.exist?(gfile) # Hackish!! how is View.new called from create_view??
|
23
|
+
|
18
24
|
live = Livetext.customize(call: ".nopara")
|
19
25
|
live.xform_file(gfile)
|
20
26
|
@globals = live.vars
|
data/runeblog.gemspec
CHANGED
@@ -20,7 +20,7 @@ spec = Gem::Specification.new do |s|
|
|
20
20
|
s.authors = ["Hal Fulton"]
|
21
21
|
s.email = 'rubyhacker@gmail.com'
|
22
22
|
s.executables << "blog"
|
23
|
-
s.add_runtime_dependency 'livetext', '~> 0.
|
23
|
+
s.add_runtime_dependency 'livetext', '~> 0.9', '>= 0.9.01'
|
24
24
|
s.add_runtime_dependency 'rubytext', '~> 0.1', '>= 0.1.20'
|
25
25
|
|
26
26
|
s.add_development_dependency 'minitest', '~> 5.10', '>= 5.10.0'
|
data/test/austin.rb
CHANGED
@@ -31,7 +31,7 @@ end
|
|
31
31
|
@fake_date = Date.today - 20
|
32
32
|
|
33
33
|
def make_post(x, title, teaser, body, views=[])
|
34
|
-
debug "
|
34
|
+
debug " make_post #{bold(title)}"
|
35
35
|
pubdate = @fake_date.strftime("%Y-%m-%d")
|
36
36
|
@fake_date += (rand(2) + 1)
|
37
37
|
x.create_new_post(title, true, teaser: teaser, body: body, views: views,
|
@@ -53,28 +53,26 @@ puts
|
|
53
53
|
debug bold("Generating test blog...")
|
54
54
|
|
55
55
|
system("rm -rf .blogs")
|
56
|
-
RuneBlog.create_new_blog_repo(".blogs")
|
57
|
-
x = RuneBlog.new(".blogs")
|
56
|
+
RuneBlog.create_new_blog_repo # (".blogs")
|
57
|
+
x = RuneBlog.new # (".blogs")
|
58
58
|
|
59
59
|
debug("create_view: #{bold('around_austin')}")
|
60
60
|
x.create_view("around_austin") # FIXME remember view title!
|
61
61
|
|
62
|
-
#### FIXME
|
63
|
-
vars = <<-VARS
|
64
|
-
|
65
|
-
.variables
|
66
|
-
blog Around Austin
|
67
|
-
blog.desc The view from downtown...
|
62
|
+
#### FIXME
|
68
63
|
|
69
|
-
|
70
|
-
|
64
|
+
vars = <<-VARS
|
65
|
+
author Hal Fulton
|
66
|
+
title Around Austin
|
67
|
+
subtitle The view from downtown...
|
68
|
+
domain foo.com
|
71
69
|
VARS
|
72
|
-
|
73
|
-
|
74
|
-
|
70
|
+
vfile = ".blogs/views/around_austin/settings/view.txt"
|
71
|
+
File.open(vfile, "w") {|f| f.puts vars }
|
72
|
+
|
75
73
|
####
|
76
74
|
|
77
|
-
debug("
|
75
|
+
debug("change_view: #{bold('around_austin')}")
|
78
76
|
x.change_view("around_austin") # 1 2 7 8 9
|
79
77
|
|
80
78
|
make_post(x, "What's at Stubbs...", <<-EXCERPT, <<-BODY)
|
@@ -144,11 +142,10 @@ But I first heard of them
|
|
144
142
|
in 2005.
|
145
143
|
BODY
|
146
144
|
|
147
|
-
debug
|
148
|
-
debug "** generate_index #{bold("around_austin")}"
|
145
|
+
debug "generate_index #{bold("around_austin")}"
|
149
146
|
x.generate_index("around_austin")
|
150
147
|
|
151
|
-
debug("
|
148
|
+
debug("generate_view: #{bold('around_austin')}")
|
152
149
|
x.generate_view("around_austin")
|
153
150
|
|
154
151
|
debug bold("...finished.\n")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: runeblog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.05
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hal Fulton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: livetext
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.9'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: 0.9.01
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '0.
|
29
|
+
version: '0.9'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
32
|
+
version: 0.9.01
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rubytext
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- data/EDITOR
|
86
86
|
- data/ROOT
|
87
87
|
- data/VIEW
|
88
|
+
- data/features.txt
|
88
89
|
- data/global.lt3
|
89
90
|
- data/universal.lt3
|
90
91
|
- empty_view/assets/austin-pano.jpg
|
@@ -109,6 +110,7 @@ files:
|
|
109
110
|
- empty_view/config/twitter/twitter.rb
|
110
111
|
- empty_view/posts/GIT_IS_DUMB
|
111
112
|
- empty_view/remote/assets/GIT_IS_DUMB
|
113
|
+
- empty_view/remote/banner/navbar/GIT_IS_DUMB
|
112
114
|
- empty_view/remote/etc/GIT_IS_DUMB
|
113
115
|
- empty_view/remote/permalink/GIT_IS_DUMB
|
114
116
|
- empty_view/remote/widgets/ad/GIT_IS_DUMB
|
@@ -116,6 +118,10 @@ files:
|
|
116
118
|
- empty_view/remote/widgets/news/GIT_IS_DUMB
|
117
119
|
- empty_view/remote/widgets/pages/GIT_IS_DUMB
|
118
120
|
- empty_view/remote/widgets/pinned/GIT_IS_DUMB
|
121
|
+
- empty_view/settings/features.txt
|
122
|
+
- empty_view/settings/publish.txt
|
123
|
+
- empty_view/settings/recent.txt
|
124
|
+
- empty_view/settings/view.txt
|
119
125
|
- empty_view/themes/standard/README
|
120
126
|
- empty_view/themes/standard/banner/banner.lt3
|
121
127
|
- empty_view/themes/standard/banner/navbar/about.lt3
|
@@ -131,12 +137,10 @@ files:
|
|
131
137
|
- empty_view/themes/standard/etc/externals.lt3
|
132
138
|
- empty_view/themes/standard/etc/favicon.ico
|
133
139
|
- empty_view/themes/standard/etc/misc.js
|
134
|
-
- empty_view/themes/standard/global.lt3
|
135
140
|
- empty_view/themes/standard/post/generate.lt3
|
136
141
|
- empty_view/themes/standard/post/head.lt3
|
137
142
|
- empty_view/themes/standard/post/index.lt3
|
138
143
|
- empty_view/themes/standard/post/permalink.lt3
|
139
|
-
- empty_view/themes/standard/recent.txt
|
140
144
|
- empty_view/themes/standard/widgets/README
|
141
145
|
- empty_view/themes/standard/widgets/ad/ad.lt3
|
142
146
|
- empty_view/themes/standard/widgets/ad/ad1.png
|
@@ -1,32 +0,0 @@
|
|
1
|
-
. --------------------------------------------------
|
2
|
-
. Global settings are stored here in the form
|
3
|
-
. <variable> <value>
|
4
|
-
. --------------------------------------------------
|
5
|
-
|
6
|
-
.variables
|
7
|
-
author Your name here
|
8
|
-
blog Blog title goes here
|
9
|
-
blog.desc Subtitle (if any) goes here
|
10
|
-
site rubyhacker.com
|
11
|
-
|
12
|
-
host localhost:4000//
|
13
|
-
charset utf-8
|
14
|
-
url localhost:4000//
|
15
|
-
locale en_US
|
16
|
-
|
17
|
-
font.family verdana
|
18
|
-
|
19
|
-
recent.title.color #010101
|
20
|
-
recent.title.size 28px
|
21
|
-
recent.text.color #0101a1
|
22
|
-
recent.text.size 22px
|
23
|
-
recent.date.color #9a9a9a
|
24
|
-
recent.date.size 15px
|
25
|
-
|
26
|
-
publish.user root
|
27
|
-
publish.server rubyhacker.com
|
28
|
-
publish.docroot /var/www/
|
29
|
-
publish.path stuff
|
30
|
-
publish.proto http
|
31
|
-
.end
|
32
|
-
|