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.
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,95 @@
1
+ # Custom code for 'pages' widget
2
+
3
+ # How to update repl code?
4
+
5
+ class ::RuneBlog::Widget
6
+ class Pages
7
+ Type, Title = "pages", "My Pages"
8
+
9
+ def initialize(repo)
10
+ @blog = repo
11
+ @datafile = "list.data"
12
+ @lines = _get_data(@datafile)
13
+ @data = @lines.map {|x| x.chomp.split(/, */, 2) }
14
+ end
15
+
16
+ def build
17
+ # build child pages
18
+ children = Dir["*.lt3"] - ["pages.lt3"]
19
+ children.each do |child|
20
+ dest = child.sub(/.lt3$/, ".html")
21
+ preprocess src: child, dst: dest
22
+ end
23
+ write_main
24
+ write_card
25
+ end
26
+
27
+ def _html_body(file, css = nil)
28
+ file.puts "<html>"
29
+ if css
30
+ file.puts " <head>"
31
+ file.puts " <style>\n#{css}\n </style>"
32
+ file.puts " </head>"
33
+ end
34
+ file.puts " <body>"
35
+ yield
36
+ file.puts " </body>\n</html>"
37
+ end
38
+
39
+ def write_main
40
+ css = "body { font-family: verdana }"
41
+ card_title = Title
42
+ File.open("#{Type}-main.html", "w") do |f|
43
+ _html_body(f, css) do
44
+ f.puts "<h1>#{card_title}</h1><br><hr>"
45
+ url_ref = nil
46
+ @data.each do |url, title|
47
+ url_ref = "href = '#{url}'"
48
+ css = "color: #8888FF; text-decoration: none; font-size: 21px"
49
+ f.puts %[<a style="#{css}" #{url_ref}>#{title}</a> <br>]
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def write_card
56
+ tag = Type
57
+ url = :widgets/tag/tag+"-main.html"
58
+ card_title = "Pages" # FIXME
59
+ cardfile = "#{Type}-card"
60
+ File.open("#{cardfile}.html", "w") do |f|
61
+ f.puts <<-EOS
62
+ <div class="card mb-3">
63
+ <div class="card-body">
64
+ <h5 class="card-title">
65
+ <button type="button" class="btn btn-primary" data-toggle="collapse" data-target="##{tag}">+</button>
66
+ <a href="javascript: void(0)"
67
+ onclick="javascript:open_main('#{url}')"
68
+ style="text-decoration: none; color: black">#{card_title}</a>
69
+ </h5>
70
+ <div class="collapse" id="#{tag}">
71
+ EOS
72
+ @data.each do |url2, title|
73
+ f.puts "<!-- #{[url2, title].inspect} -->"
74
+ url3 = :widgets/tag/url2
75
+ f.puts "<!-- url3 = #{url3.inspect} -->"
76
+ url_ref = %[href="javascript: void(0)" onclick="javascript:open_main('#{url3}')"]
77
+ anchor = %[<a #{url_ref}>#{title}</a>]
78
+ wrapper = %[<li class="list-group-item">#{anchor}</li>]
79
+ f.puts wrapper
80
+ end
81
+ f.puts <<-EOS
82
+ </div>
83
+ </div>
84
+ </div>
85
+ EOS
86
+ end
87
+ end
88
+
89
+ def edit_menu
90
+ end
91
+
92
+ def refresh
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,2 @@
1
+ This is for a "standard" Runeblog widget
2
+ Code and docs are a work in progress
@@ -0,0 +1 @@
1
+ # CSS for sidebar card
@@ -0,0 +1 @@
1
+ # This is for specialized livetext add-ons (Ruby methods)
@@ -0,0 +1,2 @@
1
+ # CSS for main area page
2
+ body { font-family: verdana }
@@ -0,0 +1,99 @@
1
+ # Custom code for 'pinned' widget
2
+
3
+ class ::RuneBlog::Widget
4
+ class Pinned
5
+ Type, Title = "pinned", "Pinned posts"
6
+
7
+ def initialize(repo)
8
+ @blog = repo
9
+ @datafile = "list.data"
10
+ @lines = _get_data?(@datafile)
11
+ end
12
+
13
+ def _html_body(file, css = nil) # FIXME
14
+ file.puts "<html>"
15
+ if css
16
+ file.puts " <head>"
17
+ file.puts " <style>\n#{css}\n </style>"
18
+ file.puts " </head>"
19
+ end
20
+ file.puts " <body>"
21
+ yield
22
+ file.puts " </body>\n</html>"
23
+ end
24
+
25
+ def build
26
+ posts = nil
27
+ Dir.chdir(@blog.root/:posts) { posts = Dir["*"] }
28
+ hash = {}
29
+ @links = []
30
+ @lines.each do |x|
31
+ num, title = x.chomp.split(" ", 2)
32
+ hash[num] = title
33
+ pre = '%04d' % num
34
+ nslug = posts.grep(/#{pre}-/).first
35
+ name = nslug[5..-1]
36
+ link = name+".html"
37
+ @links << [title, link]
38
+ end
39
+ write_main
40
+ write_card
41
+ end
42
+
43
+ def write_main
44
+ tag = Type
45
+ card_title = Title
46
+ css = "body { font-family: verdana }"
47
+ mainfile = "#{tag}-main"
48
+ File.open("#{mainfile}.html", "w") do |f|
49
+ _html_body(f, css) do
50
+ f.puts "<!-- #{@lines.inspect} in #{Dir.pwd} -->"
51
+ f.puts "<h1>#{card_title}</h1><br><hr>"
52
+ @links.each do |title, file|
53
+ title = title.gsub(/\\/, "") # kludge
54
+ css = "color: #8888FF; text-decoration: none; font-size: 21px"
55
+ f.puts %[<a style="#{css}" href="../../#{file}">#{title}</a> <br>]
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ def write_card
62
+ tag = Type
63
+ url = :widgets/tag/tag+"-main.html"
64
+ card_title = Title
65
+ cardfile = "#{tag}-card"
66
+ File.open("#{cardfile}.html", "w") do |f|
67
+ f.puts <<-EOS
68
+ <div class="card mb-3">
69
+ <div class="card-body">
70
+ <h5 class="card-title">
71
+ <button type="button" class="btn btn-primary" data-toggle="collapse" data-target="##{tag}">+</button>
72
+ <a href="javascript: void(0)"
73
+ onclick="javascript:open_main('#{url}')"
74
+ style="text-decoration: none; color: black"> #{card_title}</a>
75
+ </h5>
76
+ <div class="collapse" id="#{tag}">
77
+ EOS
78
+ @links.each do |title, file|
79
+ url2 = file
80
+ url_ref = %[href="javascript: void(0)" onclick="javascript:open_main('#{url2}')"]
81
+ anchor = %[<a #{url_ref}>#{title}</a>]
82
+ wrapper = %[<li class="list-group-item">#{anchor}</li>]
83
+ f.puts wrapper
84
+ end
85
+ f.puts <<-EOS
86
+ </div>
87
+ </div>
88
+ </div>
89
+ EOS
90
+ end
91
+ end
92
+
93
+ def edit_menu
94
+ end
95
+
96
+ def refresh
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,2 @@
1
+ This is for a "standard" Runeblog widget
2
+ Code and docs are a work in progress
@@ -0,0 +1 @@
1
+ # CSS for sidebar card
@@ -0,0 +1 @@
1
+ # This is for specialized livetext add-ons (Ruby methods)
@@ -0,0 +1,2 @@
1
+ # CSS for main area page
2
+ body { font-family: verdana }
@@ -0,0 +1,18 @@
1
+ # Custom code for 'search' widget
2
+
3
+ class ::RuneBlog::Widget
4
+ class Search
5
+ def initialize(repo)
6
+ @blog = repo
7
+ end
8
+
9
+ def build
10
+ end
11
+
12
+ def edit_menu
13
+ end
14
+
15
+ def refresh
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,2 @@
1
+ This is for a "standard" Runeblog widget
2
+ Code and docs are a work in progress
@@ -0,0 +1 @@
1
+ # CSS for sidebar card
@@ -0,0 +1 @@
1
+ # This is for specialized livetext add-ons (Ruby methods)
@@ -0,0 +1,2 @@
1
+ # CSS for main area page
2
+ body { font-family: verdana }
@@ -0,0 +1,18 @@
1
+ # Custom code for 'sitemap' widget
2
+
3
+ class ::RuneBlog::Widget
4
+ class Sitemap
5
+ def initialize(repo)
6
+ @blog = repo
7
+ end
8
+
9
+ def build
10
+ end
11
+
12
+ def edit_menu
13
+ end
14
+
15
+ def refresh
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ .mixin liveblog
2
+
3
+ .tag_cloud
4
+ https://google.com/,btn btn-dark m-1,Programming
5
+ https://google.com/,btn btn-danger m-1,Science Fiction
6
+ https://google.com/,btn btn-light m-1,Art
7
+ https://google.com/,btn btn-dark m-1,Robotics
8
+ https://google.com/,btn btn-warning m-1,Food and Travel
9
+ https://google.com/,btn btn-light m-1,DIY Hacks
10
+ https://google.com/,btn btn-info m-1,Surfing
11
+ .end
12
+
@@ -0,0 +1,2 @@
1
+ This is for a "standard" Runeblog widget
2
+ Code and docs are a work in progress
@@ -0,0 +1 @@
1
+ # CSS for sidebar card
@@ -0,0 +1 @@
1
+ # This is for specialized livetext add-ons (Ruby methods)
@@ -0,0 +1,2 @@
1
+ # CSS for main area page
2
+ body { font-family: verdana }
@@ -0,0 +1,3 @@
1
+ .mixin liveblog
2
+
3
+ <h3>Currently nothing here -- not implemented</h3)
@@ -0,0 +1,18 @@
1
+ # Custom code for 'tag-cloud' widget
2
+
3
+ class ::RuneBlog::Widget
4
+ class TagCloud
5
+ def initialize(repo)
6
+ @blog = repo
7
+ end
8
+
9
+ def build
10
+ end
11
+
12
+ def edit_menu
13
+ end
14
+
15
+ def refresh
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,69 @@
1
+ def RuneBlog.teaser_template(title: "No title", date:, view: "test_view",
2
+ teaser: "No teaser", body: "No body", slug:)
3
+ <<-TEXT
4
+ <html>
5
+
6
+ <body>
7
+
8
+ <script>
9
+ window.fbAsyncInit = function() {
10
+ FB.init({
11
+ appId : '1176481582378716',
12
+ xfbml : true,
13
+ version : 'v2.4'
14
+ });
15
+ };
16
+
17
+ (function(d, s, id){
18
+ var js, fjs = d.getElementsByTagName(s)[0];
19
+ if (d.getElementById(id)) {return;}
20
+ js = d.createElement(s); js.id = id;
21
+ js.src = '//connect.facebook.net/en_US/sdk.js';
22
+ fjs.parentNode.insertBefore(js, fjs);
23
+ }(document, 'script', 'facebook-jssdk'));
24
+ </script>
25
+ <!-- meta property='fb:admins' content='767352779' /> -->
26
+ <meta property='og:url' content='http://rubyhacker.com/blog2/#{slug}.html'/>
27
+ <meta property='og:type' content='article'/>
28
+ <meta property='og:title' content='#{title}'/>
29
+ <meta property='og:image' content='http://rubyhacker.com/blog2/blog3b.gif'/>
30
+ <meta property='og:description' content='#{teaser}'/>
31
+
32
+ <table bgcolor=#eeeeee cellspacing=5>
33
+ <tr>
34
+ <td valign=top>
35
+ <br> <font size=+2 color=red>#{title}</font> <br> #{date}
36
+ </td>
37
+ <td width=2% bgcolor=red></td>
38
+ <td valign=top>
39
+ <a href='https://twitter.com/share'
40
+ class='twitter-share-button'
41
+ data-text='#{title}'
42
+ data-url='#{'url'}'
43
+ data-via='hal_fulton'
44
+ data-related='hal_fulton'>Tweet</a>
45
+ <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
46
+ <br>
47
+ <a href='https://twitter.com/hal_fulton' class='twitter-follow-button' data-show-count='false'>Follow @hal_fulton</a>
48
+ <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
49
+
50
+ <br>
51
+ <div
52
+ class='fb-like'
53
+ data-share='true'
54
+ data-width='450'
55
+ data-show-faces='true'>
56
+ </div>
57
+ </td>
58
+ </tr>
59
+ </table>
60
+ <hr>
61
+
62
+ #{body}
63
+
64
+ <hr>
65
+ <a href="http://rubyhacker.com/blog2" style="text-decoration: none">Back</a>
66
+ <a href="http://rubyhacker.com" style="text-decoration: none">Home</a>
67
+ TEXT
68
+ end
69
+
@@ -0,0 +1,155 @@
1
+ require 'runeblog_version'
2
+ require 'fileutils'
3
+
4
+ require 'processing'
5
+
6
+ require 'lowlevel'
7
+
8
+ module RuneBlog::Helpers
9
+
10
+ def quit_RubyText
11
+ return unless defined? RubyText
12
+ sleep 6
13
+ RubyText.stop
14
+ exit
15
+ end
16
+
17
+ def read_features
18
+ hash = {}
19
+ file = @root/self.view/"settings/features.txt"
20
+ lines = File.readlines(file)
21
+ lines.each do |line|
22
+ char, line = line[0], line[1..-1].chomp
23
+ name = line.strip
24
+ hash[name] = (char != "-")
25
+ end
26
+ @features = hash
27
+ end
28
+
29
+ def get_repo_config
30
+ log!(enter: __method__, level: 3)
31
+ @editor = File.read(".blogs/data/EDITOR").chomp
32
+ @current_view = File.read(".blogs/data/VIEW").chomp
33
+ @root = File.read(".blogs/data/ROOT").chomp
34
+ rescue => err
35
+ puts "Can't read config: #{err}"
36
+ puts err.backtrace.join("\n")
37
+ puts "dir = #{Dir.pwd}"
38
+ end
39
+
40
+ def copy_data(tag, dest)
41
+ data = RuneBlog::Path + "/../data" # files kept inside gem
42
+ extra = RuneBlog::Path + "/../config" # files kept inside gem
43
+ # FIXME names are confusing
44
+ case tag
45
+ when :config
46
+ files = %w[ROOT VIEW EDITOR universal.lt3 global.lt3]
47
+ files.each {|file| copy(data + "/" + file, dest) }
48
+ when :extra # FIXME remove later
49
+ # copy!(extra, dest)
50
+ end
51
+ end
52
+
53
+ def read_vars(file)
54
+ log!(enter: __method__, args: [file], level: 3)
55
+ lines = File.readlines(file).map(&:chomp)
56
+ hash = {}
57
+ skip = ["\n", "#", "."]
58
+ lines.each do |line|
59
+ line = line.strip
60
+ next if skip.include?(line[0])
61
+ key, val = line.split(" ", 2)
62
+ next if key.nil?
63
+ hash[key] = hash[key.to_sym] = val
64
+ end
65
+ hash
66
+ rescue => err
67
+ puts "Can't read vars file '#{file}': #{err}"
68
+ puts err.backtrace.join("\n")
69
+ puts "dir = #{Dir.pwd}"
70
+ stop_RubyText rescue nil
71
+ end
72
+
73
+ def read_config(file, *syms)
74
+ log!(enter: __method__, args: [file, *syms], level: 3)
75
+ lines = File.readlines(file).map(&:chomp)
76
+ obj = ::OpenStruct.new
77
+ skip = ["\n", "#", "."]
78
+ lines.each do |line|
79
+ next if skip.include?(line[0])
80
+ key, val = line.split(/: +/, 2)
81
+ obj.send(key+"=", val)
82
+ end
83
+ return obj if syms.empty?
84
+
85
+ vals = []
86
+ if syms.empty?
87
+ vals = obj.to_hash.values
88
+ else
89
+ syms.each {|sym| vals << obj.send(sym) }
90
+ end
91
+ return vals
92
+ rescue => err
93
+ puts "Can't read config file '#{file}': #{err}"
94
+ puts err.backtrace.join("\n")
95
+ puts "dir = #{Dir.pwd}"
96
+ stop_RubyText
97
+ end
98
+
99
+ def try_read_config(file, hash)
100
+ log!(enter: __method__, args: [file, hash], level: 3)
101
+ return hash.values unless File.exist?(file)
102
+ vals = read_config(file, *hash.keys)
103
+ vals
104
+ end
105
+
106
+ def write_config(obj, file)
107
+ log!(enter: __method__, args: [obj, file], level: 2)
108
+ hash = obj.to_h
109
+ File.open(file, "w") do |out|
110
+ hash.each_pair {|key, val| out.puts "#{key}: #{val}" }
111
+ end
112
+ end
113
+
114
+ def retrieve_views # read from filesystem
115
+ log!(enter: __method__, level: 3)
116
+ dirs = subdirs("#@root/views/").sort
117
+ dirs.map {|name| RuneBlog::View.new(name) }
118
+ end
119
+
120
+ def write_repo_config(root: "#{Dir.pwd}/.blogs", view: nil, editor: "/usr/local/bin/vim")
121
+ view ||= File.read("#{root}/data/VIEW").chomp rescue "[no view]"
122
+ File.write(root + "/data/ROOT", root + "\n")
123
+ File.write(root + "/data/VIEW", view.to_s + "\n")
124
+ File.write(root + "/data/EDITOR", editor + "\n")
125
+ end
126
+
127
+ def new_sequence
128
+ log!(enter: __method__, level: 3)
129
+ dump(0, "data/sequence")
130
+ version_info = "#{RuneBlog::VERSION}\nBlog created: #{Time.now.to_s}"
131
+ dump(version_info, "data/VERSION")
132
+ end
133
+
134
+ def subdirs(dir)
135
+ log!(enter: __method__, args: [dir], level: 3)
136
+ dirs = Dir.entries(dir) - %w[. ..]
137
+ dirs.reject! {|x| ! File.directory?("#@root/views/#{x}") }
138
+ dirs
139
+ end
140
+
141
+ def find_draft_slugs
142
+ log!(enter: __method__, level: 3)
143
+ files = Dir["#@root/drafts/**"].grep /\d{4}.*.lt3$/
144
+ flagfile = "#@root/drafts/last_rebuild"
145
+ last = File.exist?(flagfile) ? File.mtime(flagfile) : (Time.now - 86_400)
146
+ files.reject! {|f| File.mtime(f) > last }
147
+ files.map! {|f| File.basename(f) }
148
+ files = files.sort.reverse
149
+ debug "fss: #{files.inspect}"
150
+ files
151
+ end
152
+
153
+ end
154
+
155
+