runeblog 0.3.02

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +7 -0
  2. data/README.lt3 +279 -0
  3. data/README.md +312 -0
  4. data/bin/blog +200 -0
  5. data/bin/mkwidget +164 -0
  6. data/data/EDITOR +1 -0
  7. data/data/ROOT +1 -0
  8. data/data/VIEW +1 -0
  9. data/data/features.txt +18 -0
  10. data/data/global.lt3 +20 -0
  11. data/data/universal.lt3 +18 -0
  12. data/empty_view/assets/austin-pano.jpg +0 -0
  13. data/empty_view/assets/sky2.jpg +0 -0
  14. data/empty_view/config/exper/2svg.lt3 +38 -0
  15. data/empty_view/config/exper/gen_svg.rb +60 -0
  16. data/empty_view/config/exper/meta.html +10 -0
  17. data/empty_view/config/exper/s2.html +25 -0
  18. data/empty_view/config/exper/varmint.rb +50 -0
  19. data/empty_view/config/facebook/credentials.txt +7 -0
  20. data/empty_view/config/facebook/facebook.rb +42 -0
  21. data/empty_view/config/facebook/fb.html +10 -0
  22. data/empty_view/config/facebook/fb.js.lt3 +15 -0
  23. data/empty_view/config/reddit/credentials.txt +6 -0
  24. data/empty_view/config/reddit/notes.txt +4 -0
  25. data/empty_view/config/reddit/reddit_post_url.py +34 -0
  26. data/empty_view/config/reddit/redpost.rb +43 -0
  27. data/empty_view/config/reddit/the-graffiti-wall.html +91 -0
  28. data/empty_view/config/twitter/credentials.txt +3 -0
  29. data/empty_view/config/twitter/tw.html +12 -0
  30. data/empty_view/config/twitter/tw.js +5 -0
  31. data/empty_view/config/twitter/twitter.rb +35 -0
  32. data/empty_view/posts/GIT_IS_DUMB +1 -0
  33. data/empty_view/remote/assets/GIT_IS_DUMB +1 -0
  34. data/empty_view/remote/banner/navbar/GIT_IS_DUMB +0 -0
  35. data/empty_view/remote/etc/GIT_IS_DUMB +1 -0
  36. data/empty_view/remote/permalink/GIT_IS_DUMB +1 -0
  37. data/empty_view/remote/widgets/ad/GIT_IS_DUMB +2 -0
  38. data/empty_view/remote/widgets/links/GIT_IS_DUMB +2 -0
  39. data/empty_view/remote/widgets/news/GIT_IS_DUMB +2 -0
  40. data/empty_view/remote/widgets/pages/GIT_IS_DUMB +2 -0
  41. data/empty_view/remote/widgets/pinned/GIT_IS_DUMB +2 -0
  42. data/empty_view/settings/features.txt +18 -0
  43. data/empty_view/settings/publish.txt +5 -0
  44. data/empty_view/settings/recent.txt +6 -0
  45. data/empty_view/settings/view.txt +4 -0
  46. data/empty_view/themes/standard/README +59 -0
  47. data/empty_view/themes/standard/banner/banner.lt3 +5 -0
  48. data/empty_view/themes/standard/banner/navbar/about.lt3 +18 -0
  49. data/empty_view/themes/standard/banner/navbar/contact.lt3 +18 -0
  50. data/empty_view/themes/standard/banner/navbar/faq.lt3 +1 -0
  51. data/empty_view/themes/standard/banner/navbar/list.data +3 -0
  52. data/empty_view/themes/standard/banner/top.lt3 +20 -0
  53. data/empty_view/themes/standard/blog/generate.lt3 +21 -0
  54. data/empty_view/themes/standard/blog/head.lt3 +16 -0
  55. data/empty_view/themes/standard/blog/index.lt3 +17 -0
  56. data/empty_view/themes/standard/blog/post_entry.lt3 +21 -0
  57. data/empty_view/themes/standard/etc/blog.css.lt3 +62 -0
  58. data/empty_view/themes/standard/etc/externals.lt3 +24 -0
  59. data/empty_view/themes/standard/etc/favicon.ico +0 -0
  60. data/empty_view/themes/standard/etc/misc.js +20 -0
  61. data/empty_view/themes/standard/post/generate.lt3 +38 -0
  62. data/empty_view/themes/standard/post/head.lt3 +7 -0
  63. data/empty_view/themes/standard/post/index.lt3 +24 -0
  64. data/empty_view/themes/standard/post/permalink.lt3 +32 -0
  65. data/empty_view/themes/standard/widgets/README +4 -0
  66. data/empty_view/themes/standard/widgets/ad/ad.lt3 +22 -0
  67. data/empty_view/themes/standard/widgets/ad/ad1.png +0 -0
  68. data/empty_view/themes/standard/widgets/ad/ad2.png +0 -0
  69. data/empty_view/themes/standard/widgets/ad/ad3.png +0 -0
  70. data/empty_view/themes/standard/widgets/ad/ad4.png +0 -0
  71. data/empty_view/themes/standard/widgets/bydates/README +2 -0
  72. data/empty_view/themes/standard/widgets/bydates/bydates.rb +18 -0
  73. data/empty_view/themes/standard/widgets/bydates/card.css +1 -0
  74. data/empty_view/themes/standard/widgets/bydates/custom.rb +1 -0
  75. data/empty_view/themes/standard/widgets/bydates/main.css +2 -0
  76. data/empty_view/themes/standard/widgets/links/README +2 -0
  77. data/empty_view/themes/standard/widgets/links/card.css +1 -0
  78. data/empty_view/themes/standard/widgets/links/custom.rb +1 -0
  79. data/empty_view/themes/standard/widgets/links/links.rb +90 -0
  80. data/empty_view/themes/standard/widgets/links/list.data +3 -0
  81. data/empty_view/themes/standard/widgets/links/main.css +2 -0
  82. data/empty_view/themes/standard/widgets/news/README +2 -0
  83. data/empty_view/themes/standard/widgets/news/card.css +1 -0
  84. data/empty_view/themes/standard/widgets/news/custom.rb +1 -0
  85. data/empty_view/themes/standard/widgets/news/list.data +4 -0
  86. data/empty_view/themes/standard/widgets/news/main.css +2 -0
  87. data/empty_view/themes/standard/widgets/news/news.rb +88 -0
  88. data/empty_view/themes/standard/widgets/pages/README +2 -0
  89. data/empty_view/themes/standard/widgets/pages/card.css +1 -0
  90. data/empty_view/themes/standard/widgets/pages/custom.rb +1 -0
  91. data/empty_view/themes/standard/widgets/pages/disclaim.lt3 +10 -0
  92. data/empty_view/themes/standard/widgets/pages/faq.lt3 +40 -0
  93. data/empty_view/themes/standard/widgets/pages/like-dislike.lt3 +11 -0
  94. data/empty_view/themes/standard/widgets/pages/list.data +4 -0
  95. data/empty_view/themes/standard/widgets/pages/local.rb +0 -0
  96. data/empty_view/themes/standard/widgets/pages/main.css +2 -0
  97. data/empty_view/themes/standard/widgets/pages/other-stuff.lt3 +10 -0
  98. data/empty_view/themes/standard/widgets/pages/pages.rb +95 -0
  99. data/empty_view/themes/standard/widgets/pinned/README +2 -0
  100. data/empty_view/themes/standard/widgets/pinned/card.css +1 -0
  101. data/empty_view/themes/standard/widgets/pinned/custom.rb +1 -0
  102. data/empty_view/themes/standard/widgets/pinned/main.css +2 -0
  103. data/empty_view/themes/standard/widgets/pinned/pinned.rb +99 -0
  104. data/empty_view/themes/standard/widgets/search/README +2 -0
  105. data/empty_view/themes/standard/widgets/search/card.css +1 -0
  106. data/empty_view/themes/standard/widgets/search/custom.rb +1 -0
  107. data/empty_view/themes/standard/widgets/search/main.css +2 -0
  108. data/empty_view/themes/standard/widgets/search/search.rb +18 -0
  109. data/empty_view/themes/standard/widgets/sitemap/README +2 -0
  110. data/empty_view/themes/standard/widgets/sitemap/card.css +1 -0
  111. data/empty_view/themes/standard/widgets/sitemap/custom.rb +1 -0
  112. data/empty_view/themes/standard/widgets/sitemap/main.css +2 -0
  113. data/empty_view/themes/standard/widgets/sitemap/sitemap.rb +18 -0
  114. data/empty_view/themes/standard/widgets/tag-cloud/OLD-example.lt3 +12 -0
  115. data/empty_view/themes/standard/widgets/tag-cloud/README +2 -0
  116. data/empty_view/themes/standard/widgets/tag-cloud/card.css +1 -0
  117. data/empty_view/themes/standard/widgets/tag-cloud/custom.rb +1 -0
  118. data/empty_view/themes/standard/widgets/tag-cloud/main.css +2 -0
  119. data/empty_view/themes/standard/widgets/tag-cloud/tag-cloud.lt3 +3 -0
  120. data/empty_view/themes/standard/widgets/tag-cloud/tag-cloud.rb +18 -0
  121. data/lib/Javascript.stuff +69 -0
  122. data/lib/helpers-blog.rb +155 -0
  123. data/lib/helpers-repl.rb +201 -0
  124. data/lib/liveblog.rb +825 -0
  125. data/lib/logging.rb +44 -0
  126. data/lib/lowlevel.rb +73 -0
  127. data/lib/pathmagic.rb +14 -0
  128. data/lib/post.rb +211 -0
  129. data/lib/processing.rb +60 -0
  130. data/lib/publish.rb +73 -0
  131. data/lib/repl.rb +597 -0
  132. data/lib/runeblog.rb +773 -0
  133. data/lib/runeblog_version.rb +50 -0
  134. data/lib/view.rb +69 -0
  135. data/runeblog.gemspec +42 -0
  136. data/test/austin.rb +158 -0
  137. data/test/fakeimage.jpg +0 -0
  138. data/test/general_test.rb +304 -0
  139. data/test/make_blog.rb +196 -0
  140. data/test/test +3 -0
  141. metadata +242 -0
@@ -0,0 +1,44 @@
1
+ unless self.respond_to?("log!")
2
+ $logging = true
3
+ $log = File.new("/tmp/runeblog.log","w")
4
+
5
+ def outlog(str = "", stderr: false)
6
+ $log.puts str
7
+ STDERR.puts str if stderr
8
+ end
9
+
10
+ def log!(str: "", enter: nil, args: [], pwd: false, dir: false, level: 0, stderr: false)
11
+ return unless $logging
12
+ @err_level ||= ENV['RUNEBLOG_ERROR_LEVEL']
13
+ @err_level ||= 0
14
+ return if level < @err_level
15
+
16
+ time = Time.now.strftime("%H:%M:%S")
17
+
18
+ meth = ""
19
+ meth = "#{enter}" if enter
20
+
21
+ para = "(#{args.inspect[1..-2]})"
22
+
23
+ source = caller[0].sub(/.*\//, " in ").sub(/:/, " line ").sub(/:.*/, "")
24
+ source = "in #{source} (probably liveblog.rb)" if source.include? "(eval)"
25
+
26
+ str = " ... #{str}" unless str.empty?
27
+ indent = " "*12
28
+
29
+ outlog "#{time} #{meth}#{para}"
30
+ outlog "#{indent} #{str} " unless str.empty?
31
+ outlog "#{indent} #{source}"
32
+ outlog "#{indent} pwd = #{Dir.pwd} " if pwd
33
+ if dir
34
+ files = (Dir.entries('.') - %w[. ..]).join(" ")
35
+ outlog "#{indent} dir/* = #{files}"
36
+ end
37
+ # outlog "#{indent} livetext params = #{livedata.inpect} " unless livedata.nil?
38
+ outlog
39
+ $log.close
40
+ $log = File.new("/tmp/runeblog.log","a")
41
+ end
42
+
43
+ end
44
+
@@ -0,0 +1,73 @@
1
+
2
+ def dump(obj, name)
3
+ File.write(name, obj)
4
+ end
5
+
6
+ def system!(str, show: false)
7
+ log!(enter: __method__, args: [str], level: 2)
8
+ STDERR.puts str if show
9
+ rc = system(str)
10
+ return rc if rc
11
+ STDERR.puts "FAILED: #{str.inspect}"
12
+ STDERR.puts "\ncaller = \n#{caller.join("\n ")}\n"
13
+ if defined?(RubyText)
14
+ sleep 6
15
+ RubyText.stop
16
+ exit
17
+ end
18
+ return rc
19
+ end
20
+
21
+ def _get_data?(file) # File need not exist
22
+ if File.exist?(file)
23
+ _get_data(file)
24
+ else
25
+ []
26
+ end
27
+ end
28
+
29
+ def _get_data(file)
30
+ lines = File.readlines(file)
31
+ lines.reject! {|line| line[0] == "-" } # allow rejection of lines
32
+ lines = lines.map do |line|
33
+ line.sub(/ *# .*$/, "") # allow trailing comments
34
+ end
35
+ lines
36
+ end
37
+
38
+ def copy(src, dst)
39
+ log!(enter: __method__, args: [src, dst], level: 2)
40
+ cmd = "cp #{src} #{dst} 2>/dev/null"
41
+ system!(cmd)
42
+ end
43
+
44
+ def copy!(src, dst)
45
+ log!(enter: __method__, args: [src, dst], level: 2)
46
+ cmd = "cp -r #{src} #{dst} 2>/dev/null"
47
+ system!(cmd)
48
+ end
49
+
50
+ def create_dirs(*dirs)
51
+ log!(enter: __method__, args: [*dirs], level: 3)
52
+ dirs.each do |dir|
53
+ dir = dir.to_s # symbols allowed
54
+ next if Dir.exist?(dir)
55
+ cmd = "mkdir -p #{dir} >/dev/null"
56
+ result = system!(cmd)
57
+ raise CantCreateDir(dir) unless result
58
+ end
59
+ end
60
+
61
+ def interpolate(str, bind)
62
+ log!(enter: __method__, args: [str, bind], level: 3)
63
+ wrap = "<<-EOS\n#{str}\nEOS"
64
+ eval wrap, bind
65
+ end
66
+
67
+ def error(err)
68
+ log!(str: err, enter: __method__, args: [err], level: 2)
69
+ str = "\n Error: #{err}"
70
+ puts str
71
+ puts err.backtrace.join("\n")
72
+ end
73
+
@@ -0,0 +1,14 @@
1
+ module PathSep
2
+ def /(right)
3
+ s1 = self.to_s.dup
4
+ s2 = right.to_s.dup
5
+ s1 << "/" unless s1.end_with?("/") || s2.start_with?("/")
6
+ path = s1 + s2
7
+ path.gsub!("//", "/")
8
+ path
9
+ end
10
+ end
11
+
12
+ String.include(PathSep)
13
+ Symbol.include(PathSep)
14
+
@@ -0,0 +1,211 @@
1
+ require 'runeblog'
2
+ require 'pathmagic'
3
+
4
+ class RuneBlog::Post
5
+
6
+ attr_reader :num, :title, :date, :views, :num, :slug
7
+ attr_accessor :meta, :blog, :draft
8
+
9
+ include RuneBlog::Helpers
10
+
11
+
12
+ def self.load(post)
13
+ log!(enter: __method__, args: [post], level: 3)
14
+ raise "Doesn't work right now"
15
+ raise NoBlogAccessor if RuneBlog.blog.nil?
16
+ # "post" is a slug
17
+ pdir = RuneBlog.blog.root/:drafts/post
18
+ meta = nil
19
+ Dir.chdir(pdir) do
20
+ meta = read_config("metadata.txt")
21
+ meta.date = Date.parse(meta.date)
22
+ meta.views = meta.views.split
23
+ meta.tags = meta.tags.split
24
+ meta.teaser = File.read("teaser.txt")
25
+ # meta.body = File.read("body.txt")
26
+ end
27
+ meta
28
+ end
29
+
30
+ def write_metadata(meta) # FIXME ???
31
+ log!(enter: __method__, args: [meta], level: 3)
32
+ debug "=== write_metadata:"
33
+ debug "-----\n#{meta.inspect}\n-----"
34
+ fname2 = "metadata.txt"
35
+ hash = meta.to_h
36
+
37
+ File.write("teaser.txt", hash[:teaser])
38
+ hash.delete(:teaser)
39
+ hash.delete(:body)
40
+
41
+ hash[:views] = hash[:views].join(" ")
42
+ hash[:tags] = hash[:tags].join(" ")
43
+
44
+ fields = [:num, :title, :date, :pubdate, :views, :tags]
45
+
46
+ f2 = File.new(fname2, "w")
47
+ fields.each {|fld| f2.puts "#{fld}: #{hash[fld]}" }
48
+ f2.close
49
+ end
50
+
51
+ def initialize
52
+ log!(enter: __method__, level: 3)
53
+ @blog = RuneBlog.blog || raise(NoBlogAccessor)
54
+ @meta = OpenStruct.new
55
+ end
56
+
57
+ def self.create(title:, teaser:, body:, pubdate: Time.now.strftime("%Y-%m-%d"),
58
+ views:[], file: nil)
59
+ log!(enter: __method__, args: [title, teaser, body, pubdate, views], stderr: true)
60
+ post = self.new
61
+ # NOTE: This is the ONLY place next_sequence is called!
62
+ num = post.meta.num = post.blog.next_sequence
63
+
64
+ # new_metadata
65
+ post.meta.title, post.meta.teaser, post.meta.body, post.meta.pubdate =
66
+ title, teaser, body, pubdate
67
+ post.meta.views = [post.blog.view.to_s] + views
68
+ post.meta.tags = []
69
+ post.blog.make_slug(post.meta) # adds to meta
70
+
71
+ # create_draft
72
+ viewhome = post.blog.view.publisher.url
73
+ meta = post.meta
74
+ if file.nil?
75
+ text = RuneBlog.post_template(num: meta.num, title: meta.title, date: meta.pubdate,
76
+ view: meta.view, teaser: meta.teaser, body: meta.body,
77
+ views: meta.views, tags: meta.tags, home: viewhome)
78
+ srcdir = post.blog.root/:drafts + "/"
79
+ vpdir = post.blog.root/:drafts + "/"
80
+ fname = meta.slug + ".lt3"
81
+ post.draft = srcdir + fname
82
+ dump(text, post.draft)
83
+ else
84
+ dump(File.read(file), post.draft)
85
+ end
86
+ return post
87
+ end
88
+
89
+ def edit
90
+ log!(enter: __method__)
91
+ result = system!("vi #@draft +8") # TODO improve this
92
+ raise EditorProblem(draft) unless result
93
+ nil
94
+ rescue => err
95
+ error(err)
96
+ end
97
+
98
+ def build
99
+ log!(enter: __method__)
100
+ post = self
101
+ views = post.meta.views
102
+ text = File.read(@draft)
103
+ @blog.generate_post(@draft)
104
+ end
105
+ end
106
+
107
+ class RuneBlog::ViewPost
108
+ attr_accessor :nslug, :aslug, :num, :view, :blog
109
+ attr_accessor :path, :title, :date, :teaser_text
110
+
111
+ def self.make(blog:, view:, nslug:)
112
+ raise "No numeric prefix on #{nslug}" unless nslug =~ /^\d{4}-/
113
+ raise "Not expecting an extension" if nslug.end_with?(".lt3") || nslug.end_with?(".html")
114
+ view = view.to_s
115
+ view.define_singleton_method :path do |subdir = ""|
116
+ str = blog.root/:views/view
117
+ str << "/#{subdir}" unless subdir.empty?
118
+ str
119
+ end
120
+ view.define_singleton_method :standard do |subdir = ""|
121
+ str = blog.root/:views/view/:themes/:standard
122
+ str << "/#{subdir}" unless subdir.empty?
123
+ str
124
+ end
125
+ view.define_singleton_method :postdir do |file = ""|
126
+ file = file.to_s
127
+ str = blog.root/:views/view/:posts/nslug
128
+ str = str/file unless file.empty?
129
+ str
130
+ end
131
+ view.define_singleton_method :remote do |dir: "", file: ""|
132
+ subdir = subdir.to_s
133
+ file = file.to_s
134
+ str = blog.root/:views/view/:remote
135
+ str = str/subdir unless subdir.empty?
136
+ str = str/file unless file.empty?
137
+ str
138
+ end
139
+ obj = RuneBlog::ViewPost.new(view, nslug)
140
+ obj.blog = blog
141
+ obj.view = view
142
+ obj.nslug = nslug
143
+ obj.aslug = nslug[5..-1]
144
+ obj.num = nslug[0..3]
145
+ obj
146
+ end
147
+
148
+ def repo(subdir = "")
149
+ subdir = subdir.to_s
150
+ unless subdir.empty?
151
+ raise "Expected 'posts' or 'drafts'" unless %w[posts drafts].include?(subdir)
152
+ end
153
+ str = blog.root
154
+ str = str/subdir unless subdir.empty?
155
+ str
156
+ end
157
+
158
+ alias root repo
159
+
160
+ def slug(num = true, ext = "")
161
+ ext = ext.to_s
162
+ str = ""
163
+ str << @num << "-" if num
164
+ str << @aslug
165
+ str << ext
166
+ str
167
+ end
168
+
169
+ =begin
170
+ aslug this-is-a-post
171
+ aslug_live this-is-a-post.lt3
172
+ aslug_html this-is-a-post.lt3
173
+ nslug 0001-this-is-a-post
174
+
175
+ slug(:num, ext = "")
176
+ =end
177
+
178
+ def initialize(view, postdir)
179
+ log!(enter: __method__, args: [view, postdir], level: 3)
180
+ # Assumes already parsed/processed
181
+ @blog = RuneBlog.blog || raise(NoBlogAccessor)
182
+ @path = postdir.dup
183
+ @nslug = @path.split("/").last
184
+ @aslug = @nslug[5..-1]
185
+ fname = "#{postdir}/teaser.txt" # ???
186
+ @teaser_text = File.read(fname).chomp
187
+ # FIXME dumb hacks...
188
+ mdfile = postdir/"metadata.txt"
189
+ lines = File.readlines(mdfile)
190
+ @title = lines.grep(/title:/).first[7..-1].chomp
191
+ @date = lines.grep(/pubdate:/).first[9..-1].chomp
192
+ # print "-- date = #{@date.inspect} "; gets
193
+ rescue => err
194
+ STDERR.puts "--- #{err}\n #{err.backtrace.join("\n ")}"
195
+ end
196
+
197
+ def get_dirs
198
+ log!(enter: __method__, args: [view, postdir], level: 3)
199
+ fname = File.basename(draft)
200
+ noext = fname.sub(/.lt3$/, "")
201
+ vdir = @root/:views/view
202
+ dir = vdir/:posts/noext + "/"
203
+ Dir.mkdir(dir) unless Dir.exist?(dir)
204
+ system!("cp #{draft} #{dir}")
205
+ viewdir, slugdir, aslug = vdir, dir, noext[5..-1]
206
+ theme = viewdir/:themes/:standard
207
+ [noext, viewdir, slugdir, aslug, theme]
208
+ end
209
+
210
+ end
211
+
@@ -0,0 +1,60 @@
1
+ if ! defined?(LIVE)
2
+
3
+ require 'livetext'
4
+
5
+ LIVE = Livetext.new
6
+ LEXT = ".lt3"
7
+
8
+ def newer?(f1, f2)
9
+ File.mtime(f1) > File.mtime(f2)
10
+ end
11
+
12
+ def stale?(src, dst, deps, force = false)
13
+ meh = File.new("/tmp/dammit-#{src.gsub(/\//, "-")}", "w")
14
+ log!(enter: __method__, args: [src, dst], level: 3)
15
+ raise "Source #{src} not found in #{Dir.pwd}" unless File.exist?(src)
16
+ return true if force
17
+ return true unless File.exist?(dst)
18
+ return true if newer?(src, dst)
19
+ deps.each {|dep| return true if newer?(dep, dst) }
20
+ return false
21
+ end
22
+
23
+ def preprocess(cwd: Dir.pwd, src:,
24
+ dst: nil, strip: false,
25
+ deps: [], copy: nil, debug: false, force: false,
26
+ mix: [], call: [], vars: {})
27
+ src += LEXT unless src.end_with?(LEXT)
28
+ if strip
29
+ dst = File.basename(src).sub(/.lt3$/,"")
30
+ else
31
+ dst += ".html" unless dst.end_with?(".html")
32
+ end
33
+ sp = " "*12
34
+ Dir.chdir(cwd) do
35
+ if debug
36
+ STDERR.puts "#{sp} -- preprocess "
37
+ STDERR.puts "#{sp} src: #{src}"
38
+ STDERR.puts "#{sp} dst: #{dst}"
39
+ STDERR.puts "#{sp} in: #{Dir.pwd}"
40
+ STDERR.puts "#{sp} from: #{caller[0]}"
41
+ STDERR.puts "#{sp} copy: #{copy}" if copy
42
+ end
43
+ stale = stale?(src, dst, deps, force)
44
+ if stale
45
+ live = Livetext.customize(mix: "liveblog", call: call, vars: vars)
46
+ out = live.xform_file(src)
47
+ File.write(dst, out)
48
+ system!("cp #{dst} #{copy}") if copy
49
+ end
50
+ puts "#{sp} -- ^ Already up to date!" if debug && ! stale
51
+ end
52
+ end
53
+
54
+ def get_live_vars(src)
55
+ live = Livetext.customize(call: [".nopara"])
56
+ live.xform_file(src)
57
+ live
58
+ end
59
+
60
+ end
@@ -0,0 +1,73 @@
1
+ if ! defined?(Already_publish)
2
+
3
+ Already_publish = nil
4
+
5
+ require 'pathmagic'
6
+ require 'processing'
7
+
8
+ class RuneBlog::Publishing
9
+ attr_reader :user, :server, :docroot, :path
10
+
11
+ BadRemoteLogin = Exception.new("Can't login remotely")
12
+ BadRemotePerms = Exception.new("Bad remote permissions")
13
+
14
+ def initialize(view)
15
+ log!(enter: __method__, args: [view.to_s])
16
+ @blog = RuneBlog.blog
17
+ dir = @blog.root/:views/view/"themes/standard/"
18
+ gfile = dir/"global.lt3"
19
+ return unless File.exist?(gfile) # FIXME Hackish as hell
20
+
21
+ live = get_live_vars(gfile)
22
+ @user = live.vars["publish.user"]
23
+ @server = live.vars["publish.server"]
24
+ @docroot = live.vars["publish.docroot"]
25
+ @path = live.vars["publish.path"]
26
+ @proto = live.vars["publish.proto"]
27
+ end
28
+
29
+ def to_h
30
+ log!(enter: __method__, level: 3)
31
+ {user: @user, server: @server, docroot: @docroot,
32
+ path: @path, proto: @proto}
33
+ end
34
+
35
+ def url
36
+ log!(enter: __method__, level: 3)
37
+ vname = @blog.view.name # .gsub(/_/, "\\_")
38
+ url = "#@proto://#@server/#@path" # /#{vname}"
39
+ end
40
+
41
+ def publish
42
+ log!(enter: __method__, level: 1)
43
+ dir = @docroot/@path
44
+ view_name = @blog.view.name
45
+ viewpath = dir # /view_name
46
+ # FIXME rsync doesn't work
47
+ cmd = "rsync -r -z #{@blog.root}/views/#{@blog.view}/remote/ #@user@#@server:#{viewpath}/"
48
+ system!(cmd)
49
+ dump("#{@blog.view} at #{Time.now}", "#{@blog.view.dir}/last_published")
50
+ true
51
+ end
52
+
53
+ def remote_login?
54
+ log!(enter: __method__)
55
+ cmd = "ssh -o BatchMode=yes #@user@#@server -x date >/dev/null 2>&1"
56
+ result = system(cmd)
57
+ return nil unless result
58
+ true
59
+ end
60
+
61
+ def remote_permissions?
62
+ log!(enter: __method__)
63
+ dir = @docroot/@path
64
+ temp = @path/"__only_testing"
65
+ try1 = system("ssh -o BatchMode=yes -o ConnectTimeout=1 #@user@#@server -x mkdir -p #{temp} >/dev/null 2>&1")
66
+ return nil unless try1
67
+ try2 = system("ssh -o BatchMode=yes -o ConnectTimeout=1 #@user@#@server -x rmdir #{temp} >/dev/null 2>&1")
68
+ return nil unless try2
69
+ true
70
+ end
71
+ end
72
+
73
+ end