pastehub 0.2.6 → 0.4.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.
@@ -1,66 +0,0 @@
1
- #
2
- # macosx.rb - PasteHub's clipboard sync thread for MacOS X
3
- #
4
- # Copyright (c) 2009-2011 Kiyoka Nishiyama <kiyoka@sumibi.org>
5
- #
6
- # Redistribution and use in source and binary forms, with or without
7
- # modification, are permitted provided that the following conditions
8
- # are met:
9
- #
10
- # 1. Redistributions of source code must retain the above copyright
11
- # notice, this list of conditions and the following disclaimer.
12
- #
13
- # 2. Redistributions in binary form must reproduce the above copyright
14
- # notice, this list of conditions and the following disclaimer in the
15
- # documentation and/or other materials provided with the distribution.
16
- #
17
- # 3. Neither the name of the authors nor the names of its contributors
18
- # may be used to endorse or promote products derived from this
19
- # software without specific prior written permission.
20
- #
21
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27
- # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
- # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
- #
33
- #
34
-
35
- module PasteHub
36
-
37
- class MacOSX
38
-
39
- def self.push( data )
40
- pbcopy = "/usr/bin/pbcopy"
41
- if File.exist?( pbcopy )
42
- begin
43
- IO.popen(pbcopy, "r+") {|io|
44
- io.write data
45
- io.close
46
- }
47
- STDERR.puts "Info: push to MacOS X clipboard."
48
- rescue IOError => e
49
- STDERR.puts( "Error: program #{pbcopy} not found." )
50
- return false
51
- end
52
- end
53
- end
54
-
55
- def self.hasNew?( username )
56
- osxPaste = open( "|/usr/bin/pbpaste" ) { |f|
57
- f.read
58
- }
59
- if 0 < osxPaste.size
60
- osxPaste
61
- else
62
- nil
63
- end
64
- end
65
- end
66
- end
@@ -1,213 +0,0 @@
1
- #
2
- # masterdb.rb - PasteHub's master database manager
3
- #
4
- # Copyright (c) 2009-2011 Kiyoka Nishiyama <kiyoka@sumibi.org>
5
- #
6
- # Redistribution and use in source and binary forms, with or without
7
- # modification, are permitted provided that the following conditions
8
- # are met:
9
- #
10
- # 1. Redistributions of source code must retain the above copyright
11
- # notice, this list of conditions and the following disclaimer.
12
- #
13
- # 2. Redistributions in binary form must reproduce the above copyright
14
- # notice, this list of conditions and the following disclaimer in the
15
- # documentation and/or other materials provided with the distribution.
16
- #
17
- # 3. Neither the name of the authors nor the names of its contributors
18
- # may be used to endorse or promote products derived from this
19
- # software without specific prior written permission.
20
- #
21
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27
- # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
- # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
- #
33
- #
34
- require 'dynamoid'
35
- require 'date'
36
-
37
- module PasteHub
38
-
39
- # fake DynamoDB on localhost
40
- Dynamoid.configure do |conf|
41
- config = PasteHub::Config.instance
42
- conf.adapter = 'aws_sdk'
43
- conf.namespace = config.domain # To namespace tables created by Dynamoid from other tables you might have.
44
- conf.warn_on_scan = config.awsWarn # Output a warning to the logger when you perform a scan rather than a query on a table.
45
- conf.partitioning = false # Spread writes randomly across the database. See "partitioning" below for more.
46
- conf.partition_size = 1 # Determine the key space size that writes are randomly spread across.
47
- conf.read_capacity = 1 # Read capacity for your tables
48
- conf.write_capacity = 1 # Write capacity for your tables
49
- conf.access_key = config.dynamoAccessKey # If connecting to DynamoDB, your access key is required.
50
- conf.secret_key = config.dynamoSecretKey # So is your secret key.
51
- conf.endpoint = config.dynamoEp # Set the regional endpoint
52
- conf.port = '443' # Use real dynamo
53
- if not config.aws
54
- conf.endpoint = 'localhost' # Set the regional endpoint
55
- conf.use_ssl = false # Don't use SSL
56
- conf.port = '4567' # Use fake_dynamo
57
- end
58
- end
59
-
60
- class User
61
- include Dynamoid::Document
62
-
63
- table :name => :users, :key => :username
64
-
65
- field :username
66
- field :secretKey
67
- field :created_datetime, :datetime
68
- field :touched_datetime, :datetime
69
- #field :friends, :set
70
-
71
- # index :username
72
-
73
- validates_presence_of :username
74
- validates_presence_of :secretKey
75
- end
76
-
77
- class Entry
78
- include Dynamoid::Document
79
-
80
- table :name => :entries, :key => :userkey
81
-
82
- field :userkey
83
- field :username
84
- # field :comment
85
- # field :from
86
- # field :to
87
- # field :cc
88
- # field :type
89
- field :data
90
-
91
- index [:username]
92
-
93
- validates_presence_of :userkey
94
- # validates_presence_of :data
95
-
96
- def id
97
- userkey
98
- end
99
- end
100
-
101
-
102
- class Users
103
- def addUser( username, secretKey )
104
- user = User.new( :username => username, :secretKey => secretKey, :created_datetime => DateTime.new())
105
- user.save
106
- end
107
-
108
- def updateSecretKey( username, secretKey )
109
- arr = User.where( :username => username ).all
110
- if 0 < arr.size
111
- arr.first.secretKey = secretKey
112
- arr.first.save
113
- true
114
- else
115
- false
116
- end
117
- end
118
-
119
- def getSecretKey( username )
120
- arr = User.where( :username => username ).all
121
- if 0 < arr.size
122
- arr.first.secretKey
123
- else
124
- nil
125
- end
126
- end
127
-
128
- def touch( username )
129
- arr = User.where( :username => username ).all
130
- if 0 < arr.size
131
- arr.first.touched_datetime = DateTime.new()
132
- arr.first.save
133
- true
134
- else
135
- nil
136
- end
137
- end
138
-
139
- def getList()
140
- arr = User.all
141
- arr.map { |x| x.username }.sort
142
- end
143
-
144
- def __deleteUser( username )
145
- user = User.find( username )
146
- if user
147
- user.delete
148
- true
149
- else
150
- false
151
- end
152
- end
153
-
154
- end
155
-
156
-
157
- class Entries
158
- def initialize( username )
159
- @holdUsername = username
160
- end
161
-
162
- def getList( limit = nil )
163
- arr = Entry.where( :username => @holdUsername ).map {|x|
164
- # remove username from `userkey'
165
- field = x.userkey.split( /::/ )
166
- field[1]
167
- }.sort {|a,b| -(a <=> b) }
168
- if limit
169
- arr.take( limit )
170
- else
171
- arr
172
- end
173
- end
174
-
175
- def getValue( key, fallback = false )
176
- p "username=#{@holdUsername}"
177
- p "key=#{key}"
178
- entry = Entry.find( @holdUsername + "::" + key, :consistent_read => true )
179
- if entry
180
- if entry.data
181
- entry.data.force_encoding("UTF-8")
182
- end
183
- else
184
- fallback
185
- end
186
- end
187
-
188
- def insertValue( key, value )
189
- entry = Entry.new( :username => @holdUsername,
190
- :userkey => @holdUsername + "::" + key,
191
- :data => value.force_encoding("UTF-8") )
192
- entry.save
193
- end
194
-
195
- def deleteLast( )
196
- arr = getList( )
197
- if 0 < arr.size
198
- deleteValue( arr[arr.size-1] )
199
- end
200
- end
201
-
202
- def deleteValue( key )
203
- # caution: This method is non consistent read.
204
- entry = Entry.find( @holdUsername + "::" + key )
205
- if entry
206
- entry.delete
207
- true
208
- else
209
- false
210
- end
211
- end
212
- end
213
- end
@@ -1,141 +0,0 @@
1
- require 'vertx'
2
- require 'json/pure'
3
- require 'cgi'
4
- require 'date'
5
- require 'memcache'
6
-
7
- $LOAD_PATH.push( File.dirname(__FILE__) + "/../lib" )
8
- require 'pastehub'
9
- require 'pastehub/log'
10
- PasteHub::Config.instance.loadServer
11
-
12
- # display config info
13
- ins = PasteHub::Config.instance
14
- printf( "Use AWS: %s\n", ins.aws )
15
- printf( "Domain: %s\n", ins.domain )
16
- printf( "Dynamo Endpoint: %s\n", ins.dynamoEp )
17
- printf( "Memcache Endpoint: %s\n", ins.memcacheEp )
18
-
19
- # initialize master database
20
- require 'pastehub/masterdb'
21
-
22
-
23
- # setup user table for Fake DynamoDB
24
- users = PasteHub::Users.new( )
25
- if not ins.aws
26
- open( "/var/pastehub/users.tsv", "r" ) {|f|
27
- f.readlines.each { |line|
28
- pair = line.chomp.split( /[\t ]+/ )
29
- printf( "Added local user table: %s\n", pair[0] )
30
- users.addUser( pair[0], pair[1] )
31
- }
32
- }
33
- end
34
-
35
-
36
- notifyHash = Memcache.new( :server => PasteHub::Config.instance.memcacheEp )
37
-
38
- masterdb_server = Vertx::HttpServer.new
39
- masterdb_server.request_handler do |req|
40
-
41
- req.body_handler do |body|
42
- util = PasteHub::Util.new
43
- auth = PasteHub::AuthForServer.new( users )
44
- ret = auth.invoke( req.headers, util.currentSeconds() )
45
- username = ret[1]
46
-
47
- log = PasteHub::Log.new( :api => req.path, :user => username )
48
- if ret[0]
49
- log.info( "connected" )
50
- else
51
- log.error( 'Auth failure:' + ret[2].to_s, { :reason => ret[2].to_s } )
52
- req.response.status_code = 403
53
- req.response.status_message = "Authorization failure."
54
- req.response.end
55
- return
56
- end
57
-
58
- entries = PasteHub::Entries.new( username )
59
- users = PasteHub::Users.new( )
60
-
61
- case req.path
62
- when "/authTest"
63
- req.response.end
64
-
65
- when "/putValue"
66
- data = body.to_s.dup
67
- digest = util.digest( data )
68
-
69
- # update db
70
- key = req.headers[ 'X-Pastehub-Key' ].dup
71
- puts "[#{username}]:putValue: key=[#{key}] "
72
-
73
- # client have no specified key
74
- if "_" == key
75
- key = util.currentTime( ) + "=" + digest
76
- end
77
-
78
- # data duplicate check
79
- insertFlag = true
80
- prevKey = notifyHash.get( username )
81
- if prevKey
82
- if util.key_digest( prevKey ) == digest
83
- log.info( "canceled because data is duplicate. ", { :key => key } )
84
- insertFlag = false
85
- key = prevKey
86
- end
87
- end
88
-
89
- if insertFlag
90
- Vertx.set_timer(1000) do
91
- log.info( "START: delayed job." )
92
- # update db
93
- log.info( "insert", { :key => key } )
94
- entries.insertValue( key, data )
95
- users.touch( username )
96
- # notify to client
97
- notifyHash.set( username, key, PasteHub::Config.instance.keyCacheTime )
98
-
99
- # remove Last entry
100
- arr = entries.getList( )
101
- if PasteHub::Config.instance.listItems < arr.size
102
- entries.deleteValue( arr[arr.size-1] )
103
- end
104
- log.info( "END: delayed job", { :entries => arr.size } )
105
- end
106
- end
107
- req.response.end( key )
108
-
109
-
110
- when "/getList"
111
- limit = req.headers[ 'X-Pastehub-Limit' ]
112
- if limit
113
- str = entries.getList( ).take( limit.to_i ).join( "\n" )
114
- else
115
- str = entries.getList( ).join( "\n" )
116
- end
117
- log.info( "getList", { :limit => limit, :entries => entries.getList( ).size } )
118
- puts str
119
- req.response.end( str )
120
-
121
- when "/getValue"
122
- k = body.to_s.chomp
123
- if 0 < k.size
124
- str = entries.getValue( k.dup )
125
- else
126
- str = ""
127
- end
128
- log.info( "getValue", { :key => k } )
129
- puts "[#{username}]:getValue:" + k
130
- req.response.end( str )
131
-
132
- else
133
- mes = "Error: Unknown API #{req.path}"
134
- log.error( mes )
135
- req.response.status_code = 400
136
- req.response.status_message = mes
137
- req.response.end
138
-
139
- end
140
- end
141
- end.listen(8000)
@@ -1,89 +0,0 @@
1
- require 'vertx'
2
- require 'cgi'
3
- require 'memcache'
4
- require 'pp'
5
- $LOAD_PATH.push( File.dirname(__FILE__) + "/../lib" )
6
- require 'pastehub'
7
- require 'pastehub/log'
8
- PasteHub::Config.instance.loadServer
9
-
10
- # display config info
11
- ins = PasteHub::Config.instance
12
- printf( "Use AWS: %s\n", ins.aws )
13
- printf( "Domain: %s\n", ins.domain )
14
- printf( "Dynamo Endpoint: %s\n", ins.dynamoEp )
15
- printf( "Memcache Endpoint: %s\n", ins.memcacheEp )
16
- printf( "ssl keystore file: %s\n", ins.keystore )
17
-
18
- # initialize master database
19
- require 'pastehub/masterdb'
20
-
21
- # setup user table for Fake DynamoDB
22
- users = PasteHub::Users.new( )
23
- if not ins.aws
24
- open( "/var/pastehub/users.tsv", "r" ) {|f|
25
- f.readlines.each { |line|
26
- pair = line.chomp.split( /[\t ]+/ )
27
- printf( "Added local user table: %s\n", pair[0] )
28
- users.addUser( pair[0], pair[1] )
29
- }
30
- }
31
- end
32
-
33
-
34
- INTERVAL = 0.5
35
- POLLING_SEC = 60
36
-
37
- notifyHash = Memcache.new( :server => PasteHub::Config.instance.memcacheEp )
38
-
39
- def notify( res, str )
40
- res.write_str( "#{str}\n" )
41
- end
42
-
43
- notifier = Vertx::HttpServer.new
44
- if ins.keystore
45
- notifier.ssl = true
46
- notifier.key_store_path = ins.keystore
47
- notifier.key_store_password = ins.keystorePassword
48
- end
49
-
50
- notifier.request_handler do |req|
51
- util = PasteHub::Util.new
52
- auth = PasteHub::AuthForServer.new( users )
53
-
54
- ret = auth.invoke( req.headers, util.currentSeconds() )
55
- username = ret[1]
56
- # Now send back a response
57
- req.response.chunked = true
58
-
59
- log = PasteHub::Log.new( :api => 'notifier', :user => username )
60
- if ret[0]
61
- log.info( "connected" )
62
- else
63
- log.error( 'Auth failure:' + ret[2].to_s, { :reason => ret[2].to_s } )
64
- req.response.status_code = 403
65
- req.response.status_message = "Authorization failure."
66
- req.response.end
67
- return
68
- end
69
-
70
- got = nil
71
- timer_count = 0
72
-
73
- Vertx::set_periodic (1000 * INTERVAL) { |timer_id|
74
- timer_count += INTERVAL
75
- if notifyHash[ username ]
76
- if got != notifyHash[ username ]
77
- got = notifyHash[ username ]
78
- log.info( 'notify', { :notify => got } )
79
- notify( req.response, got )
80
- end
81
- end
82
-
83
- if ( POLLING_SEC < timer_count )
84
- log.info( 'timeout', { :notify => nil } )
85
- req.response.end
86
- Vertx::cancel_timer(timer_id)
87
- end
88
- }
89
- end.listen(8001)