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,597 @@
1
+ require 'runeblog'
2
+ require 'ostruct'
3
+ require 'helpers-repl' # FIXME structure
4
+ require 'pathmagic'
5
+
6
+ make_exception(:PublishError, "Error during publishing")
7
+ make_exception(:EditorProblem, "Could not edit $1")
8
+
9
+ module RuneBlog::REPL
10
+ def edit_file(file, vim: "")
11
+ STDSCR.saveback
12
+ ed = @blog.editor
13
+ params = vim if ed =~ /vim$/
14
+ result = system!("#{@blog.editor} #{file} #{params}")
15
+ raise EditorProblem(file) unless result
16
+ STDSCR.restback
17
+ # cmd_clear(nil)
18
+ end
19
+
20
+ def cmd_quit(arg, testing = false)
21
+ cmd_clear(nil)
22
+ RubyText.stop
23
+ sleep 0.1
24
+
25
+ sleep 0.1
26
+ exit
27
+ end
28
+
29
+ def cmd_clear(arg, testing = false)
30
+ # STDSCR.rows.times { puts " "*(STDSCR.cols-1) }
31
+ STDSCR.clear
32
+ end
33
+
34
+ def cmd_version(arg, testing = false)
35
+ reset_output
36
+ output RuneBlog::VERSION
37
+ puts fx("\n RuneBlog", :bold), fx(" v #{RuneBlog::VERSION}\n", Red) unless testing
38
+ @out
39
+ end
40
+
41
+ def OLD_cmd_config(arg, testing = false)
42
+ hash = {"global.lt3 Global configuration" => "global.lt3",
43
+ "banner/top.lt3 Text portion of banner" => "banner/top.lt3",
44
+ "blog/generate.lt3 Generator for view (usu not edited)" => "blog/generate.lt3",
45
+ ".... head.lt3 HEAD info for view" => "blog/head.lt3",
46
+ ".... banner.lt3 banner description" => "blog/banner.lt3",
47
+ ".... index.lt3 User-edited detail for view" => "blog/index.lt3",
48
+ ".... post_entry.lt3 Generator for post entry in recent-posts" => "blog/post_entry.lt3",
49
+ "etc/blog.css.lt3 Global CSS" => "etc/blog.css.lt3",
50
+ "... externals.lt3 External JS/CSS (Bootstrap, etc.)" => "/etc/externals.lt3",
51
+ "post/generate.lt3 Generator for a post" => "post/generate.lt3",
52
+ ".... head.lt3 HEAD info for post" => "post/head.lt3",
53
+ ".... index.lt3 Content for post" => "post/index.lt3",
54
+ ".... permalink.lt3 Generator for permalink" => "post/permalink.lt3",
55
+ }
56
+
57
+ dir = @blog.view.dir/"themes/standard/"
58
+ num, target = STDSCR.menu(title: "Edit file:", items: hash)
59
+ edit_file(dir/target)
60
+ end
61
+
62
+ def cmd_config(arg, testing = false)
63
+ hash = {"Global configuration" => "global.lt3",
64
+ " View-specific variables" => "../../settings/view.txt",
65
+ " Recent posts" => "../../settings/recent.txt",
66
+ " Publishing vars" => "../../settings/publish.txt",
67
+ "Banner description" => "blog/banner.lt3",
68
+ " Text portion of banner" => "banner/top.lt3",
69
+ "Generator for view (usu not edited)" => "blog/generate.lt3",
70
+ " HEAD info for view" => "blog/head.lt3",
71
+ " User-edited detail for view" => "blog/index.lt3",
72
+ "Generator for post entry in recent-posts" => "blog/post_entry.lt3",
73
+ "Global CSS" => "etc/blog.css.lt3",
74
+ "External JS/CSS (Bootstrap, etc.)" => "/etc/externals.lt3",
75
+ "Generator for a post" => "post/generate.lt3",
76
+ " HEAD info for post" => "post/head.lt3",
77
+ " Content for post" => "post/index.lt3",
78
+ "Generator for permalink" => "post/permalink.lt3",
79
+ }
80
+
81
+ dir = @blog.view.dir/"themes/standard/"
82
+ num, target = STDSCR.menu(title: "Edit file:", items: hash)
83
+ edit_file(dir/target)
84
+ end
85
+
86
+
87
+
88
+ def cmd_manage(arg, testing = false)
89
+ case arg
90
+ when "pages"; _manage_pages(nil, testing = false)
91
+ when "links"; _manage_links(nil, testing = false)
92
+ when "navbar"; _manage_navbar(nil, testing = false)
93
+ # when "pinned"; _manage_pinned(nil, testing = false) # ditch this??
94
+ else
95
+ puts "#{arg} is unknown"
96
+ end
97
+ end
98
+
99
+ def _manage_pinned(arg, testing = false) # cloned from manage_links
100
+ dir = @blog.view.dir/"themes/standard/widgets/pinned"
101
+ data = dir/"list.data"
102
+ edit_file(data)
103
+ end
104
+
105
+ def _manage_navbar(arg, testing = false) # cloned from manage_pages
106
+ dir = @blog.view.dir/"themes/standard/banner/navbar"
107
+ files = Dir.entries(dir) - %w[. .. navbar.lt3]
108
+ main_file = "[ navbar.lt3 ]"
109
+ new_item = " [New item] "
110
+ files = [main_file] + files + [new_item]
111
+ num, fname = STDSCR.menu(title: "Edit navbar:", items: files)
112
+ return if fname.nil?
113
+ case fname
114
+ when new_item
115
+ print "Page title: "
116
+ title = RubyText.gets
117
+ title.chomp!
118
+ print "File name (.lt3): "
119
+ fname = RubyText.gets
120
+ fname << ".lt3" unless fname.end_with?(".lt3")
121
+ new_file = dir/fname
122
+ File.open(new_file, "w") do |f|
123
+ f.puts "<h1>#{title}</h1>\n\n\n "
124
+ f.puts ".backlink"
125
+ end
126
+ edit_file(new_file)
127
+ when main_file
128
+ edit_file(main_file[2..-3])
129
+ else
130
+ edit_file(dir/fname)
131
+ end
132
+ end
133
+
134
+ def _manage_links(arg, testing = false)
135
+ dir = @blog.view.dir/"themes/standard/widgets/links"
136
+ data = dir/"list.data"
137
+ edit_file(data)
138
+ end
139
+
140
+ def _manage_pages(arg, testing = false)
141
+ dir = @blog.view.dir/"themes/standard/widgets/pages"
142
+ # Assume child files already generated (and list.data??)
143
+ data = dir/"list.data"
144
+ lines = _get_data?(data)
145
+ hash = {}
146
+ lines.each do |line|
147
+ url, name = line.chomp.split(",")
148
+ source = url.sub(/.html$/, ".lt3")
149
+ hash[name] = source
150
+ end
151
+ new_item = "[New page]"
152
+ num, fname = STDSCR.menu(title: "Edit page:", items: hash.keys + [new_item])
153
+ return if fname.nil?
154
+ if fname == new_item
155
+ print "Page title: "
156
+ title = RubyText.gets
157
+ title.chomp!
158
+ print "File name (.lt3): "
159
+ fname = RubyText.gets
160
+ fname << ".lt3" unless fname.end_with?(".lt3")
161
+ fhtml = fname.sub(/.lt3$/, ".html")
162
+ File.open(data, "a") {|f| f.puts "#{fhtml},#{title}" }
163
+ new_file = dir/fname
164
+ File.open(new_file, "w") do |f|
165
+ f.puts "<h1>#{title}</h1>\n\n\n "
166
+ f.puts ".backlink"
167
+ end
168
+ edit_file(new_file)
169
+ else
170
+ target = hash[fname]
171
+ edit_file(dir/target)
172
+ end
173
+ end
174
+
175
+ def cmd_import(arg, testing = false)
176
+ files = ask("\n File(s) = ")
177
+ system!("cp #{files} #{@blog.root}/views/#{@blog.view.name}/assets/")
178
+ end
179
+
180
+ def cmd_browse(arg, testing = false)
181
+ reset_output
182
+ url = @blog.view.publisher.url
183
+ if url.nil?
184
+ output! "Publish first."
185
+ puts "\n Publish first."
186
+ return @out
187
+ end
188
+ result = system!("open '#{url}'")
189
+ raise CantOpen(url) unless result
190
+ return @out
191
+ end
192
+
193
+ def cmd_preview(arg, testing = false)
194
+ reset_output
195
+ local = @blog.view.local_index
196
+ unless File.exist?(local)
197
+ puts "\n No index. Rebuilding..."
198
+ cmd_rebuild(nil)
199
+ end
200
+ result = system!("open #{local}")
201
+ raise CantOpen(local) unless result
202
+ @out
203
+ rescue => err
204
+ out = "/tmp/blog#{rand(100)}.txt"
205
+ File.open(out, "w") do |f|
206
+ f.puts err
207
+ f.puts err.backtrace.join("\n")
208
+ end
209
+ puts "Error: See #{out}"
210
+ end
211
+
212
+ def cmd_publish(arg, testing = false)
213
+ # Future Hal says please refactor this
214
+ puts unless testing
215
+ reset_output
216
+ unless @blog.view.can_publish?
217
+ msg = "Can't publish... see global.lt3"
218
+ puts msg unless testing
219
+ output! msg
220
+ return @out
221
+ end
222
+
223
+ ret = RubyText.spinner(label: " Publishing... ") do
224
+ @blog.view.publisher.publish
225
+ end
226
+ return @out unless ret
227
+
228
+ vdir = @blog.view.dir
229
+ dump("fix this later", "#{vdir}/last_published")
230
+ if ! testing || ! ret
231
+ puts " ...finished.\n "
232
+ output! "...finished.\n"
233
+ end
234
+ return @out
235
+ rescue => err
236
+ out = "/tmp/blog#{rand(100)}.txt"
237
+ File.open(out, "w") do |f|
238
+ f.puts err
239
+ f.puts err.backtrace.join("\n")
240
+ end
241
+ puts "Error: See #{out}"
242
+ end
243
+
244
+ def fresh?(src, dst)
245
+ return false unless File.exist?(dst)
246
+ File.mtime(src) <= File.mtime(dst)
247
+ end
248
+
249
+ def regen_posts
250
+ drafts = @blog.drafts # current view
251
+ drafts.each do |draft|
252
+ orig = @blog.root/:drafts/draft
253
+ html = @blog.root/:posts/draft
254
+ html.sub!(/.lt3$/, "/guts.html")
255
+ next if fresh?(orig, html)
256
+ puts " Regenerating #{draft}"
257
+ @blog.generate_post(orig) # rebuild post
258
+ end
259
+ puts
260
+ end
261
+
262
+ def cmd_rebuild(arg, testing = false)
263
+ debug "Starting cmd_rebuild..."
264
+ reset_output
265
+ puts unless testing
266
+ @blog.generate_view(@blog.view)
267
+ @blog.generate_index(@blog.view)
268
+ regen_posts
269
+ @out
270
+ rescue => err
271
+ out = "/tmp/blog#{rand(100)}.txt"
272
+ File.open(out, "w") do |f|
273
+ f.puts err
274
+ f.puts err.backtrace.join("\n")
275
+ end
276
+ puts "Error: See #{out}"
277
+ end
278
+
279
+ def cmd_change_view(arg, testing = false)
280
+ reset_output
281
+ # Simplify this
282
+ if arg.nil?
283
+ viewnames = @blog.views.map {|x| x.name }
284
+ n = viewnames.find_index(@blog.view.name)
285
+ name = @blog.view.name
286
+ # TODO: Add view description
287
+ k, name = STDSCR.menu(title: "Views", items: viewnames, curr: n) unless testing
288
+ return if name.nil?
289
+ @blog.view = name
290
+ output name + "\n"
291
+ puts "\n ", fx(name, :bold), "\n" unless testing
292
+ return @out
293
+ else
294
+ if @blog.view?(arg)
295
+ @blog.view = arg
296
+ output "View: " + @blog.view.name.to_s
297
+ puts "\n ", fx(arg, :bold), "\n" unless testing
298
+ end
299
+ end
300
+ return @out
301
+ end
302
+
303
+ def cmd_new_view(arg, testing = false)
304
+ reset_output
305
+ if arg.nil?
306
+ arg = ask(fx("\nFilename: ", :bold))
307
+ puts
308
+ end
309
+ @blog.create_view(arg)
310
+ text = File.read("#{@blog.root}/data/global.lt3")
311
+ File.write("#{@blog.root}/views/#{@blog.view}/themes/standard/global.lt3",
312
+ text.gsub(/VIEW_NAME/, @blog.view.to_s))
313
+ vim_params = '-c ":set hlsearch" -c ":hi Search ctermfg=2 ctermbg=6" +/"\(VIEW_.*\|SITE.*\)"'
314
+ edit_file(@blog.view.dir/"themes/standard/global.lt3", vim: vim_params)
315
+ @blog.change_view(arg)
316
+ @out
317
+ rescue ViewAlreadyExists
318
+ puts 'Blog already exists'
319
+ rescue => err
320
+ out = "/tmp/blog#{rand(100)}.txt"
321
+ File.open(out, "w") do |f|
322
+ f.puts err
323
+ f.puts err.backtrace.join("\n")
324
+ end
325
+ puts "Error: See #{out}"
326
+ end
327
+
328
+ def cmd_new_post(arg, testing = false)
329
+ reset_output
330
+ if @blog.views.empty?
331
+ puts "\n Create a view before creating the first post!\n "
332
+ return
333
+ end
334
+ title = ask("\nTitle: ")
335
+ puts
336
+ @blog.create_new_post(title)
337
+ # STDSCR.clear
338
+ @out
339
+ rescue => err
340
+ out = "/tmp/blog#{rand(100)}.txt"
341
+ File.open(out, "w") do |f|
342
+ f.puts err
343
+ f.puts err.backtrace.join("\n")
344
+ end
345
+ puts "Error: See #{out}"
346
+ end
347
+
348
+ def _remove_post(arg, testing=false)
349
+ id = get_integer(arg)
350
+ result = @blog.remove_post(id)
351
+ puts "Post #{id} not found" if result.nil?
352
+ end
353
+
354
+ def cmd_remove_post(arg, testing = false)
355
+ reset_output
356
+ args = arg.split
357
+ args.each do |x|
358
+ # FIXME
359
+ ret = _remove_post(x.to_i, false)
360
+ puts ret
361
+ output ret
362
+ end
363
+ @out
364
+ end
365
+
366
+ def cmd_edit_post(arg, testing = false)
367
+ reset_output
368
+ id = get_integer(arg)
369
+ # Simplify this
370
+ tag = "#{'%04d' % id}"
371
+ files = ::Find.find(@blog.root/:drafts).to_a
372
+ files = files.grep(/#{tag}-.*lt3/)
373
+ files = files.map {|f| File.basename(f) }
374
+ if files.size > 1
375
+ msg = "Multiple files: #{files}"
376
+ output msg
377
+ puts msg unless testing
378
+ return [false, msg]
379
+ end
380
+ if files.empty?
381
+ msg = "\n Can't edit post #{id}"
382
+ output msg
383
+ puts msg unless testing
384
+ return [false, msg]
385
+ end
386
+
387
+ file = files.first
388
+ draft = @blog.root/:drafts/file
389
+ vim_params = '-c G'
390
+ result = edit_file(draft)
391
+ @blog.generate_post(draft)
392
+ rescue => err
393
+ out = "/tmp/blog#{rand(100)}.txt"
394
+ File.open(out, "w") do |f|
395
+ f.puts err
396
+ f.puts err.backtrace.join("\n")
397
+ end
398
+ puts "Error: See #{out}"
399
+ end
400
+
401
+ def cmd_list_views(arg, testing = false)
402
+ reset_output("\n")
403
+ puts unless testing
404
+ @blog.views.each do |v|
405
+ v = v.to_s
406
+ v = fx(v, :bold) if v == @blog.view.name
407
+ output v + "\n"
408
+ # FIXME: next 3 lines are crufty as hell
409
+ lines = File.readlines(@blog.root/"views/#{v}/themes/standard/global.lt3")
410
+ lines = lines.select {|x| x =~ /^blog / && x !~ /VIEW_/ }
411
+ title = lines.first.split(" ", 2)[1]
412
+ print " ", ('%15s' % v) unless testing
413
+ puts " ", fx(title, :black) unless testing
414
+ end
415
+ puts unless testing
416
+ # @out
417
+ end
418
+
419
+ def cmd_list_posts(arg, testing = false)
420
+ reset_output
421
+ posts = @blog.posts # current view
422
+ str = @blog.view.name + ":\n"
423
+ output str
424
+ puts unless testing
425
+ puts " ", fx(str, :bold) unless testing
426
+ if posts.empty?
427
+ output! "No posts"
428
+ puts " No posts" unless testing
429
+ else
430
+ posts.each do |post|
431
+ outstr " #{colored_slug(post)}\n"
432
+ base = post.sub(/.lt3$/, "")
433
+ num, rest = base[0..3], base[4..-1]
434
+ puts " ", fx(num, Red), fx(rest, Blue) unless testing
435
+ draft = @blog.root/:drafts/post + ".lt3"
436
+ other = @blog._get_views(draft) - [@blog.view.to_s]
437
+ unless other.empty?
438
+ print fx(" "*7 + "also in: ", :bold)
439
+ puts other.join(", ")
440
+ end
441
+ end
442
+ end
443
+ puts unless testing
444
+ @out
445
+ end
446
+
447
+ def cmd_list_drafts(arg, testing = false)
448
+ reset_output
449
+ drafts = @blog.drafts # current view
450
+ if drafts.empty?
451
+ output! "No drafts"
452
+ puts "\n No drafts\n " unless testing
453
+ return @out
454
+ else
455
+ puts unless testing
456
+ drafts.each do |draft|
457
+ outstr " #{colored_slug(draft.sub(/.lt3$/, ""))}\n"
458
+ base = draft.sub(/.lt3$/, "")
459
+ num, rest = base[0..3], base[4..-1]
460
+ puts " ", fx(num, Red), fx(rest, Blue) unless testing
461
+ other = @blog._get_views(@blog.root/:drafts/draft) - [@blog.view.to_s]
462
+ unless other.empty?
463
+ print fx(" "*7 + "also in: ", :bold)
464
+ puts other.join(", ")
465
+ end
466
+ end
467
+ end
468
+ puts unless testing
469
+ @out
470
+ end
471
+
472
+ def cmd_list_assets(arg, testing = false)
473
+ reset_output
474
+ dir = @blog.view.dir + "/assets"
475
+ assets = Dir[dir + "/*"]
476
+ if assets.empty?
477
+ output! "No assets"
478
+ puts " No assets" unless testing
479
+ return @out
480
+ else
481
+ puts unless testing
482
+ assets.each do |name|
483
+ asset = File.basename(name)
484
+ outstr asset
485
+ puts " ", fx(asset, Blue) unless testing
486
+ end
487
+ end
488
+ puts unless testing
489
+ @out
490
+ end
491
+
492
+ def cmd_ssh(arg, testing = false)
493
+ pub = @blog.view.publisher
494
+ puts
495
+ system!("tputs clear; ssh #{pub.user}@#{pub.server}")
496
+ sleep 0.1
497
+ cmd_clear(nil)
498
+ end
499
+
500
+ def cmd_INVALID(arg, testing = false)
501
+ reset_output "\n Command '#{arg}' was not understood."
502
+ print fx("\n Command ", :bold)
503
+ print fx(arg, Red, :bold)
504
+ puts fx(" was not understood.\n ", :bold)
505
+ @out
506
+ end
507
+
508
+ def cmd_legacy(arg = nil)
509
+ # dir = ask("Dir = ")
510
+ dir = "sources/computing"
511
+ puts "Importing from: #{dir}"
512
+ files = Dir[dir/"**"]
513
+ files.each do |fname|
514
+ name = fname
515
+ cmd = "grep ^.title #{name}"
516
+ grep = `#{cmd}` # find .title
517
+ @title = grep.sub(/^.title /, "")
518
+ num = `grep ^.post #{name}`.sub(/^.post /, "").to_i
519
+ seq = @blog.get_sequence
520
+ tnum = File.basename(fname).to_i
521
+
522
+ raise "num != seq + 1" if num != seq + 1
523
+ raise "num != tnum" if num != tnum
524
+ seq = @blog.next_sequence
525
+ raise "num != seq" if num != seq
526
+
527
+ label = '%04d' % num
528
+ slug0 = @title.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
529
+ @slug = "#{label}-#{slug0}"
530
+ @fname = @slug + ".lt3"
531
+ cmd = "cp #{name} #{@blog.root}/drafts/#@fname"
532
+ result = system!(cmd)
533
+ raise CantCopy(name, "#{@blog.root}/drafts/#@fname") unless result
534
+ # post = Post.load(@slug)
535
+ draft = "#{@blog.root}/drafts/#@fname"
536
+ @meta = @blog.generate_post(draft)
537
+ puts
538
+ sleep 2
539
+ end
540
+ rescue => err
541
+ error(err)
542
+ end
543
+
544
+ Help = <<-EOS
545
+
546
+ {Basics:} {Views:}
547
+ ------------------------------------------- -------------------------------------------
548
+ {h, help} This message {change view VIEW} Change current view
549
+ {q, quit} Exit the program {cv VIEW} Change current view
550
+ {v, version} Print version information {new view} Create a new view
551
+ {clear} Clear screen {list views} List all views available
552
+ {lsv} Same as: list views
553
+
554
+
555
+ {Posts:} {Advanced:}
556
+ ------------------------------------------- -------------------------------------------
557
+ {p, post} Create a new post {config} Edit various system files
558
+ {new post} Same as p, post {customize} (BUGGY) Change set of tags, extra views
559
+ {lsp, list posts} List posts in current view {preview} Look at current (local) view in browser
560
+ {lsd, list drafts} List all drafts (all views) {browse} Look at current (published) view in browser
561
+ {delete ID [ID...]} Remove multiple posts {rebuild} Regenerate all posts and relink
562
+ {undelete ID} Undelete a post {publish} Publish (current view)
563
+ {edit ID} Edit a post {ssh} Login to remote server
564
+ {import ASSETS} Import assets (images, etc.) {manage WIDGET} Manage content/layout of a widget
565
+ EOS
566
+
567
+ def cmd_help(arg, testing = false)
568
+ reset_output
569
+ msg = Help
570
+ output msg
571
+ msg.each_line do |line|
572
+ e = line.each_char
573
+ first = true
574
+ loop do
575
+ s1 = ""
576
+ c = e.next
577
+ if c == "{"
578
+ s2 = first ? "" : " "
579
+ first = false
580
+ loop do
581
+ c = e.next
582
+ break if c == "}"
583
+ s2 << c
584
+ end
585
+ print fx(s2, :bold)
586
+ s2 = ""
587
+ else
588
+ s1 << c
589
+ end
590
+ print s1
591
+ end
592
+ end
593
+ puts unless testing
594
+ @out
595
+ end
596
+ end
597
+