rethoth 0.4.1

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 (109) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +26 -0
  3. data/bin/thoth +233 -0
  4. data/lib/proto/config.ru +45 -0
  5. data/lib/proto/thoth.conf.sample +206 -0
  6. data/lib/thoth/cache.rb +53 -0
  7. data/lib/thoth/config.rb +158 -0
  8. data/lib/thoth/controller/admin.rb +75 -0
  9. data/lib/thoth/controller/api/comment.rb +73 -0
  10. data/lib/thoth/controller/api/page.rb +134 -0
  11. data/lib/thoth/controller/api/post.rb +122 -0
  12. data/lib/thoth/controller/api/tag.rb +59 -0
  13. data/lib/thoth/controller/archive.rb +50 -0
  14. data/lib/thoth/controller/comment.rb +173 -0
  15. data/lib/thoth/controller/main.rb +193 -0
  16. data/lib/thoth/controller/media.rb +172 -0
  17. data/lib/thoth/controller/page.rb +167 -0
  18. data/lib/thoth/controller/post.rb +310 -0
  19. data/lib/thoth/controller/search.rb +86 -0
  20. data/lib/thoth/controller/tag.rb +107 -0
  21. data/lib/thoth/controller.rb +48 -0
  22. data/lib/thoth/errors.rb +35 -0
  23. data/lib/thoth/helper/admin.rb +86 -0
  24. data/lib/thoth/helper/cookie.rb +45 -0
  25. data/lib/thoth/helper/error.rb +122 -0
  26. data/lib/thoth/helper/pagination.rb +131 -0
  27. data/lib/thoth/helper/wiki.rb +77 -0
  28. data/lib/thoth/helper/ysearch.rb +89 -0
  29. data/lib/thoth/importer/pants.rb +81 -0
  30. data/lib/thoth/importer/poseidon.rb +54 -0
  31. data/lib/thoth/importer/thoth.rb +103 -0
  32. data/lib/thoth/importer.rb +131 -0
  33. data/lib/thoth/layout/default.rhtml +47 -0
  34. data/lib/thoth/middleware/minify.rb +82 -0
  35. data/lib/thoth/migrate/001_create_schema.rb +108 -0
  36. data/lib/thoth/migrate/002_add_media_size.rb +37 -0
  37. data/lib/thoth/migrate/003_add_post_draft.rb +38 -0
  38. data/lib/thoth/migrate/004_add_comment_email.rb +37 -0
  39. data/lib/thoth/migrate/005_add_page_position.rb +37 -0
  40. data/lib/thoth/migrate/006_add_comment_close_delete.rb +43 -0
  41. data/lib/thoth/migrate/007_add_comment_summary.rb +37 -0
  42. data/lib/thoth/model/comment.rb +216 -0
  43. data/lib/thoth/model/media.rb +87 -0
  44. data/lib/thoth/model/page.rb +204 -0
  45. data/lib/thoth/model/post.rb +262 -0
  46. data/lib/thoth/model/tag.rb +80 -0
  47. data/lib/thoth/model/tags_posts_map.rb +34 -0
  48. data/lib/thoth/monkeypatch/sequel/model/errors.rb +37 -0
  49. data/lib/thoth/plugin/thoth_delicious.rb +105 -0
  50. data/lib/thoth/plugin/thoth_flickr.rb +86 -0
  51. data/lib/thoth/plugin/thoth_pinboard.rb +98 -0
  52. data/lib/thoth/plugin/thoth_tags.rb +68 -0
  53. data/lib/thoth/plugin/thoth_twitter.rb +175 -0
  54. data/lib/thoth/plugin.rb +59 -0
  55. data/lib/thoth/public/css/admin.css +223 -0
  56. data/lib/thoth/public/css/thoth.css +592 -0
  57. data/lib/thoth/public/images/admin-sprite.png +0 -0
  58. data/lib/thoth/public/images/thoth-sprite.png +0 -0
  59. data/lib/thoth/public/js/admin/comments.js +116 -0
  60. data/lib/thoth/public/js/admin/name.js +244 -0
  61. data/lib/thoth/public/js/admin/tagcomplete.js +332 -0
  62. data/lib/thoth/public/js/lazyload-min.js +4 -0
  63. data/lib/thoth/public/js/thoth.js +203 -0
  64. data/lib/thoth/public/robots.txt +5 -0
  65. data/lib/thoth/version.rb +37 -0
  66. data/lib/thoth/view/admin/index.rhtml +1 -0
  67. data/lib/thoth/view/admin/login.rhtml +23 -0
  68. data/lib/thoth/view/admin/toolbar.rhtml +117 -0
  69. data/lib/thoth/view/admin/welcome.rhtml +58 -0
  70. data/lib/thoth/view/archive/index.rhtml +24 -0
  71. data/lib/thoth/view/comment/comment.rhtml +47 -0
  72. data/lib/thoth/view/comment/delete.rhtml +15 -0
  73. data/lib/thoth/view/comment/form.rhtml +81 -0
  74. data/lib/thoth/view/comment/index.rhtml +68 -0
  75. data/lib/thoth/view/comment/list.rhtml +48 -0
  76. data/lib/thoth/view/media/delete.rhtml +15 -0
  77. data/lib/thoth/view/media/edit.rhtml +12 -0
  78. data/lib/thoth/view/media/form.rhtml +7 -0
  79. data/lib/thoth/view/media/list.rhtml +35 -0
  80. data/lib/thoth/view/media/media.rhtml +44 -0
  81. data/lib/thoth/view/media/new.rhtml +7 -0
  82. data/lib/thoth/view/page/delete.rhtml +15 -0
  83. data/lib/thoth/view/page/edit.rhtml +15 -0
  84. data/lib/thoth/view/page/form.rhtml +57 -0
  85. data/lib/thoth/view/page/index.rhtml +9 -0
  86. data/lib/thoth/view/page/list.rhtml +49 -0
  87. data/lib/thoth/view/page/new.rhtml +15 -0
  88. data/lib/thoth/view/post/comments.rhtml +12 -0
  89. data/lib/thoth/view/post/compact.rhtml +48 -0
  90. data/lib/thoth/view/post/delete.rhtml +15 -0
  91. data/lib/thoth/view/post/edit.rhtml +15 -0
  92. data/lib/thoth/view/post/form.rhtml +83 -0
  93. data/lib/thoth/view/post/index.rhtml +48 -0
  94. data/lib/thoth/view/post/list.rhtml +61 -0
  95. data/lib/thoth/view/post/new.rhtml +15 -0
  96. data/lib/thoth/view/post/tiny.rhtml +4 -0
  97. data/lib/thoth/view/search/index.rhtml +45 -0
  98. data/lib/thoth/view/tag/index.rhtml +34 -0
  99. data/lib/thoth/view/thoth/css.rhtml +9 -0
  100. data/lib/thoth/view/thoth/footer.rhtml +15 -0
  101. data/lib/thoth/view/thoth/header.rhtml +23 -0
  102. data/lib/thoth/view/thoth/index.rhtml +11 -0
  103. data/lib/thoth/view/thoth/js.rhtml +6 -0
  104. data/lib/thoth/view/thoth/sidebar.rhtml +38 -0
  105. data/lib/thoth/view/thoth/util/pager.rhtml +23 -0
  106. data/lib/thoth/view/thoth/util/simple_pager.rhtml +15 -0
  107. data/lib/thoth/view/thoth/util/table_sortheader.rhtml +20 -0
  108. data/lib/thoth.rb +394 -0
  109. metadata +409 -0
@@ -0,0 +1,45 @@
1
+ #--
2
+ # Copyright (c) 2009 Ryan Grove <ryan@wonko.com>
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of this project nor the names of its contributors may be
14
+ # used to endorse or promote products derived from this software without
15
+ # specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ module Thoth; module Helper
30
+
31
+ # The Cookie helper wraps access to Ramaze's request.cookies hash and returns
32
+ # only the first cookie matching a specified name (rather than an array).
33
+ module Cookie
34
+ private
35
+
36
+ # Gets the first cookie matching the specified _name_. If not found, the
37
+ # provided _default_ value will be returned.
38
+ def cookie(name, default = nil)
39
+ return default unless cookie = request.cookies[name.to_s]
40
+ return cookie.first if cookie.is_a?(Array)
41
+ cookie
42
+ end
43
+ end
44
+
45
+ end; end
@@ -0,0 +1,122 @@
1
+ #--
2
+ # Copyright (c) 2009 Ryan Grove <ryan@wonko.com>
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of this project nor the names of its contributors may be
14
+ # used to endorse or promote products derived from this software without
15
+ # specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ module Thoth; module Helper
30
+
31
+ # The Error helper module provides methods for interrupting the current
32
+ # request and responding with an error message and corresponding HTTP error
33
+ # code.
34
+ module Error
35
+ Ramaze::Helper::LOOKUP << self
36
+
37
+ # Displays a "400 Bad Request" error message and returns a 400 response
38
+ # code.
39
+ def error_400(message = nil)
40
+ if message
41
+ error_layout 400, '400 Bad Request', %[
42
+ <p>
43
+ Your browser sent a request that this server could not understand.
44
+ </p>
45
+
46
+ <p>
47
+ #{message}
48
+ </p>
49
+ ]
50
+ else
51
+ error_layout 400, '400 Bad Request', %[
52
+ <p>
53
+ Your browser sent a request that this server could not understand.
54
+ </p>
55
+ ]
56
+ end
57
+ end
58
+
59
+ # Displays a "403 Forbidden" error message and returns a 403 response code.
60
+ def error_403
61
+ error_layout 403, '403 Forbidden', %[
62
+ <p>
63
+ You don't have permission to access
64
+ <code>#{h(request.REQUEST_URI)}</code> on this server.
65
+ </p>
66
+ ]
67
+ end
68
+
69
+ # Displays a "404 Not Found" error message and returns a 404 response code.
70
+ def error_404
71
+ error_layout 404, '404 Not Found', %[
72
+ <p>
73
+ The requested URL <code>#{h(request.REQUEST_URI)}</code> was not
74
+ found on this server.
75
+ </p>
76
+ ]
77
+ end
78
+
79
+ # Displays a "405 Method Not Allowed" error message and returns a 405
80
+ # response code.
81
+ def error_405
82
+ error_layout 405, '405 Method Not Allowed', %[
83
+ <p>
84
+ The #{request.env['REQUEST_METHOD']} method is not allowed for the
85
+ requested URL.
86
+ </p>
87
+ ]
88
+ end
89
+
90
+ # Displays a "500 Internal Server Error" error message and returns a 500
91
+ # response code.
92
+ def error_500
93
+ if e = request.env[Rack::RouteExceptions::EXCEPTION]
94
+ Ramaze::Log.error e
95
+ end
96
+
97
+ error_layout 500, '500 Internal Server Error', %[
98
+ <p>
99
+ The server encountered an internal error and was unable to complete
100
+ your request.
101
+ </p>
102
+ ]
103
+ end
104
+
105
+ private
106
+
107
+ def error_layout(status, title, content = '')
108
+ respond! %[
109
+ <html>
110
+ <head>
111
+ <title>#{h(title)}</title>
112
+ </head>
113
+ <body>
114
+ <h1>#{h(title)}</h1>
115
+ #{content}
116
+ </body>
117
+ </html>
118
+ ].unindent, status
119
+ end
120
+ end
121
+
122
+ end; end
@@ -0,0 +1,131 @@
1
+ #--
2
+ # Copyright (c) 2009 Ryan Grove <ryan@wonko.com>
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of this project nor the names of its contributors may be
14
+ # used to endorse or promote products derived from this software without
15
+ # specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ module Thoth
30
+
31
+ # The Pager class provides a simple wrapper around a paginated Sequel dataset.
32
+ class Pager
33
+
34
+ # Initializes a new Pager instance wrapping the given Sequel _dataset_ and
35
+ # using _url_ as the template for all generated URLs. _url_ should be a
36
+ # string containing an sprintf flag (such as <tt>%s</tt>) in place of the
37
+ # page number.
38
+ def initialize(dataset, url)
39
+ @dataset = dataset
40
+ @url = url
41
+ end
42
+
43
+ # Returns the number of the current page.
44
+ def current_page
45
+ @dataset.current_page
46
+ end
47
+
48
+ # Returns the number of records in the current page.
49
+ def current_page_record_count
50
+ @dataset.current_page_record_count
51
+ end
52
+
53
+ # Returns the record range for the current page.
54
+ def current_page_record_range
55
+ @dataset.current_page_record_range
56
+ end
57
+
58
+ # Iterates over all pages within 5 steps from the current page, yielding the
59
+ # page number and URL for each.
60
+ def navigate # :yields: page, url
61
+ nav_start = [current_page - 5, 1].max
62
+ nav_end = [nav_start + 9, page_count].min
63
+ (nav_start..nav_end).each {|page| yield page, url(page) }
64
+ end
65
+
66
+ # Returns +true+ if the total number of pages is greater than 1.
67
+ def navigation?
68
+ page_count > 1
69
+ end
70
+
71
+ # Returns the number of the next page or +nil+ if the current page is the
72
+ # last.
73
+ def next_page
74
+ @dataset.next_page
75
+ end
76
+
77
+ # Returns the URL for the next page or +nil+ if the current page is the
78
+ # last.
79
+ def next_url
80
+ next_page ? url(next_page) : nil
81
+ end
82
+
83
+ # Returns the total number of pages.
84
+ def page_count
85
+ @dataset.page_count
86
+ end
87
+
88
+ # Returns the page range.
89
+ def page_range
90
+ @dataset.page_range
91
+ end
92
+
93
+ # Returns the number of records per page.
94
+ def page_size
95
+ @dataset.page_size
96
+ end
97
+
98
+ # Returns the number of the previous page or +nil+ if the current page is
99
+ # the first.
100
+ def prev_page
101
+ @dataset.prev_page
102
+ end
103
+
104
+ # Returns the URL for the previous page or +nil+ if the current page is the
105
+ # first.
106
+ def prev_url
107
+ prev_page ? url(prev_page) : nil
108
+ end
109
+
110
+ # Returns the total number of records in the dataset.
111
+ def record_count
112
+ @dataset.pagination_record_count
113
+ end
114
+
115
+ # Returns the URL for the specified page number.
116
+ def url(page)
117
+ @url.to_s.gsub('__page__', page.to_i.to_s)
118
+ end
119
+
120
+ end
121
+ end
122
+
123
+ module Thoth; module Helper
124
+ module Pagination
125
+
126
+ def pager(dataset, url = rs(:/, '__page__'))
127
+ Pager.new(dataset, url)
128
+ end
129
+
130
+ end
131
+ end; end
@@ -0,0 +1,77 @@
1
+ #--
2
+ # Copyright (c) 2009 Ryan Grove <ryan@wonko.com>
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of this project nor the names of its contributors may be
14
+ # used to endorse or promote products derived from this software without
15
+ # specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ module Thoth; module Helper
30
+
31
+ module Wiki
32
+ private
33
+
34
+ # Parse wiki-style markup into HTML markup.
35
+ def wiki_to_html(string)
36
+ # [[page_name|link text]]
37
+ string.gsub!(/\[\[([0-9a-z_-]+)\|(.+?)\]\]/i) do
38
+ PageController.a($2, :/, $1.downcase)
39
+ end
40
+
41
+ # [[page_name]]
42
+ string.gsub!(/\[\[([0-9a-z_-]+)\]\]/i) do
43
+ PageController.a($1, :/, $1.downcase)
44
+ end
45
+
46
+ # [[@post_name|link text]]
47
+ # [[@123|link text]]
48
+ string.gsub!(/\[\[@(\d+|[0-9a-z_-]+)\|(.+?)\]\]/i) do
49
+ PostController.a($2, :/, $1.downcase)
50
+ end
51
+
52
+ # [[@post_name]]
53
+ # [[@123]]
54
+ string.gsub!(/\[\[@(\d+|[0-9a-z_-]+)\]\]/i) do
55
+ PostController.a($1, :/, $1.downcase)
56
+ end
57
+
58
+ # [[media:filename|link text]]
59
+ string.gsub!(/\[\[media:([^\]]+)\|(.+?)\]\]/i) do
60
+ MediaController.a($2, :/, $1)
61
+ end
62
+
63
+ # [[media:filename]]
64
+ string.gsub!(/\[\[media:([^\]]+)\]\]/i) do
65
+ MediaController.a($1, :/, $1)
66
+ end
67
+
68
+ # [[media_url:filename]]
69
+ string.gsub!(/\[\[media_url:([^\]]+)\]\]/i) do
70
+ MediaController.r(:/, $1).to_s
71
+ end
72
+
73
+ string
74
+ end
75
+ end
76
+
77
+ end; end
@@ -0,0 +1,89 @@
1
+ #--
2
+ # Copyright (c) 2009 Ryan Grove <ryan@wonko.com>
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of this project nor the names of its contributors may be
14
+ # used to endorse or promote products derived from this software without
15
+ # specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ require 'cgi'
30
+ require 'json'
31
+ require 'open-uri'
32
+
33
+ module Thoth; module Helper
34
+
35
+ # The YSearch helper provides search results using the Yahoo! Search API.
36
+ # Requires the json or json_pure gem.
37
+ module Ysearch
38
+ class SearchError < Thoth::Error; end
39
+
40
+ # Yahoo! Developer API key. Feel free to replace this with your own key.
41
+ API_ID = 'pNi6xQDV34FbvnO3QRfWKSByhmPFG.3fVS_R2KzOhMek3szHWKNBrTsdi1mob2vZgKjLoLuZ4A--'
42
+
43
+ # Yahoo! Search API URL.
44
+ API_URL = 'http://search.yahooapis.com/WebSearchService/V1/webSearch'
45
+
46
+ private
47
+
48
+ # Performs a web search using the Yahoo! Search API and returns the results
49
+ # as a Hash. For details on the available options, see
50
+ # http://developer.yahoo.com/search/web/V1/webSearch.html
51
+ def yahoo_search(query, options = {})
52
+ options = {:format => 'html'}.merge(options).collect{|key, val|
53
+ "#{key.to_s}=#{::CGI.escape(val.to_s)}"}.join('&')
54
+
55
+ request = "#{API_URL}?appid=#{API_ID}&query=#{::CGI.escape(query)}&" +
56
+ options + '&output=json'
57
+
58
+ r = JSON.parse(open(request).read)['ResultSet']
59
+
60
+ # Parse the response into a more Rubyish format.
61
+ data = {
62
+ :available => r['totalResultsAvailable'],
63
+ :end => r['totalResultsReturned'] + r['firstResultPosition'] - 1,
64
+ :results => [],
65
+ :start => r['firstResultPosition'],
66
+ :returned => r['totalResultsReturned']
67
+ }
68
+
69
+ r['Result'].each do |result|
70
+ data[:results] << {
71
+ :cache_size => result['Cache'] ? result['Cache']['Size'].to_i : 0,
72
+ :cache_url => result['Cache'] ? result['Cache']['Url'] : '',
73
+ :click_url => result['ClickUrl'],
74
+ :mime => result['MimeType'],
75
+ :modified => Time.at(result['ModificationDate']),
76
+ :summary => result['Summary'],
77
+ :title => result['Title'],
78
+ :url => result['Url']
79
+ }
80
+ end
81
+
82
+ return data
83
+
84
+ rescue => e
85
+ raise SearchError, "Unable to retrieve search results: #{e}"
86
+ end
87
+ end
88
+
89
+ end; end
@@ -0,0 +1,81 @@
1
+ #
2
+ # Pants -> Thoth importer.
3
+ #
4
+
5
+ class PantsImporter < Thoth::Importer
6
+
7
+ before_import do
8
+ unless uri = ARGV.shift
9
+ puts "Please enter a connection string for the Pants database you want to import."
10
+ puts "Example: mysql://user:pass@localhost/dbname"
11
+ print "> "
12
+
13
+ uri = STDIN.gets.strip
14
+ puts
15
+ end
16
+
17
+ begin
18
+ @pants = Sequel.connect(uri)
19
+ rescue => e
20
+ abort("Error: unable to connect to database: #{e}")
21
+ end
22
+ end
23
+
24
+ import_comments do
25
+ @pants[:comments].each do |row|
26
+ Thoth::Comment.create do |comment|
27
+ comment.id = row[:id]
28
+ comment.author = row[:author]
29
+ comment.author_url = row[:url]
30
+ comment.title = row[:title]
31
+ comment.body = row[:content]
32
+ comment.created_at = row[:posted]
33
+ comment.updated_at = row[:posted]
34
+ comment.post_id = row[:article_id]
35
+ end
36
+ end
37
+ end
38
+
39
+ import_pages do
40
+ @pants[:pages].each do |row|
41
+ Thoth::Page.create do |page|
42
+ page.id = row[:id]
43
+ page.title = row[:title]
44
+ page.name = row[:name]
45
+ page.body = row[:content]
46
+ page.created_at = row[:posted]
47
+ page.updated_at = row[:modified]
48
+ end
49
+ end
50
+ end
51
+
52
+ import_posts do
53
+ @pants[:articles].each do |row|
54
+ Thoth::Post.create do |post|
55
+ post.id = row[:id]
56
+ post.title = row[:title]
57
+ post.body = row[:content]
58
+ post.created_at = row[:posted]
59
+ post.updated_at = row[:modified]
60
+ end
61
+ end
62
+ end
63
+
64
+ import_tags do
65
+ @pants[:tags].each do |tag|
66
+ Thoth.db[:tags] << {
67
+ :id => tag[:id],
68
+ :name => tag[:name].downcase
69
+ }
70
+ end
71
+
72
+ @pants[:tags_articles_map].each do |tagmap|
73
+ Thoth.db[:tags_posts_map] << {
74
+ :id => tagmap[:id],
75
+ :tag_id => tagmap[:tag_id],
76
+ :post_id => tagmap[:article_id]
77
+ }
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,54 @@
1
+ #
2
+ # Poseidon 0.3 -> Thoth importer.
3
+ #
4
+
5
+ class PoseidonImporter < Thoth::Importer
6
+
7
+ before_import do
8
+ unless uri = ARGV.shift
9
+ puts "Please enter a connection string for the Poseidon database you want to import."
10
+ puts "Example: mysql://user:pass@localhost/dbname"
11
+ print "> "
12
+
13
+ uri = STDIN.gets.strip
14
+ puts
15
+ end
16
+
17
+ begin
18
+ @poseidon = Sequel.connect(uri)
19
+ rescue => e
20
+ abort("Error: unable to connect to database: #{e}")
21
+ end
22
+ end
23
+
24
+ import_comments do
25
+ @poseidon[:comments].all do |row|
26
+ user = @poseidon[:users].filter(:id => row[:userid]).first
27
+
28
+ Thoth::Comment.create do |comment|
29
+ comment.id = row[:id]
30
+ comment.author = user[:username]
31
+ comment.author_url = ''
32
+ comment.title = row[:title]
33
+ comment.body = row[:content]
34
+ comment.created_at = Time.at(row[:posted])
35
+ comment.updated_at = Time.at(row[:posted])
36
+ comment.ip = row[:ip]
37
+ comment.post_id = row[:contentid]
38
+ end
39
+ end
40
+ end
41
+
42
+ import_posts do
43
+ @poseidon[:content].each do |row|
44
+ Thoth::Post.create do |post|
45
+ post.id = row[:id]
46
+ post.title = row[:title]
47
+ post.body = row[:content]
48
+ post.created_at = Time.at(row[:posted])
49
+ post.updated_at = Time.at(row[:posted])
50
+ end
51
+ end
52
+ end
53
+
54
+ end