runeblog 0.3.02
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 +7 -0
- data/README.lt3 +279 -0
- data/README.md +312 -0
- data/bin/blog +200 -0
- data/bin/mkwidget +164 -0
- data/data/EDITOR +1 -0
- data/data/ROOT +1 -0
- data/data/VIEW +1 -0
- data/data/features.txt +18 -0
- data/data/global.lt3 +20 -0
- data/data/universal.lt3 +18 -0
- data/empty_view/assets/austin-pano.jpg +0 -0
- data/empty_view/assets/sky2.jpg +0 -0
- data/empty_view/config/exper/2svg.lt3 +38 -0
- data/empty_view/config/exper/gen_svg.rb +60 -0
- data/empty_view/config/exper/meta.html +10 -0
- data/empty_view/config/exper/s2.html +25 -0
- data/empty_view/config/exper/varmint.rb +50 -0
- data/empty_view/config/facebook/credentials.txt +7 -0
- data/empty_view/config/facebook/facebook.rb +42 -0
- data/empty_view/config/facebook/fb.html +10 -0
- data/empty_view/config/facebook/fb.js.lt3 +15 -0
- data/empty_view/config/reddit/credentials.txt +6 -0
- data/empty_view/config/reddit/notes.txt +4 -0
- data/empty_view/config/reddit/reddit_post_url.py +34 -0
- data/empty_view/config/reddit/redpost.rb +43 -0
- data/empty_view/config/reddit/the-graffiti-wall.html +91 -0
- data/empty_view/config/twitter/credentials.txt +3 -0
- data/empty_view/config/twitter/tw.html +12 -0
- data/empty_view/config/twitter/tw.js +5 -0
- data/empty_view/config/twitter/twitter.rb +35 -0
- data/empty_view/posts/GIT_IS_DUMB +1 -0
- data/empty_view/remote/assets/GIT_IS_DUMB +1 -0
- data/empty_view/remote/banner/navbar/GIT_IS_DUMB +0 -0
- data/empty_view/remote/etc/GIT_IS_DUMB +1 -0
- data/empty_view/remote/permalink/GIT_IS_DUMB +1 -0
- data/empty_view/remote/widgets/ad/GIT_IS_DUMB +2 -0
- data/empty_view/remote/widgets/links/GIT_IS_DUMB +2 -0
- data/empty_view/remote/widgets/news/GIT_IS_DUMB +2 -0
- data/empty_view/remote/widgets/pages/GIT_IS_DUMB +2 -0
- data/empty_view/remote/widgets/pinned/GIT_IS_DUMB +2 -0
- data/empty_view/settings/features.txt +18 -0
- data/empty_view/settings/publish.txt +5 -0
- data/empty_view/settings/recent.txt +6 -0
- data/empty_view/settings/view.txt +4 -0
- data/empty_view/themes/standard/README +59 -0
- data/empty_view/themes/standard/banner/banner.lt3 +5 -0
- data/empty_view/themes/standard/banner/navbar/about.lt3 +18 -0
- data/empty_view/themes/standard/banner/navbar/contact.lt3 +18 -0
- data/empty_view/themes/standard/banner/navbar/faq.lt3 +1 -0
- data/empty_view/themes/standard/banner/navbar/list.data +3 -0
- data/empty_view/themes/standard/banner/top.lt3 +20 -0
- data/empty_view/themes/standard/blog/generate.lt3 +21 -0
- data/empty_view/themes/standard/blog/head.lt3 +16 -0
- data/empty_view/themes/standard/blog/index.lt3 +17 -0
- data/empty_view/themes/standard/blog/post_entry.lt3 +21 -0
- data/empty_view/themes/standard/etc/blog.css.lt3 +62 -0
- data/empty_view/themes/standard/etc/externals.lt3 +24 -0
- data/empty_view/themes/standard/etc/favicon.ico +0 -0
- data/empty_view/themes/standard/etc/misc.js +20 -0
- data/empty_view/themes/standard/post/generate.lt3 +38 -0
- data/empty_view/themes/standard/post/head.lt3 +7 -0
- data/empty_view/themes/standard/post/index.lt3 +24 -0
- data/empty_view/themes/standard/post/permalink.lt3 +32 -0
- data/empty_view/themes/standard/widgets/README +4 -0
- data/empty_view/themes/standard/widgets/ad/ad.lt3 +22 -0
- data/empty_view/themes/standard/widgets/ad/ad1.png +0 -0
- data/empty_view/themes/standard/widgets/ad/ad2.png +0 -0
- data/empty_view/themes/standard/widgets/ad/ad3.png +0 -0
- data/empty_view/themes/standard/widgets/ad/ad4.png +0 -0
- data/empty_view/themes/standard/widgets/bydates/README +2 -0
- data/empty_view/themes/standard/widgets/bydates/bydates.rb +18 -0
- data/empty_view/themes/standard/widgets/bydates/card.css +1 -0
- data/empty_view/themes/standard/widgets/bydates/custom.rb +1 -0
- data/empty_view/themes/standard/widgets/bydates/main.css +2 -0
- data/empty_view/themes/standard/widgets/links/README +2 -0
- data/empty_view/themes/standard/widgets/links/card.css +1 -0
- data/empty_view/themes/standard/widgets/links/custom.rb +1 -0
- data/empty_view/themes/standard/widgets/links/links.rb +90 -0
- data/empty_view/themes/standard/widgets/links/list.data +3 -0
- data/empty_view/themes/standard/widgets/links/main.css +2 -0
- data/empty_view/themes/standard/widgets/news/README +2 -0
- data/empty_view/themes/standard/widgets/news/card.css +1 -0
- data/empty_view/themes/standard/widgets/news/custom.rb +1 -0
- data/empty_view/themes/standard/widgets/news/list.data +4 -0
- data/empty_view/themes/standard/widgets/news/main.css +2 -0
- data/empty_view/themes/standard/widgets/news/news.rb +88 -0
- data/empty_view/themes/standard/widgets/pages/README +2 -0
- data/empty_view/themes/standard/widgets/pages/card.css +1 -0
- data/empty_view/themes/standard/widgets/pages/custom.rb +1 -0
- data/empty_view/themes/standard/widgets/pages/disclaim.lt3 +10 -0
- data/empty_view/themes/standard/widgets/pages/faq.lt3 +40 -0
- data/empty_view/themes/standard/widgets/pages/like-dislike.lt3 +11 -0
- data/empty_view/themes/standard/widgets/pages/list.data +4 -0
- data/empty_view/themes/standard/widgets/pages/local.rb +0 -0
- data/empty_view/themes/standard/widgets/pages/main.css +2 -0
- data/empty_view/themes/standard/widgets/pages/other-stuff.lt3 +10 -0
- data/empty_view/themes/standard/widgets/pages/pages.rb +95 -0
- data/empty_view/themes/standard/widgets/pinned/README +2 -0
- data/empty_view/themes/standard/widgets/pinned/card.css +1 -0
- data/empty_view/themes/standard/widgets/pinned/custom.rb +1 -0
- data/empty_view/themes/standard/widgets/pinned/main.css +2 -0
- data/empty_view/themes/standard/widgets/pinned/pinned.rb +99 -0
- data/empty_view/themes/standard/widgets/search/README +2 -0
- data/empty_view/themes/standard/widgets/search/card.css +1 -0
- data/empty_view/themes/standard/widgets/search/custom.rb +1 -0
- data/empty_view/themes/standard/widgets/search/main.css +2 -0
- data/empty_view/themes/standard/widgets/search/search.rb +18 -0
- data/empty_view/themes/standard/widgets/sitemap/README +2 -0
- data/empty_view/themes/standard/widgets/sitemap/card.css +1 -0
- data/empty_view/themes/standard/widgets/sitemap/custom.rb +1 -0
- data/empty_view/themes/standard/widgets/sitemap/main.css +2 -0
- data/empty_view/themes/standard/widgets/sitemap/sitemap.rb +18 -0
- data/empty_view/themes/standard/widgets/tag-cloud/OLD-example.lt3 +12 -0
- data/empty_view/themes/standard/widgets/tag-cloud/README +2 -0
- data/empty_view/themes/standard/widgets/tag-cloud/card.css +1 -0
- data/empty_view/themes/standard/widgets/tag-cloud/custom.rb +1 -0
- data/empty_view/themes/standard/widgets/tag-cloud/main.css +2 -0
- data/empty_view/themes/standard/widgets/tag-cloud/tag-cloud.lt3 +3 -0
- data/empty_view/themes/standard/widgets/tag-cloud/tag-cloud.rb +18 -0
- data/lib/Javascript.stuff +69 -0
- data/lib/helpers-blog.rb +155 -0
- data/lib/helpers-repl.rb +201 -0
- data/lib/liveblog.rb +825 -0
- data/lib/logging.rb +44 -0
- data/lib/lowlevel.rb +73 -0
- data/lib/pathmagic.rb +14 -0
- data/lib/post.rb +211 -0
- data/lib/processing.rb +60 -0
- data/lib/publish.rb +73 -0
- data/lib/repl.rb +597 -0
- data/lib/runeblog.rb +773 -0
- data/lib/runeblog_version.rb +50 -0
- data/lib/view.rb +69 -0
- data/runeblog.gemspec +42 -0
- data/test/austin.rb +158 -0
- data/test/fakeimage.jpg +0 -0
- data/test/general_test.rb +304 -0
- data/test/make_blog.rb +196 -0
- data/test/test +3 -0
- metadata +242 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
if !defined?(RuneBlog::Path)
|
|
2
|
+
|
|
3
|
+
# if ! (Object.constants.include?(:RuneBlog) && RuneBlog.constants.include?(:Path))
|
|
4
|
+
|
|
5
|
+
class RuneBlog
|
|
6
|
+
VERSION = "0.3.02"
|
|
7
|
+
|
|
8
|
+
path = Gem.find_files("runeblog").grep(/runeblog-/).first
|
|
9
|
+
Path = File.dirname(path)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# skeleton
|
|
13
|
+
|
|
14
|
+
class RuneBlog
|
|
15
|
+
module Helpers
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Default
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class View
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class Publishing
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class Post
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Refactor, move stuff elsewhere?
|
|
32
|
+
|
|
33
|
+
def make_exception(sym, str)
|
|
34
|
+
log!(enter: __method__, args: [sym, str], level: 3)
|
|
35
|
+
return if Object.constants.include?(sym)
|
|
36
|
+
Object.const_set(sym, StandardError.dup)
|
|
37
|
+
define_method(sym) do |*args|
|
|
38
|
+
msg = str
|
|
39
|
+
args.each.with_index {|arg, i| msg.sub!("$#{i+1}", arg) }
|
|
40
|
+
Object.class_eval(sym.to_s).new(msg)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def prefix(num)
|
|
45
|
+
log!(enter: __method__, args: [num], level: 3)
|
|
46
|
+
"#{'%04d' % num.to_i}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
end
|
data/lib/view.rb
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'logging'
|
|
2
|
+
|
|
3
|
+
class RuneBlog::View
|
|
4
|
+
attr_reader :name, :state, :globals
|
|
5
|
+
attr_accessor :publisher
|
|
6
|
+
|
|
7
|
+
include RuneBlog::Helpers
|
|
8
|
+
|
|
9
|
+
def initialize(name)
|
|
10
|
+
log!(enter: __method__, args: [name], level: 3)
|
|
11
|
+
raise NoBlogAccessor if RuneBlog.blog.nil?
|
|
12
|
+
@blog = RuneBlog.blog
|
|
13
|
+
@name = name
|
|
14
|
+
@publisher = RuneBlog::Publishing.new(name)
|
|
15
|
+
@can_publish = true # FIXME
|
|
16
|
+
@blog.view = self
|
|
17
|
+
gfile = @blog.root/"views/#{name}/themes/standard/global.lt3"
|
|
18
|
+
return unless File.exist?(gfile) # Hackish!! how is View.new called from create_view??
|
|
19
|
+
|
|
20
|
+
live = Livetext.customize(call: ".nopara")
|
|
21
|
+
live.xform_file(gfile)
|
|
22
|
+
@globals = live.vars
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def dir
|
|
26
|
+
@blog.root + "/views/#@name/"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def local_index
|
|
30
|
+
dir + "/remote/index.html"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def index
|
|
34
|
+
dir + "index.html"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_s
|
|
38
|
+
@name
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def publishable_files
|
|
42
|
+
log!(enter: __method__, level: 2)
|
|
43
|
+
vdir = dir()
|
|
44
|
+
remote = local_index()
|
|
45
|
+
files = [remote]
|
|
46
|
+
others = Dir.entries(vdir/:remote) - %w[. ..]
|
|
47
|
+
others.map! {|x| "#{vdir}/remote/#{x}" }
|
|
48
|
+
|
|
49
|
+
assets = Dir.entries("#{vdir}/assets") - %w[. ..]
|
|
50
|
+
assets.map! {|x| "#{vdir}/assets/#{x}" }
|
|
51
|
+
assets.reject! {|x| File.directory?(x) }
|
|
52
|
+
# assets.reject! {|x| ! recent?(x) }
|
|
53
|
+
files = files + others
|
|
54
|
+
all = files.dup
|
|
55
|
+
dirty = files.reject {|f| ! recent?(f) }
|
|
56
|
+
[dirty, all, assets]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def can_publish?
|
|
60
|
+
@can_publish
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def recent?(file)
|
|
64
|
+
File.mtime(file) > File.mtime("#{self.dir()}/last_published")
|
|
65
|
+
rescue
|
|
66
|
+
true
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
data/runeblog.gemspec
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'date'
|
|
2
|
+
require 'find'
|
|
3
|
+
|
|
4
|
+
$LOAD_PATH << "lib"
|
|
5
|
+
|
|
6
|
+
require "runeblog_version"
|
|
7
|
+
|
|
8
|
+
Gem.post_install do |spec|
|
|
9
|
+
Dir.chdir(RuneBlog::Path)
|
|
10
|
+
system("livetext -i liveblog.rb")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
spec = Gem::Specification.new do |s|
|
|
14
|
+
system("rm -f *.gem")
|
|
15
|
+
s.name = 'runeblog'
|
|
16
|
+
s.version = RuneBlog::VERSION
|
|
17
|
+
s.date = Date.today.strftime("%Y-%m-%d")
|
|
18
|
+
s.summary = "A command-line blogging system"
|
|
19
|
+
s.description = "A blog system based on Ruby and Livetext"
|
|
20
|
+
s.authors = ["Hal Fulton"]
|
|
21
|
+
s.email = 'rubyhacker@gmail.com'
|
|
22
|
+
s.executables << "blog"
|
|
23
|
+
s.add_runtime_dependency 'livetext', '~> 0.9', '>= 0.9.01'
|
|
24
|
+
s.add_runtime_dependency 'rubytext', '~> 0.1', '>= 0.1.20'
|
|
25
|
+
|
|
26
|
+
s.add_development_dependency 'minitest', '~> 5.10', '>= 5.10.0'
|
|
27
|
+
|
|
28
|
+
# Files...
|
|
29
|
+
main = Find.find("bin").to_a +
|
|
30
|
+
Find.find("lib").to_a
|
|
31
|
+
data = Find.find("data").to_a
|
|
32
|
+
test = Find.find("test").to_a
|
|
33
|
+
misc = %w[./README.lt3 ./README.md ./runeblog.gemspec]
|
|
34
|
+
empty_view = Find.find("empty_view").to_a
|
|
35
|
+
|
|
36
|
+
s.files = main + misc + data + test + empty_view
|
|
37
|
+
s.homepage = 'https://github.com/Hal9000/runeblog'
|
|
38
|
+
s.license = "Ruby"
|
|
39
|
+
s.post_install_message = "\n Success! Run 'blog' command and type h for help.\n "
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
spec
|
data/test/austin.rb
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
$LOAD_PATH << "./lib"
|
|
2
|
+
|
|
3
|
+
major, minor = RUBY_VERSION.split(".").values_at(0,1)
|
|
4
|
+
ver = major.to_i*10 + minor.to_i
|
|
5
|
+
abort "Need Ruby 2.4 or greater" unless ver >= 24
|
|
6
|
+
|
|
7
|
+
# Home = Dir.pwd
|
|
8
|
+
|
|
9
|
+
require 'date'
|
|
10
|
+
|
|
11
|
+
require 'runeblog'
|
|
12
|
+
require 'repl'
|
|
13
|
+
|
|
14
|
+
def bold(str)
|
|
15
|
+
"\e[1m#{str}\e[0m"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def getch
|
|
19
|
+
# sleep 5
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def debug(str = "")
|
|
23
|
+
t = Time.now
|
|
24
|
+
time = t.to_f.to_s
|
|
25
|
+
n = time.index(".")
|
|
26
|
+
msec = time[n..(n+2)]
|
|
27
|
+
time = t.strftime("%H:%M:%S") + msec
|
|
28
|
+
STDERR.puts "#{'%-11s' % time} #{str}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
@fake_date = Date.today - 20
|
|
32
|
+
|
|
33
|
+
def make_post(x, title, teaser, body, views=[])
|
|
34
|
+
debug " make_post #{bold(title)}"
|
|
35
|
+
pubdate = @fake_date.strftime("%Y-%m-%d")
|
|
36
|
+
@fake_date += (rand(2) + 1)
|
|
37
|
+
x.create_new_post(title, true, teaser: teaser, body: body, views: views,
|
|
38
|
+
pubdate: pubdate)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def show_lines(text)
|
|
42
|
+
lines = text.split("\n")
|
|
43
|
+
str = "#{lines.size} lines\n"
|
|
44
|
+
lines.each {|line| str << " #{line.inspect}\n" }
|
|
45
|
+
str
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# "Main"...
|
|
49
|
+
|
|
50
|
+
t0 = Time.now
|
|
51
|
+
|
|
52
|
+
puts
|
|
53
|
+
debug bold("Generating test blog...")
|
|
54
|
+
|
|
55
|
+
system("rm -rf .blogs")
|
|
56
|
+
RuneBlog.create_new_blog_repo(".blogs")
|
|
57
|
+
x = RuneBlog.new(".blogs")
|
|
58
|
+
|
|
59
|
+
debug("create_view: #{bold('around_austin')}")
|
|
60
|
+
x.create_view("around_austin") # FIXME remember view title!
|
|
61
|
+
|
|
62
|
+
#### FIXME
|
|
63
|
+
|
|
64
|
+
vars = <<-VARS
|
|
65
|
+
author Hal Fulton
|
|
66
|
+
title Around Austin
|
|
67
|
+
subtitle The view from downtown...
|
|
68
|
+
domain foo.com
|
|
69
|
+
VARS
|
|
70
|
+
vfile = ".blogs/views/around_austin/settings/view.txt"
|
|
71
|
+
File.open(vfile, "w") {|f| f.puts vars }
|
|
72
|
+
|
|
73
|
+
####
|
|
74
|
+
|
|
75
|
+
debug("-- change_view: #{bold('around_austin')}")
|
|
76
|
+
x.change_view("around_austin") # 1 2 7 8 9
|
|
77
|
+
|
|
78
|
+
make_post(x, "What's at Stubbs...", <<-EXCERPT, <<-BODY)
|
|
79
|
+
Stubbs has been around for longer than civilization.
|
|
80
|
+
EXCERPT
|
|
81
|
+
That's a good thing. But their music isn't always the greatest.
|
|
82
|
+
BODY
|
|
83
|
+
|
|
84
|
+
make_post(x, "The new amphitheatre is overrated", <<-EXCERPT, <<-BODY)
|
|
85
|
+
It used to be that all major concerts played the Erwin Center.
|
|
86
|
+
EXCERPT
|
|
87
|
+
.pin around_austin
|
|
88
|
+
Now, depending on what you consider "major," blah blah blah...
|
|
89
|
+
BODY
|
|
90
|
+
|
|
91
|
+
make_post(x, "The graffiti wall", <<-EXCERPT, <<-BODY)
|
|
92
|
+
RIP, Hope Gallery
|
|
93
|
+
EXCERPT
|
|
94
|
+
|
|
95
|
+
.dropcap It's been a while since I was there. They say it was torn down
|
|
96
|
+
while I wasn't looking. Never tagged anything there, of course, nor
|
|
97
|
+
anywhere else. Spraypainting public places isn't my thing, but in this
|
|
98
|
+
case I condoned it because it was sort of there for that purpose.
|
|
99
|
+
|
|
100
|
+
This fake entry is a long one so as to demonstrate both drop-caps
|
|
101
|
+
(above) and an inset quote. Blah blah blah. Lorem ipsum dolor and
|
|
102
|
+
a partridge in a pear tree.
|
|
103
|
+
|
|
104
|
+
.inset left 20
|
|
105
|
+
Wherever you go, there you are. Last night I saw upon the stair
|
|
106
|
+
a little man who was not there. He wasn't there again today; I
|
|
107
|
+
wish, I wish he'd go away. As far as we know, our computer has
|
|
108
|
+
never had an undetected error.
|
|
109
|
+
|On a clean disk, you can seek forever.
|
|
110
|
+
And never let it be denied that
|
|
111
|
+
pobbles are happier without their toes. And may your snark never
|
|
112
|
+
be a boojum. How do you know you aren't dreaming right now? When
|
|
113
|
+
you see a butterfly, think of Chuang Tzu.
|
|
114
|
+
.end
|
|
115
|
+
|
|
116
|
+
Contact light. Houston, this is Tranquility Base. The Eagle has
|
|
117
|
+
landed. That's one small step for (a) man, one giant leap for
|
|
118
|
+
mankind.
|
|
119
|
+
|
|
120
|
+
Here's the PDF of $$link["Ruby for the Old-Time C Programmer"|http://rubyhacker.com/blog2/rubydino.pdf]
|
|
121
|
+
|
|
122
|
+
Pity this busy monster, manunkind, not. Pity rather... Listen:
|
|
123
|
+
There's a hell of a universe next door; let's go.
|
|
124
|
+
BODY
|
|
125
|
+
|
|
126
|
+
make_post(x, "The Waller Creek project", <<-EXCERPT, <<-BODY)
|
|
127
|
+
Will it ever be finished?
|
|
128
|
+
EXCERPT
|
|
129
|
+
Blah blah Waller Creek blah blah...
|
|
130
|
+
BODY
|
|
131
|
+
|
|
132
|
+
make_post(x, "Life on Sabine Street", <<-EXCERPT, <<-BODY)
|
|
133
|
+
It's like Pooh Corner, except not.
|
|
134
|
+
EXCERPT
|
|
135
|
+
This is about Sabine St, blah blah lorem ipsum dolor...
|
|
136
|
+
BODY
|
|
137
|
+
|
|
138
|
+
make_post(x, "Remember Modest Mouse?", <<-EXCERPT, <<-BODY)
|
|
139
|
+
They date to the 90s or before.
|
|
140
|
+
EXCERPT
|
|
141
|
+
But I first heard of them
|
|
142
|
+
in 2005.
|
|
143
|
+
BODY
|
|
144
|
+
|
|
145
|
+
debug
|
|
146
|
+
debug "** generate_index #{bold("around_austin")}"
|
|
147
|
+
x.generate_index("around_austin")
|
|
148
|
+
|
|
149
|
+
debug("** generate_view: #{bold('around_austin')}")
|
|
150
|
+
x.generate_view("around_austin")
|
|
151
|
+
|
|
152
|
+
debug bold("...finished.\n")
|
|
153
|
+
|
|
154
|
+
t1 = Time.now
|
|
155
|
+
|
|
156
|
+
elapsed = t1 - t0
|
|
157
|
+
puts "Elapsed: #{'%3.2f' % elapsed} secs\n "
|
|
158
|
+
|
data/test/fakeimage.jpg
ADDED
|
Binary file
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
$LOAD_PATH << "."
|
|
2
|
+
# require "test_helper"
|
|
3
|
+
|
|
4
|
+
require "minitest/autorun"
|
|
5
|
+
# require "minitest/fail_fast"
|
|
6
|
+
|
|
7
|
+
require 'runeblog'
|
|
8
|
+
require 'lib/repl'
|
|
9
|
+
require 'rubytext'
|
|
10
|
+
|
|
11
|
+
major, minor = RUBY_VERSION.split(".").values_at(0,1)
|
|
12
|
+
ver = major.to_i*10 + minor.to_i
|
|
13
|
+
abort "Need Ruby 2.4 or greater" unless ver >= 24
|
|
14
|
+
|
|
15
|
+
RubyText.start
|
|
16
|
+
|
|
17
|
+
class TestREPL < Minitest::Test
|
|
18
|
+
include RuneBlog::REPL
|
|
19
|
+
|
|
20
|
+
def show_lines(text)
|
|
21
|
+
lines = text.split("\n")
|
|
22
|
+
str = "#{lines.size} lines\n"
|
|
23
|
+
lines.each {|line| str << " #{line.inspect}\n" }
|
|
24
|
+
str
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def setup
|
|
28
|
+
# To be strictly correct in testing (though slower),
|
|
29
|
+
# run make_blog here.
|
|
30
|
+
system("ruby test/make_blog.rb") if ARGV.first == "new"
|
|
31
|
+
@blog = RuneBlog.new
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Note: "Bang" methods depend on the data subtree
|
|
35
|
+
|
|
36
|
+
def test_001_cmd_help
|
|
37
|
+
# puts __method__
|
|
38
|
+
out = cmd_help(nil, true)
|
|
39
|
+
assert out.is_a?(String), "Expected a string returned"
|
|
40
|
+
lines = out.split("\n").length
|
|
41
|
+
assert lines > 15, "Expecting lengthy help message"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_002_cmd_version
|
|
45
|
+
# puts __method__
|
|
46
|
+
out = cmd_version(nil, true)
|
|
47
|
+
assert out.is_a?(String), "Expected a string returned"
|
|
48
|
+
lines = out
|
|
49
|
+
assert lines =~ /\d+\.\d+\.\d+/m,
|
|
50
|
+
"Couldn't find version number; found #{out.inspect}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_003_list_views!
|
|
54
|
+
# puts __method__
|
|
55
|
+
out = cmd_list_views(nil, true)
|
|
56
|
+
assert out.is_a?(String), "Expected a string returned"
|
|
57
|
+
lines = out.split("\n").length
|
|
58
|
+
assert lines >= 2, "Expecting at least 2 lines"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_004_change_view!
|
|
62
|
+
# puts __method__
|
|
63
|
+
out = cmd_change_view(nil, true) # no param, but testing
|
|
64
|
+
assert out.is_a?(String), "Expected a string; got: #{out.inspect}"
|
|
65
|
+
assert out =~ /alpha_view/m, "Expecting 'alpha_view' as default; got: #{out.inspect}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_005_lsd!
|
|
69
|
+
# puts __method__
|
|
70
|
+
out = cmd_list_drafts(nil, true)
|
|
71
|
+
assert out.is_a?(String), "Expected a string returned"
|
|
72
|
+
nlines = out.split("\n").length
|
|
73
|
+
exp = 10
|
|
74
|
+
assert nlines == exp, "Expecting #{exp} lines, got #{nlines}; #{show_lines(out)}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_006_lsp!
|
|
78
|
+
# puts __method__
|
|
79
|
+
out = cmd_list_posts(nil, true)
|
|
80
|
+
assert out.is_a?(String), "Expected a string returned; got: #{out.inspect}"
|
|
81
|
+
lines = out.split("\n").length
|
|
82
|
+
assert lines == 6, "Expecting 6 lines; got #{lines.size}; #{show_lines(out)}"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_007_parser
|
|
86
|
+
# puts __method__
|
|
87
|
+
parse_tests = {
|
|
88
|
+
# Loading/trailing blanks as well
|
|
89
|
+
"kill 81 82 83" => [:cmd_kill, "81 82 83"],
|
|
90
|
+
" kill 81 82 83" => [:cmd_kill, "81 82 83"],
|
|
91
|
+
"kill 81 82 83 " => [:cmd_kill, "81 82 83"],
|
|
92
|
+
" kill 81 82 83 " => [:cmd_kill, "81 82 83"],
|
|
93
|
+
"help" => [:cmd_help, nil],
|
|
94
|
+
"h" => [:cmd_help, nil],
|
|
95
|
+
"version" => [:cmd_version, nil],
|
|
96
|
+
"v" => [:cmd_version, nil],
|
|
97
|
+
"list views" => [:cmd_list_views, nil],
|
|
98
|
+
"lsv" => [:cmd_list_views, nil],
|
|
99
|
+
"new view foobar" => [:cmd_new_view, "foobar"],
|
|
100
|
+
"new post" => [:cmd_new_post, nil],
|
|
101
|
+
"p" => [:cmd_new_post, nil],
|
|
102
|
+
"post" => [:cmd_new_post, nil],
|
|
103
|
+
"change view beta_view" => [:cmd_change_view, "beta_view"],
|
|
104
|
+
"cv" => [:cmd_change_view, nil], # 0-arity
|
|
105
|
+
"cv myview" => [:cmd_change_view, "myview"],
|
|
106
|
+
"list posts" => [:cmd_list_posts, nil],
|
|
107
|
+
"lsp" => [:cmd_list_posts, nil],
|
|
108
|
+
"list drafts" => [:cmd_list_drafts, nil],
|
|
109
|
+
"lsd" => [:cmd_list_drafts, nil],
|
|
110
|
+
"rm 999" => [:cmd_remove_post, "999"],
|
|
111
|
+
"kill 101 102 103" => [:cmd_kill, "101 102 103"],
|
|
112
|
+
"edit 104" => [:cmd_edit_post, "104"],
|
|
113
|
+
"ed 105" => [:cmd_edit_post, "105"],
|
|
114
|
+
"e 106" => [:cmd_edit_post, "106"],
|
|
115
|
+
"preview" => [:cmd_preview, nil],
|
|
116
|
+
"browse" => [:cmd_browse, nil],
|
|
117
|
+
"relink" => [:cmd_relink, nil],
|
|
118
|
+
"rebuild" => [:cmd_rebuild, nil],
|
|
119
|
+
"publish" => [:cmd_publish, nil],
|
|
120
|
+
"q" => [:cmd_quit, nil],
|
|
121
|
+
"quit" => [:cmd_quit, nil]
|
|
122
|
+
# Later: too many/few params
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
parse_tests.each_pair do |cmd, expected|
|
|
126
|
+
result = RuneBlog::REPL.choose_method(cmd)
|
|
127
|
+
assert result == expected, "Expected #{expected.inspect} but got #{result.inspect}"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def test_008_current_view!
|
|
132
|
+
# puts __method__
|
|
133
|
+
assert @blog.view.to_s == "alpha_view", "Current view wrong (#{@blog.view}, not alpha_view)"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def test_009_change_view!
|
|
137
|
+
# puts __method__
|
|
138
|
+
assert @blog.change_view("beta_view")
|
|
139
|
+
assert @blog.view.to_s == "beta_view", "Current view wrong (#{@blog.view}, not beta_view)"
|
|
140
|
+
assert @blog.change_view("alpha_view")
|
|
141
|
+
assert @blog.view.to_s == "alpha_view", "Current view wrong (#{@blog.view}, not alpha_view)"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def test_010_accessors!
|
|
145
|
+
# puts __method__
|
|
146
|
+
sorted_views = @blog.views.map(&:to_s).sort
|
|
147
|
+
assert sorted_views == ["alpha_view", "beta_view", "gamma_view", "test_view"],
|
|
148
|
+
"Got: #{sorted_views.inspect}"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def test_011_create_delete_view!
|
|
152
|
+
# puts __method__
|
|
153
|
+
@blog.create_view("anotherview")
|
|
154
|
+
sorted_views = @blog.views.map(&:to_s).sort
|
|
155
|
+
assert sorted_views == ["alpha_view", "anotherview", "beta_view", "gamma_view", "test_view"],
|
|
156
|
+
"After create: #{sorted_views.inspect}"
|
|
157
|
+
@blog.delete_view("anotherview", true)
|
|
158
|
+
sorted_views = @blog.views.map(&:to_s).sort
|
|
159
|
+
assert sorted_views == ["alpha_view", "beta_view", "gamma_view", "test_view"],
|
|
160
|
+
"After delete: #{sorted_views.inspect}"
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def test_012_create_remove_post!
|
|
164
|
+
# puts __method__
|
|
165
|
+
@blog.change_view("beta_view")
|
|
166
|
+
assert @blog.view.to_s == "beta_view", "Expected beta_view"
|
|
167
|
+
nposts = @blog.posts.size
|
|
168
|
+
ndrafts = @blog.drafts.size
|
|
169
|
+
title = "Uninteresting title"
|
|
170
|
+
num = @blog.create_new_post(title, true)
|
|
171
|
+
|
|
172
|
+
assert @blog.posts.size == nposts + 1, "Don't see new post"
|
|
173
|
+
@blog.remove_post(num)
|
|
174
|
+
assert @blog.posts.size == nposts, "Failed to delete post"
|
|
175
|
+
|
|
176
|
+
assert @blog.drafts.size == ndrafts + 1, "Don't see new draft"
|
|
177
|
+
@blog.delete_draft(num)
|
|
178
|
+
assert @blog.drafts.size == ndrafts, "Failed to delete draft"
|
|
179
|
+
@blog.change_view("alpha_view")
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def xtest_013_slug_tests
|
|
183
|
+
hash = { "abcxyz" => "abcxyz", # 0-based
|
|
184
|
+
"abc'xyz" => "abcxyz",
|
|
185
|
+
'abc"xyz' => "abcxyz",
|
|
186
|
+
'7%sol' => "7sol",
|
|
187
|
+
"only a test" => "only-a-test",
|
|
188
|
+
"abc xyz" => "abc--xyz", # change this behavior?
|
|
189
|
+
"ABCxyZ" => "abcxyz",
|
|
190
|
+
}
|
|
191
|
+
hash.each_pair.with_index do |keys, i|
|
|
192
|
+
real, fixed = *keys
|
|
193
|
+
meta = OpenStruct.new
|
|
194
|
+
meta.title = real
|
|
195
|
+
meta.num = 99
|
|
196
|
+
result = @blog.make_slug(meta)[5..-1] # Skip num (test_013...)
|
|
197
|
+
assert result == fixed, "Case #{i}: expected: #{fixed.inspect}, got #{result.inspect}"
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def xtest_014_remove_nonexistent_post!
|
|
202
|
+
@blog.change_view("alpha_view")
|
|
203
|
+
out = cmd_remove_post(99, true)
|
|
204
|
+
assert out =~ /Post 99 not found/, "Expected error about nonexistent post, got: #{out}"
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def xtest_015_kill_multiple_posts!
|
|
208
|
+
@blog.change_view("alpha_view")
|
|
209
|
+
out = cmd_list_posts(nil, true)
|
|
210
|
+
before = out.split("\n").length
|
|
211
|
+
cmd_kill("1 2 7", true)
|
|
212
|
+
out = cmd_list_posts(nil, true)
|
|
213
|
+
after = out.split("\n").length
|
|
214
|
+
expecting = before - 3
|
|
215
|
+
assert after == expecting, "list_posts saw #{before} posts, now #{after} (not #{expecting})"
|
|
216
|
+
@blog.undelete_post(1)
|
|
217
|
+
@blog.undelete_post(2)
|
|
218
|
+
@blog.undelete_post(7)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
if File.exist?("testing.publish") # FIXME!!!
|
|
222
|
+
|
|
223
|
+
def xtest_016_can_publish
|
|
224
|
+
# puts __method__
|
|
225
|
+
x = OpenStruct.new
|
|
226
|
+
x.user, x.server, x.docroot, x.docroot, x.path, x.proto =
|
|
227
|
+
"root", "rubyhacker.com", "/var/www", "whatever", "http"
|
|
228
|
+
dep = RuneBlog::Publishing.new(x)
|
|
229
|
+
result = dep.remote_login?
|
|
230
|
+
assert result == true, "Valid login doesn't work"
|
|
231
|
+
result = dep.remote_permissions?
|
|
232
|
+
assert result == true, "Valid mkdir doesn't work"
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def xtest_017_cannot_publish_wrong_user
|
|
236
|
+
# puts __method__
|
|
237
|
+
x = OpenStruct.new
|
|
238
|
+
x.user, x.server, x.docroot, x.docroot, x.path, x.proto =
|
|
239
|
+
"bad_user", "rubyhacker.com", "/var/www", "whatever", "http"
|
|
240
|
+
dep = RuneBlog::Publishing.new(x)
|
|
241
|
+
result = dep.remote_login?
|
|
242
|
+
assert result.nil?, "Expected to detect login error (bad user)"
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def xtest_018_cannot_publish_bad_server
|
|
246
|
+
# puts __method__
|
|
247
|
+
x = OpenStruct.new
|
|
248
|
+
x.user, x.server, x.docroot, x.docroot, x.path, x.proto =
|
|
249
|
+
"root", "nonexistent123.com", "/var/www", "whatever", "http"
|
|
250
|
+
dep = RuneBlog::Publishing.new(x)
|
|
251
|
+
result = dep.remote_login?
|
|
252
|
+
assert result.nil?, "Expected to detect login error (bad server)"
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
end # conditional tests
|
|
256
|
+
|
|
257
|
+
def xtest_019_exception_existing_blog
|
|
258
|
+
# puts __method__
|
|
259
|
+
assert_raises(BlogAlreadyExists) { RuneBlog.create_new_blog_repo }
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def xtest_020_exception_missing_blog_accessor
|
|
263
|
+
# puts __method__
|
|
264
|
+
save = RuneBlog.blog
|
|
265
|
+
RuneBlog.blog = nil
|
|
266
|
+
assert_raises(NoBlogAccessor) { RuneBlog::Post.load(1) }
|
|
267
|
+
RuneBlog.blog = save
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def xtest_021_exception_cant_assign_view
|
|
271
|
+
# puts __method__
|
|
272
|
+
assert_raises(CantAssignView) { @blog.view = 99 }
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def xtest_022_exception_no_such_view
|
|
276
|
+
# puts __method__
|
|
277
|
+
assert_raises(NoSuchView) { @blog.view = 'not_a_view_name' }
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def xtest_023_exception_view_already_exists
|
|
281
|
+
# puts __method__
|
|
282
|
+
assert_raises(ViewAlreadyExists) { @blog.create_view('alpha_view') }
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def xtest_024_exception_livetext_error # FIXME Doesn't work! Change Livetext
|
|
286
|
+
# puts __method__
|
|
287
|
+
testfile = "testfile.lt3"
|
|
288
|
+
path = @blog.root + "/drafts/" + testfile
|
|
289
|
+
cmd = "echo .no_such_command > #{path}"
|
|
290
|
+
system(cmd)
|
|
291
|
+
# system("ls -l #{path}")
|
|
292
|
+
save = STDERR
|
|
293
|
+
STDERR.reopen("/dev/null")
|
|
294
|
+
assert_raises(LivetextError) { @blog.process_post(testfile) }
|
|
295
|
+
STDERR.reopen(save)
|
|
296
|
+
File.rm(path)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# later tests...
|
|
300
|
+
# new view asks for publishing info and writes it
|
|
301
|
+
# (how to mimic user input? test some other way?)
|
|
302
|
+
|
|
303
|
+
end
|
|
304
|
+
|