adocsite 1.0.0
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.
- data/.gitignore +21 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +82 -0
- data/Rakefile +1 -0
- data/TODO.md +12 -0
- data/adocsite.gemspec +32 -0
- data/bin/adocsite +63 -0
- data/examples/myconfig.rb +7 -0
- data/examples/mywpconfig.rb +9 -0
- data/lib/adocsite.rb +35 -0
- data/lib/adocsite/commands.rb +83 -0
- data/lib/adocsite/config.rb +66 -0
- data/lib/adocsite/content_loader.rb +59 -0
- data/lib/adocsite/content_types.rb +60 -0
- data/lib/adocsite/context.rb +118 -0
- data/lib/adocsite/engine.rb +147 -0
- data/lib/adocsite/site.rb +49 -0
- data/lib/adocsite/templates.rb +91 -0
- data/lib/adocsite/version.rb +3 -0
- data/lib/adocsite/wp/post.rb +170 -0
- data/tpl/default/includes/anything.haml +2 -0
- data/tpl/default/includes/bottom.haml +2 -0
- data/tpl/default/includes/footer.haml +4 -0
- data/tpl/default/includes/header.haml +2 -0
- data/tpl/default/includes/menu.haml +9 -0
- data/tpl/default/includes/one_level_menu.haml +5 -0
- data/tpl/default/includes/top.haml +2 -0
- data/tpl/default/layouts/compact.haml +14 -0
- data/tpl/default/layouts/default.haml +14 -0
- data/tpl/default/literals/google_analytics +7 -0
- data/tpl/default/partials/article.haml +2 -0
- data/tpl/default/partials/category.haml +6 -0
- data/tpl/default/partials/home.haml +12 -0
- data/tpl/default/partials/page.haml +2 -0
- data/tpl/default/resources/asciidoc.js +189 -0
- data/tpl/default/resources/asciidoctor.css +351 -0
- data/tpl/default/resources/funky.css +0 -0
- data/tpl/default/resources/kernel.css +0 -0
- data/tpl/default/resources/myblueraven.css +11 -0
- data/tpl/default/resources/myblueraven.js +0 -0
- data/tpl/default/resources/old-myblueraven.css +1316 -0
- data/tpl/default/resources/sleepy.js +0 -0
- metadata +201 -0
@@ -0,0 +1,170 @@
|
|
1
|
+
module Adocsite
|
2
|
+
class WpPost
|
3
|
+
attr_reader :categories, :content, :title, :excerpt, :name, :img_srcs, :post_media
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@engine = Adocsite::Engine::new
|
7
|
+
|
8
|
+
@wp = Rubypress::Client.new(Adocsite.wpconfig)
|
9
|
+
end
|
10
|
+
|
11
|
+
def process_by_title(article_title)
|
12
|
+
article_name = Adocsite::Content::title_to_name(article_title)
|
13
|
+
process(article_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def process(article_name)
|
17
|
+
@name = article_name
|
18
|
+
context = Adocsite::Context::new(@engine, Adocsite::Request.new('article', @name))
|
19
|
+
article = context.get_article
|
20
|
+
if article.nil?
|
21
|
+
abort "Can't find article."
|
22
|
+
end
|
23
|
+
|
24
|
+
@categories = article.categories
|
25
|
+
@content = article.content
|
26
|
+
@title = article.title
|
27
|
+
@excerpt = article.abstract
|
28
|
+
|
29
|
+
collect_images
|
30
|
+
create_post
|
31
|
+
upload_post_media
|
32
|
+
replace_images(@post_media)
|
33
|
+
update_post
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_post
|
37
|
+
# get all WP categories
|
38
|
+
wp_categories = @wp.getTerms(:taxonomy => 'category')
|
39
|
+
all_categories = Hash.new
|
40
|
+
wp_categories.each {|term|
|
41
|
+
all_categories[term['name']] = term['term_id']
|
42
|
+
}
|
43
|
+
|
44
|
+
# are there any new we need to create?
|
45
|
+
new_categories_names = @categories - all_categories.keys
|
46
|
+
|
47
|
+
# pp new_categories_names
|
48
|
+
|
49
|
+
# create new categories, collect term_ids
|
50
|
+
new_categories = Hash.new
|
51
|
+
unless new_categories_names.empty?
|
52
|
+
new_categories_names.each {|name|
|
53
|
+
term_id = @wp.newTerm(:content => {:taxonomy => 'category', :name => name})
|
54
|
+
new_categories[name] = term_id
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
# create list of all article categories with their term_ids
|
59
|
+
article_categories = Hash.new
|
60
|
+
@categories.each {|name|
|
61
|
+
if all_categories.include?(name)
|
62
|
+
article_categories[name] = all_categories[name]
|
63
|
+
end
|
64
|
+
if new_categories.include?(name)
|
65
|
+
article_categories[name] = new_categories[name]
|
66
|
+
end
|
67
|
+
}
|
68
|
+
|
69
|
+
# now create new post from article
|
70
|
+
@post_id = @wp.newPost(:content => {
|
71
|
+
# :post_type => 'post', # by default post_type is 'post'
|
72
|
+
:post_status => 'draft', # post will be draft if post_status is omitted
|
73
|
+
:post_title => @title,
|
74
|
+
# :post_author => 'admin', # by default post_author is same as user you use for calling wp.newPost method
|
75
|
+
:post_excerpt => @excerpt,
|
76
|
+
:post_content => "", # empty content for now
|
77
|
+
:terms =>
|
78
|
+
{
|
79
|
+
:category => article_categories.values # these are term_ids for categories, if omitted default is 'Uncategorized'
|
80
|
+
}
|
81
|
+
})
|
82
|
+
# pp post_id
|
83
|
+
@post_id
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_full_image_path(image_name, image_list)
|
87
|
+
ret_arr = image_list.collect {|element|
|
88
|
+
if element.end_with? image_name
|
89
|
+
element
|
90
|
+
else
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
}
|
94
|
+
ret_arr.compact[0]
|
95
|
+
end
|
96
|
+
|
97
|
+
def upload_post_media
|
98
|
+
site_images = @engine.content_loader.images
|
99
|
+
@post_media = Hash.new
|
100
|
+
@img_srcs.each {|image_name|
|
101
|
+
file_path = find_full_image_path(image_name, site_images)
|
102
|
+
# file_name = File.join("", file_path)
|
103
|
+
file_name = file_path
|
104
|
+
|
105
|
+
image_contents = XMLRPC::Base64.new(IO.read(file_name))
|
106
|
+
image_type = MIME::Types.type_for(image_name).first.to_s
|
107
|
+
|
108
|
+
media_upload = @wp.uploadFile(:data => {
|
109
|
+
:name => image_name,
|
110
|
+
:type => image_type,
|
111
|
+
# :filename => file_name,
|
112
|
+
:bits => image_contents,
|
113
|
+
:overwrite => false,
|
114
|
+
:post_id => @post_id
|
115
|
+
})
|
116
|
+
# media_upload[:url] is NOT going to work here
|
117
|
+
@post_media[image_name] = media_upload["url"]
|
118
|
+
# pp media_upload
|
119
|
+
}
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
def update_post
|
124
|
+
#Update/Edit post
|
125
|
+
@post_id = @wp.editPost(:post_id => @post_id,
|
126
|
+
:content => {
|
127
|
+
:post_status => 'publish', # it was created as draft, now publish it
|
128
|
+
:post_content => @content
|
129
|
+
})
|
130
|
+
# pp post_id
|
131
|
+
@post_id
|
132
|
+
end
|
133
|
+
|
134
|
+
def stringreturn(img_name)
|
135
|
+
@img_hash[img_name]
|
136
|
+
end
|
137
|
+
|
138
|
+
def collect_images
|
139
|
+
doc = Nokogiri::HTML(@content)
|
140
|
+
img_srcs = doc.css('img').map{ |i| i['src'] } # Array of strings
|
141
|
+
|
142
|
+
# pp article_content
|
143
|
+
|
144
|
+
# pp img_srcs
|
145
|
+
|
146
|
+
img_srcs = img_srcs.collect {|img_src|
|
147
|
+
md = /^img\/(.*)/.match(img_src)
|
148
|
+
md.captures[0] unless md == nil
|
149
|
+
}
|
150
|
+
|
151
|
+
@img_srcs = img_srcs.compact
|
152
|
+
|
153
|
+
# pp img_srcs
|
154
|
+
end
|
155
|
+
|
156
|
+
def replace_images(new_images)
|
157
|
+
@img_hash = Hash.new
|
158
|
+
@img_srcs.each {|img_nm|
|
159
|
+
# @img_hash[img_nm] = "\"myimages/#{img_nm}\""
|
160
|
+
@img_hash[img_nm] = new_images[img_nm]
|
161
|
+
}
|
162
|
+
|
163
|
+
# pp article_content
|
164
|
+
@content = @content.gsub(/"img\/(.*?)"/) {|img_tag| stringreturn("#$1")}
|
165
|
+
# pp article_content
|
166
|
+
end
|
167
|
+
|
168
|
+
private :create_post, :find_full_image_path, :upload_post_media, :update_post, :stringreturn, :collect_images, :replace_images
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
%html
|
2
|
+
%head
|
3
|
+
%title= page_title
|
4
|
+
%script{:src => 'js/asciidoc.js'}
|
5
|
+
%script{:src => 'js/myblueraven.js'}
|
6
|
+
%link{:rel => 'stylesheet', :media => "screen", :href => 'css/myblueraven.css'}
|
7
|
+
%body
|
8
|
+
#page
|
9
|
+
#header
|
10
|
+
This is 'compact' layout. Looks the same as default, it's here only to show that you can have different ones.
|
11
|
+
#content
|
12
|
+
= get_content_for_layout()
|
13
|
+
#footer
|
14
|
+
= get_include('footer')
|
@@ -0,0 +1,14 @@
|
|
1
|
+
%html
|
2
|
+
%head
|
3
|
+
%title= page_title
|
4
|
+
%script{:src => 'js/asciidoc.js'}
|
5
|
+
%script{:src => 'js/myblueraven.js'}
|
6
|
+
%link{:rel => 'stylesheet', :media => "screen", :href => 'css/myblueraven.css'}
|
7
|
+
%body
|
8
|
+
#page
|
9
|
+
#header
|
10
|
+
= get_include('header')
|
11
|
+
#content
|
12
|
+
= get_content_for_layout()
|
13
|
+
#footer
|
14
|
+
= get_include('footer')
|
@@ -0,0 +1,7 @@
|
|
1
|
+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
2
|
+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
3
|
+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
4
|
+
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
5
|
+
|
6
|
+
//ga('create', 'UA-931975-7', 'unknownworlds.com');
|
7
|
+
//ga('send', 'pageview');
|
@@ -0,0 +1,12 @@
|
|
1
|
+
.content
|
2
|
+
%h1 Pages list
|
3
|
+
- get_pages().each do |page|
|
4
|
+
%p
|
5
|
+
%a{:href => sitenav('page', page.name)}
|
6
|
+
= page.name
|
7
|
+
%h1 Categories list
|
8
|
+
- get_categories().each do |category|
|
9
|
+
%p
|
10
|
+
%a{:href => sitenav('category', category.name)}
|
11
|
+
= category.name
|
12
|
+
|
@@ -0,0 +1,189 @@
|
|
1
|
+
var asciidoc = { // Namespace.
|
2
|
+
|
3
|
+
/////////////////////////////////////////////////////////////////////
|
4
|
+
// Table Of Contents generator
|
5
|
+
/////////////////////////////////////////////////////////////////////
|
6
|
+
|
7
|
+
/* Author: Mihai Bazon, September 2002
|
8
|
+
* http://students.infoiasi.ro/~mishoo
|
9
|
+
*
|
10
|
+
* Table Of Content generator
|
11
|
+
* Version: 0.4
|
12
|
+
*
|
13
|
+
* Feel free to use this script under the terms of the GNU General Public
|
14
|
+
* License, as long as you do not remove or alter this notice.
|
15
|
+
*/
|
16
|
+
|
17
|
+
/* modified by Troy D. Hanson, September 2006. License: GPL */
|
18
|
+
/* modified by Stuart Rackham, 2006, 2009. License: GPL */
|
19
|
+
|
20
|
+
// toclevels = 1..4.
|
21
|
+
toc: function (toclevels) {
|
22
|
+
|
23
|
+
function getText(el) {
|
24
|
+
var text = "";
|
25
|
+
for (var i = el.firstChild; i != null; i = i.nextSibling) {
|
26
|
+
if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
|
27
|
+
text += i.data;
|
28
|
+
else if (i.firstChild != null)
|
29
|
+
text += getText(i);
|
30
|
+
}
|
31
|
+
return text;
|
32
|
+
}
|
33
|
+
|
34
|
+
function TocEntry(el, text, toclevel) {
|
35
|
+
this.element = el;
|
36
|
+
this.text = text;
|
37
|
+
this.toclevel = toclevel;
|
38
|
+
}
|
39
|
+
|
40
|
+
function tocEntries(el, toclevels) {
|
41
|
+
var result = new Array;
|
42
|
+
var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
|
43
|
+
// Function that scans the DOM tree for header elements (the DOM2
|
44
|
+
// nodeIterator API would be a better technique but not supported by all
|
45
|
+
// browsers).
|
46
|
+
var iterate = function (el) {
|
47
|
+
for (var i = el.firstChild; i != null; i = i.nextSibling) {
|
48
|
+
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
|
49
|
+
var mo = re.exec(i.tagName);
|
50
|
+
if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
|
51
|
+
result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
|
52
|
+
}
|
53
|
+
iterate(i);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
iterate(el);
|
58
|
+
return result;
|
59
|
+
}
|
60
|
+
|
61
|
+
var toc = document.getElementById("toc");
|
62
|
+
if (!toc) {
|
63
|
+
return;
|
64
|
+
}
|
65
|
+
|
66
|
+
// Delete existing TOC entries in case we're reloading the TOC.
|
67
|
+
var tocEntriesToRemove = [];
|
68
|
+
var i;
|
69
|
+
for (i = 0; i < toc.childNodes.length; i++) {
|
70
|
+
var entry = toc.childNodes[i];
|
71
|
+
if (entry.nodeName == 'div'
|
72
|
+
&& entry.getAttribute("class")
|
73
|
+
&& entry.getAttribute("class").match(/^toclevel/))
|
74
|
+
tocEntriesToRemove.push(entry);
|
75
|
+
}
|
76
|
+
for (i = 0; i < tocEntriesToRemove.length; i++) {
|
77
|
+
toc.removeChild(tocEntriesToRemove[i]);
|
78
|
+
}
|
79
|
+
|
80
|
+
// Rebuild TOC entries.
|
81
|
+
var entries = tocEntries(document.getElementById("content"), toclevels);
|
82
|
+
for (var i = 0; i < entries.length; ++i) {
|
83
|
+
var entry = entries[i];
|
84
|
+
if (entry.element.id == "")
|
85
|
+
entry.element.id = "_toc_" + i;
|
86
|
+
var a = document.createElement("a");
|
87
|
+
a.href = "#" + entry.element.id;
|
88
|
+
a.appendChild(document.createTextNode(entry.text));
|
89
|
+
var div = document.createElement("div");
|
90
|
+
div.appendChild(a);
|
91
|
+
div.className = "toclevel" + entry.toclevel;
|
92
|
+
toc.appendChild(div);
|
93
|
+
}
|
94
|
+
if (entries.length == 0)
|
95
|
+
toc.parentNode.removeChild(toc);
|
96
|
+
},
|
97
|
+
|
98
|
+
|
99
|
+
/////////////////////////////////////////////////////////////////////
|
100
|
+
// Footnotes generator
|
101
|
+
/////////////////////////////////////////////////////////////////////
|
102
|
+
|
103
|
+
/* Based on footnote generation code from:
|
104
|
+
* http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
|
105
|
+
*/
|
106
|
+
|
107
|
+
footnotes: function () {
|
108
|
+
// Delete existing footnote entries in case we're reloading the footnodes.
|
109
|
+
var i;
|
110
|
+
var noteholder = document.getElementById("footnotes");
|
111
|
+
if (!noteholder) {
|
112
|
+
return;
|
113
|
+
}
|
114
|
+
var entriesToRemove = [];
|
115
|
+
for (i = 0; i < noteholder.childNodes.length; i++) {
|
116
|
+
var entry = noteholder.childNodes[i];
|
117
|
+
if (entry.nodeName == 'div' && entry.getAttribute("class") == "footnote")
|
118
|
+
entriesToRemove.push(entry);
|
119
|
+
}
|
120
|
+
for (i = 0; i < entriesToRemove.length; i++) {
|
121
|
+
noteholder.removeChild(entriesToRemove[i]);
|
122
|
+
}
|
123
|
+
|
124
|
+
// Rebuild footnote entries.
|
125
|
+
var cont = document.getElementById("content");
|
126
|
+
var spans = cont.getElementsByTagName("span");
|
127
|
+
var refs = {};
|
128
|
+
var n = 0;
|
129
|
+
for (i=0; i<spans.length; i++) {
|
130
|
+
if (spans[i].className == "footnote") {
|
131
|
+
n++;
|
132
|
+
var note = spans[i].getAttribute("data-note");
|
133
|
+
if (!note) {
|
134
|
+
// Use [\s\S] in place of . so multi-line matches work.
|
135
|
+
// Because JavaScript has no s (dotall) regex flag.
|
136
|
+
note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
|
137
|
+
spans[i].innerHTML =
|
138
|
+
"[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
|
139
|
+
"' title='View footnote' class='footnote'>" + n + "</a>]";
|
140
|
+
spans[i].setAttribute("data-note", note);
|
141
|
+
}
|
142
|
+
noteholder.innerHTML +=
|
143
|
+
"<div class='footnote' id='_footnote_" + n + "'>" +
|
144
|
+
"<a href='#_footnoteref_" + n + "' title='Return to text'>" +
|
145
|
+
n + "</a>. " + note + "</div>";
|
146
|
+
var id =spans[i].getAttribute("id");
|
147
|
+
if (id != null) refs["#"+id] = n;
|
148
|
+
}
|
149
|
+
}
|
150
|
+
if (n == 0)
|
151
|
+
noteholder.parentNode.removeChild(noteholder);
|
152
|
+
else {
|
153
|
+
// Process footnoterefs.
|
154
|
+
for (i=0; i<spans.length; i++) {
|
155
|
+
if (spans[i].className == "footnoteref") {
|
156
|
+
var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
|
157
|
+
href = href.match(/#.*/)[0]; // Because IE return full URL.
|
158
|
+
n = refs[href];
|
159
|
+
spans[i].innerHTML =
|
160
|
+
"[<a href='#_footnote_" + n +
|
161
|
+
"' title='View footnote' class='footnote'>" + n + "</a>]";
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}
|
165
|
+
},
|
166
|
+
|
167
|
+
install: function(toclevels) {
|
168
|
+
var timerId;
|
169
|
+
|
170
|
+
function reinstall() {
|
171
|
+
asciidoc.footnotes();
|
172
|
+
if (toclevels) {
|
173
|
+
asciidoc.toc(toclevels);
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
function reinstallAndRemoveTimer() {
|
178
|
+
clearInterval(timerId);
|
179
|
+
reinstall();
|
180
|
+
}
|
181
|
+
|
182
|
+
timerId = setInterval(reinstall, 500);
|
183
|
+
if (document.addEventListener)
|
184
|
+
document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
|
185
|
+
else
|
186
|
+
window.onload = reinstallAndRemoveTimer;
|
187
|
+
}
|
188
|
+
|
189
|
+
}
|