pastis 0.0.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 (4) hide show
  1. data/LICENSE +15 -0
  2. data/bin/pastis +73 -0
  3. data/lib/pastis.rb +222 -0
  4. metadata +56 -0
data/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ Copyright (c) 2007 Samuel Lebeau
2
+
3
+ This program is free software; you can redistribute it and/or modify
4
+ it under the terms of the GNU General Public License as published by
5
+ the Free Software Foundation; either version 2 of the License, or
6
+ (at your option) any later version.
7
+
8
+ This program is distributed in the hope that it will be useful,
9
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ GNU General Public License for more details.
12
+
13
+ You should have received a copy of the GNU General Public License
14
+ along with this program; if not, write to the Free Software
15
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
data/bin/pastis ADDED
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'pastis'
4
+ require 'tempfile'
5
+ require 'optparse'
6
+ require 'timeout'
7
+
8
+ language = restricted = edit = nil
9
+
10
+ def version
11
+ "Pastis, version #{Pastis::Version.join('.')}"
12
+ end
13
+
14
+ OptionParser.new do |opts|
15
+ opts.banner = <<END
16
+ #{version}
17
+ Paste the given file or STDIN to Pastie, returns the paste URL.
18
+
19
+ Usage: #{ARGV.first} [options] [file]
20
+ END
21
+
22
+ opts.separator ''
23
+
24
+ opts.separator 'Options:'
25
+
26
+ opts.on('-l', '--language [LANGUAGE]', "Select a language\n\
27
+ (c/diff/html/javascript/nitro_xhtml/pascal/plaintext/rhtml/ruby/sql)") do |l|
28
+ language = l.downcase
29
+ end
30
+ opts.on('-p', '--[no-]private', 'Private paste (default to false)') { |r| restricted = r }
31
+ opts.on('-e', '--[no-]edit', 'Edit the input with $EDITOR (defaults to false)') { |e| edit = e }
32
+
33
+ opts.on_tail('-h', '--help', 'Show this message') do
34
+ puts opts
35
+ exit
36
+ end
37
+
38
+ opts.on_tail('-v', '--version', 'Print Pastis version') do
39
+ puts version
40
+ exit
41
+ end
42
+ end.parse!
43
+
44
+ paste =
45
+ if ARGV.first
46
+ File.read(ARGV.first)
47
+ else
48
+ # detect if there's something from STDIN
49
+ begin
50
+ timeout(0.1) { $stdin.gets } << $stdin.read
51
+ rescue TimeoutError
52
+ end
53
+ end
54
+
55
+ if (!paste || edit)
56
+ Tempfile.open('pastie') do |f|
57
+ f << paste
58
+ f.rewind
59
+ system("#{ENV['EDITOR']} #{f.path}")
60
+ f.rewind
61
+ # Tempfile.open curiously returns 'nil' instead of the last expression
62
+ paste = f.read
63
+ end
64
+ end
65
+
66
+ begin
67
+ puts Pastis.paste(paste, {
68
+ :language => language,
69
+ :private => restricted
70
+ }).url
71
+ rescue Pastis::Error => e
72
+ abort e.message
73
+ end
data/lib/pastis.rb ADDED
@@ -0,0 +1,222 @@
1
+ require 'net/http'
2
+ require 'open-uri'
3
+
4
+ # Load Hpricot on demand
5
+ def Hpricot(object) #:nodoc:
6
+ require 'rubygems'
7
+ require 'hpricot'
8
+ Kernel.send(:Hpricot, object)
9
+ end
10
+
11
+ class Module #:nodoc:
12
+ alias_method :const_missing_without_pastis, :const_missing
13
+
14
+ # Load CGI on demand
15
+ def const_missing(const)
16
+ if const == :CGI
17
+ require 'cgi'
18
+ Module.send(:alias_method, :const_missing, :const_missing_without_pastis)
19
+ CGI
20
+ else
21
+ const_missing_without_pastis(const)
22
+ end
23
+ end
24
+ end
25
+
26
+ #
27
+ # Pastis is a simple ruby interface to Pastie (http://pastie.caboo.se)
28
+ #
29
+ # == Usage
30
+ #
31
+ # paste = Pastis.paste "var some = 'private js code';", :language => :javascript, :private => true
32
+ #
33
+ # paste.url
34
+ # # => "http://pastie.caboo.se/private/lbejcc0royyyyozwl8jbg"
35
+ #
36
+ # paste.raw_url
37
+ # # => "http://pastie.caboo.se/private/lbejcc0royyyyozwl8jbg.txt"
38
+ #
39
+ # paste.body
40
+ # # => "var some = 'private js code';"
41
+ #
42
+ # pages = Pastis.search [a search expression]
43
+ #
44
+ # pages.next_page.last.url
45
+ # # => "http://pastie.caboo.se/pastes/43577"
46
+ module Pastis
47
+ Version = [ 0, 0, 1 ]
48
+
49
+ class Error < RuntimeError; end
50
+ class PasteNotCreatedError < Error; end
51
+ class EmptyPasteError < Error; end
52
+ class PaginationError < Error; end
53
+
54
+ # Represents a paste, shoudn't be created by hand
55
+ class Paste
56
+ def initialize(attributes)
57
+ %w(url body time preview).each do |attribute|
58
+ instance_variable_set("@#{attribute}", attributes[attribute.intern])
59
+ end
60
+ end
61
+
62
+ attr_reader :url
63
+
64
+ # Url of the raw paste
65
+ def raw_url
66
+ "#{url}.txt"
67
+ end
68
+
69
+ # 5 first lines of the paste
70
+ def preview
71
+ @preview ||= body.to_a[0, 6].to_s
72
+ end
73
+
74
+ # Creation time
75
+ def time
76
+ @time ||= Time.parse(Hpricot(get(url)).at("#paste_date").innerText)
77
+ end
78
+
79
+ # Body of the paste
80
+ def body
81
+ @body ||= get(raw_url)
82
+ end
83
+ alias_method :to_s, :body
84
+
85
+ private
86
+
87
+ def get(url)
88
+ Pastis.send(:get, url)
89
+ end
90
+ end
91
+
92
+ # Represents a collection of pastes paginated
93
+ class Collection < Array
94
+ def initialize(page, &block)
95
+ @page, @block = page, block
96
+
97
+ parse_url(yield(page))
98
+ super(@pastes)
99
+ end
100
+
101
+ attr_reader :page, :pages_count
102
+
103
+ def next_page
104
+ raise PaginationError, "last page" if last_page?
105
+ move(page + 1)
106
+ end
107
+ alias_method :next, :next_page
108
+
109
+ def previous_page
110
+ raise PaginationError, "first page" if first_page?
111
+ move(page - 1)
112
+ end
113
+ alias_method :previous, :previous_page
114
+
115
+ def goto_page(page)
116
+ raise PaginationError, "page out of range" unless (1..pages_count).member?(page)
117
+ move(page)
118
+ end
119
+ alias_method :goto, :goto_page
120
+
121
+ def last_page?
122
+ page == pages_count
123
+ end
124
+
125
+ def first_page?
126
+ page == 1
127
+ end
128
+
129
+ private
130
+
131
+ def get(url)
132
+ Pastis.send(:get, url)
133
+ end
134
+
135
+ def move(page)
136
+ Collection.new(page, &@block)
137
+ end
138
+
139
+ def parse_url(url)
140
+ doc = Hpricot(get(url))
141
+
142
+ @pastes = (doc/'.pastePreview').collect do |node|
143
+ Paste.new :time => Time.parse(node.at('.when span').innerText),
144
+ :url => node.at('.link a').attributes['href'],
145
+ :preview => node.at('.code').innerText
146
+ end
147
+
148
+ @pages_count =
149
+ Hpricot((doc/'.pages strong').first.innerText.split(' ').last).innerText.to_i
150
+ end
151
+ end
152
+
153
+ class << self
154
+ def url #:nodoc:
155
+ "http://pastie.caboo.se"
156
+ end
157
+
158
+ # Creates a paste, returns the created Paste object.
159
+ # The options are :
160
+ #
161
+ # * <tt>:language</tt>: The language used in the paste (defaults to Ruby)
162
+ # * <tt>:private</tt>: true if the paste is private (default to false)
163
+ def create(body, options = {})
164
+ raise EmptyPasteError, "Empty paste, not submitted..." unless body =~ /\w/
165
+
166
+ response = post_paste(body, options);
167
+
168
+ raise PasteNotCreatedError, "Error occured : #{response.code}" unless response.code =~ /[23]0\d/
169
+ raise PasteNotCreatedError, "Paste not created" unless response['location']
170
+
171
+ return Paste.new(:body => body, :url => response['location'], :time => Time.now)
172
+ end
173
+ alias_method :paste, :create
174
+
175
+ # Searches some expression on Pastie.
176
+ # Returns a Collection object
177
+ def search(expression, page = 1)
178
+ Collection.new(page) do |page|
179
+ search_url(expression, page)
180
+ end
181
+ end
182
+
183
+ # Lists all pastes.
184
+ # Returns a Collection object
185
+ def list(page = 1)
186
+ Collection.new(page) do |page|
187
+ all_url(page)
188
+ end
189
+ end
190
+ alias_method :all, :list
191
+
192
+ private
193
+
194
+ def post_paste(body, options)
195
+ post(create_url,
196
+ "paste[restricted]" => options[:private] ? '1' : '0',
197
+ "paste[parser]" => options[:language] ? options[:language].to_s.downcase : :ruby,
198
+ "paste[body]" => body,
199
+ "paste[authorization]" => 'burger');
200
+ end
201
+
202
+ def get(url)
203
+ open(url) { |f| f.read }
204
+ end
205
+
206
+ def post(url, parameters = {})
207
+ Net::HTTP.post_form(URI.parse(url), parameters)
208
+ end
209
+
210
+ def create_url
211
+ "#{url}/pastes/create"
212
+ end
213
+
214
+ def search_url(query, page)
215
+ "#{url}/search?q=#{CGI.escape(query.to_s)}&page=#{page}"
216
+ end
217
+
218
+ def all_url(page)
219
+ "#{url}/all/page/#{page}"
220
+ end
221
+ end
222
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: pastis
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-09-25 00:00:00 +02:00
8
+ summary: A simple interface to Pastie
9
+ require_paths:
10
+ - lib
11
+ email: sam@gotfresh.info
12
+ homepage: http://i.gotfresh.info
13
+ rubyforge_project:
14
+ description: Pastis is a simple interface to create, list and search for pastes on Pastie (http://pastie.caboo.se).\n\ It could be used as a library or a standalone binary
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Samuel Lebeau
31
+ files:
32
+ - LICENSE
33
+ - bin/pastis
34
+ - lib/pastis.rb
35
+ test_files: []
36
+
37
+ rdoc_options: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ executables:
42
+ - pastis
43
+ extensions: []
44
+
45
+ requirements: []
46
+
47
+ dependencies:
48
+ - !ruby/object:Gem::Dependency
49
+ name: hpricot
50
+ version_requirement:
51
+ version_requirements: !ruby/object:Gem::Version::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0.6"
56
+ version: