pastejour 1.1.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/CHANGELOG.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ === 1.0.0 (2009-02-27)
2
+
3
+ * Birthday!
data/Manifest.txt ADDED
@@ -0,0 +1,9 @@
1
+ CHANGELOG.rdoc
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ bin/pastejour
6
+ lib/pastejour.rb
7
+ lib/pastejour/cli.rb
8
+ lib/pastejour/version.rb
9
+ test/pastejour/cli_test.rb
data/README.rdoc ADDED
@@ -0,0 +1,64 @@
1
+ = Pastejour
2
+
3
+ Broadcast standard out using Bonjour.
4
+
5
+ == Examples
6
+
7
+ alice$ git diff | pastejour
8
+ bob$ pastejour alice
9
+
10
+ alice$ git diff | pastejour bob
11
+ bob$ pastejour
12
+
13
+ alice$ git diff | pastejour monkeys
14
+ bob$ pastejour alice-monkeys
15
+
16
+ alice$ git diff | pastejour monkeys
17
+ bob$ pastejour -f
18
+ Searching for servers (3 seconds)
19
+ alice-monkeys
20
+
21
+ # Copy the clipboard contents from one machine to another
22
+ alice$ pbpaste | pastejour bob
23
+ bob$ pastejour | pbcopy
24
+
25
+ == ORLY?
26
+
27
+ Yup. Pastejour gives you a simple, discoverable pipe for standard in
28
+ and out. By default, Pastejour will only stay up until the first
29
+ person grabs your paste. If you want to let a bunch of people grab the
30
+ same thing, shoot it out in multiple mode:
31
+
32
+ alice$ git diff | pastejour -m # keeps on serving 'til you CTRL-C
33
+
34
+ == Awesome!
35
+
36
+ You know it.
37
+
38
+ == Installation
39
+
40
+ $ sudo gem install pastejour
41
+
42
+ == License
43
+
44
+ Copyright 2008 - 2009 John Barnette (jbarnette@rubyforge.org), Evan
45
+ Phoenix (evan@fallingsnow.net)
46
+
47
+ Permission is hereby granted, free of charge, to any person obtaining
48
+ a copy of this software and associated documentation files (the
49
+ 'Software'), to deal in the Software without restriction, including
50
+ without limitation the rights to use, copy, modify, merge, publish,
51
+ distribute, sublicense, and/or sell copies of the Software, and to
52
+ permit persons to whom the Software is furnished to do so, subject to
53
+ the following conditions:
54
+
55
+ The above copyright notice and this permission notice shall be
56
+ included in all copies or substantial portions of the Software.
57
+
58
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
59
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
60
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
61
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
62
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
63
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
64
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "rubygems"
2
+ require "hoe"
3
+
4
+ require "./lib/pastejour/version.rb"
5
+
6
+ Hoe.new "pastejour", Pastejour::VERSION do |p|
7
+ p.developer "John Barnette", "jbarnette@rubyforge.org"
8
+
9
+ p.url = "http://github.com/jbarnette/pastejour"
10
+ p.history_file = "CHANGELOG.rdoc"
11
+ p.readme_file = "README.rdoc"
12
+ p.extra_rdoc_files = [p.readme_file]
13
+ p.need_tar = false
14
+ p.test_globs = %w(test/**/*_test.rb)
15
+ p.testlib = :minitest
16
+
17
+ p.extra_deps << "dnssd"
18
+ end
data/bin/pastejour ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "pastejour/cli"
4
+
5
+ opts = Pastejour::Cli.new STDOUT, ARGV
6
+
7
+ if opts.run?
8
+ if opts.list?
9
+ Pastejour.list
10
+ elsif $stdin.tty?
11
+ name = /#{ENV["USER"]}$/ if opts.name.nil? || opts.name.empty?
12
+ $stdout.write Pastejour.get(name)
13
+ $stdout.flush
14
+ else
15
+ name = [ENV["USER"], opts.name].compact.join "-"
16
+ contents = $stdin.read
17
+ Pastejour.serve name, opts.multiple?, contents
18
+ $stdout.puts contents if opts.tee?
19
+ end
20
+ end
@@ -0,0 +1,68 @@
1
+ require "optparse"
2
+ require "pastejour"
3
+ require "pastejour/version"
4
+
5
+ module Pastejour
6
+ class Cli
7
+ attr_reader :name
8
+
9
+ def initialize out, args
10
+ @list = false
11
+ @multiple = false
12
+ @run = true
13
+ @tee = false
14
+ @verbose = false
15
+
16
+ OptionParser.new do |opts|
17
+ opts.separator ""
18
+
19
+ opts.on "--list", "-l", "List available pastes." do
20
+ @list = true
21
+ end
22
+
23
+ opts.on "--help", "-h", "-?", "Show this help." do
24
+ out.puts opts
25
+ @run = false
26
+ end
27
+
28
+ opts.on "--multiple", "-m", "Allow multiple slurps when pasting." do
29
+ @multiple = true
30
+ end
31
+
32
+ opts.on "--tee", "-t", "Tee to STDOUT when pasting." do
33
+ @tee = true
34
+ end
35
+
36
+ opts.on "--version", "-V", "Prints #{Pastejour::VERSION}." do
37
+ out.puts Pastejour::VERSION
38
+ @run = false
39
+ end
40
+
41
+ opts.separator ""
42
+
43
+ opts.parse! args
44
+ @name = args.shift
45
+ end
46
+ end
47
+
48
+ def list?
49
+ @list
50
+ end
51
+
52
+ def multiple?
53
+ @multiple
54
+ end
55
+
56
+ def run?
57
+ @run
58
+ end
59
+
60
+ def tee?
61
+ @tee
62
+ end
63
+
64
+ def verbose?
65
+ @verbose
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,3 @@
1
+ module Pastejour
2
+ VERSION = "1.1.0"
3
+ end
data/lib/pastejour.rb ADDED
@@ -0,0 +1,96 @@
1
+ require "rubygems"
2
+ require "dnssd"
3
+ require "set"
4
+ require "socket"
5
+ require "webrick"
6
+
7
+ Thread.abort_on_exception = true
8
+
9
+ module Pastejour
10
+ include Socket::Constants
11
+
12
+ Paste = Struct.new(:name, :host, :port)
13
+ PORT = 42424
14
+ SERVICE = "_pastejour._tcp"
15
+
16
+ def self.list
17
+ servers = {}
18
+ service = DNSSD.browse(SERVICE) do |reply|
19
+ servers[reply.name] ||= reply
20
+ end
21
+ STDERR.puts "Searching for servers (3 seconds)"
22
+ # Wait for something to happen
23
+ sleep 3
24
+ service.stop
25
+ servers.each { |string,obj|
26
+ name, port = string.split ":"
27
+ STDERR.puts "Found pastejour at '#{name}'"
28
+ }
29
+ end
30
+
31
+ def self.find(name, first=true)
32
+ hosts = Set.new
33
+
34
+ waiting = Thread.current
35
+
36
+ service = DNSSD.browse(SERVICE) do |reply|
37
+ if name === reply.name
38
+ DNSSD.resolve(reply.name, reply.type, reply.domain) do |rr|
39
+ hosts << Paste.new(reply.name, rr.target, rr.port)
40
+ waiting.run if first
41
+ end
42
+ end
43
+ end
44
+
45
+ sleep 5
46
+ service.stop
47
+
48
+ hosts
49
+ end
50
+
51
+ def self.get(name)
52
+ hosts = find(name)
53
+
54
+ if hosts.empty?
55
+ STDERR.puts "ERROR: Unable to find #{name}"
56
+ elsif hosts.size > 1
57
+ STDERR.puts "ERROR: Multiple possibles found:"
58
+ hosts.each do |host|
59
+ STDERR.puts " #{host.name} (#{host.host}:#{host.port})"
60
+ end
61
+ else
62
+ # Set is weird. There is no #[] or #at
63
+ hosts.each do |host|
64
+ STDERR.puts "(#{host.name} from #{host.host}:#{host.port})"
65
+ sock = TCPSocket.open host.host, host.port
66
+ return sock.read
67
+ end
68
+ end
69
+ end
70
+
71
+ def self.serve(name, multiple, contents)
72
+ tr = DNSSD::TextRecord.new
73
+ tr["description"] = "A paste."
74
+
75
+ DNSSD.register(name, SERVICE, "local", PORT, tr.encode) do |reply|
76
+ STDERR.puts "Pasting #{name}..."
77
+ end
78
+
79
+ log = WEBrick::Log.new(true) # true fools it
80
+ def log.log(*anything); end # send it to the abyss
81
+
82
+ server = WEBrick::GenericServer.new(:Port => PORT, :Logger => log)
83
+
84
+ %w(INT TERM).each do |signal|
85
+ trap signal do
86
+ server.shutdown
87
+ exit!
88
+ end
89
+ end
90
+
91
+ server.start do |socket|
92
+ socket.print(contents)
93
+ server.shutdown unless multiple
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,24 @@
1
+ require "minitest/unit"
2
+ require "pastejour/cli"
3
+ require "pastejour/version"
4
+
5
+ module Pastejour
6
+ class CliTest < MiniTest::Unit::TestCase
7
+ def pastejour *args
8
+ stdout = StringIO.new
9
+ cli = Cli.new stdout, args
10
+
11
+ [cli, stdout.string]
12
+ end
13
+
14
+ def test_help
15
+ opts, out = pastejour "--help"
16
+ assert !opts.run?, "shouldn't run when asking for help"
17
+ end
18
+
19
+ def test_version
20
+ _, out = pastejour "--version"
21
+ assert_equal Pastejour::VERSION, out.strip
22
+ end
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pastejour
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - John Barnette
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-27 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: dnssd
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.9.0
34
+ version:
35
+ description: ""
36
+ email:
37
+ - jbarnette@rubyforge.org
38
+ executables:
39
+ - pastejour
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - Manifest.txt
44
+ - README.rdoc
45
+ files:
46
+ - CHANGELOG.rdoc
47
+ - Manifest.txt
48
+ - README.rdoc
49
+ - Rakefile
50
+ - bin/pastejour
51
+ - lib/pastejour.rb
52
+ - lib/pastejour/cli.rb
53
+ - lib/pastejour/version.rb
54
+ - test/pastejour/cli_test.rb
55
+ has_rdoc: true
56
+ homepage: http://github.com/jbarnette/pastejour
57
+ post_install_message:
58
+ rdoc_options:
59
+ - --main
60
+ - README.rdoc
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ requirements: []
76
+
77
+ rubyforge_project: pastejour
78
+ rubygems_version: 1.3.1
79
+ signing_key:
80
+ specification_version: 2
81
+ summary: ""
82
+ test_files:
83
+ - test/pastejour/cli_test.rb