hubeye 0.3.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,767 +0,0 @@
1
- require "log/logger"
2
- include Log
3
-
4
- class Hubeye
5
-
6
- # simple interface to Github's api v3 for commits
7
- class Commit
8
- attr_reader :raw_input, :repo, :only_sha, :latest
9
- def initialize(input)
10
- @raw_input = input
11
- @repo = input.keys.first
12
- if Hash === input
13
- if input[@repo].keys == ["sha"]
14
- @only_sha = true
15
- else
16
- @latest = true
17
- end
18
- else
19
- raise ArgumentError.new "input must be a kind of hash"
20
- end
21
- end
22
-
23
- def sha
24
- @sha ||= @raw_input[@repo]['sha']
25
- end
26
-
27
- def commit_message
28
- if @only_sha
29
- return
30
- elsif @latest
31
- @commit_message ||= @raw_input[@repo]['commit']['message']
32
- else
33
- raise
34
- end
35
- end
36
-
37
- def committer_name
38
- if @only_sha
39
- return
40
- elsif @latest
41
- @committer_name ||= @raw_input[@repo]['commit']['committer']['name']
42
- else
43
- raise
44
- end
45
- end
46
- end
47
-
48
- module Server
49
- attr_accessor :remote_connection
50
- attr_reader :socket, :sockets, :session, :daemonized
51
-
52
- # standard lib.
53
- require 'socket'
54
- require 'yaml'
55
- require 'json'
56
- require 'open-uri'
57
- # hubeye
58
- require "config/parser"
59
- require "notification/finder"
60
- require "hooks/git_hooks"
61
- require "hooks/executer"
62
- require "helpers/time"
63
- include Helpers::Time
64
-
65
- CONFIG_FILE = File.join(ENV['HOME'], ".hubeye", "hubeyerc")
66
- CONFIG = {}
67
- # find Desktop notification system
68
-
69
- # CONFIG options: defined in ~/.hubeye/hubeyerc
70
- #
71
- # Option overview:
72
- #
73
- # CONFIG[:oncearound]: 60 (seconds) is the default amount of time for looking
74
- # for changes in every single repository. If tracking lots of repos,
75
- # it might be a good idea to increase the value, or hubeye will cry
76
- # due to overwork, fatigue and general anhedonia.
77
- #
78
- # hubeyerc format => oncearound: 1000
79
- #
80
- # CONFIG[:username] is the username used when not specified.
81
- # hubeyerc format => username: 'hansolo'
82
- # when set to 'hansolo'
83
- # >rails
84
- # would track https://www.github.com/hansolo/rails
85
- # but a full URI path won't use CONFIG[:username]
86
- # >rails/rails
87
- # would track https://www.github.com/rails/rails
88
- Config::Parser.new(CONFIG_FILE) do |c|
89
- CONFIG[:username] = c.username ||
90
- `git config --get-regexp github`.split(' ').last
91
- CONFIG[:oncearound] = c.oncearound || 60
92
- CONFIG[:load_repos] = c.load_repos || []
93
- CONFIG[:load_hooks] = c.load_hooks || []
94
- CONFIG[:default_track] = c.default_track || nil
95
-
96
- CONFIG[:notification_wanted] = if c.notification_wanted.nil?
97
- true
98
- else
99
- c.notification_wanted
100
- end
101
- end
102
-
103
- CONFIG[:desktop_notification] = Notification::Finder.find_notify if
104
- CONFIG[:notification_wanted]
105
-
106
- class Strategy
107
- UnknownStrategy = Class.new(StandardError)
108
- attr_reader :server, :input
109
-
110
- def initialize(server, options={})
111
- @server = server
112
- opts = {:internal_input => nil}.merge options
113
- if !opts[:internal_input]
114
- @input = server.socket.gets
115
- # check if the client pressed ^C or ^D
116
- if @input.nil?
117
- @server.remote_connection = false
118
- throw(:invalid_input)
119
- end
120
- @input.chop!
121
- else
122
- @input = opts[:internal_input]
123
- end
124
- unless @input
125
- Logger.log "Client on #{@server.socket.peeraddr[2]} disconnected."
126
- @server.sockets.delete(socket)
127
- @server.socket.close
128
- return
129
- end
130
- @input = @input.strip.downcase
131
- @input.gsub! /diiv/, '/'
132
- end
133
-
134
- STRATEGY_CLASSES = [ "Shutdown", "Exit", "SaveHook", "SaveRepo",
135
- "LoadHook", "LoadRepo", "AddHook", "ListHooks", "ListTracking",
136
- "Next", "RmRepo", "AddRepo" ]
137
-
138
-
139
- STRATEGY_CLASSES.each do |klass_str|
140
- binding.eval "class #{klass_str}; end"
141
- klass = const_get klass_str.intern
142
- klass.class_eval do
143
- def initialize matches, strategy, options={}
144
- @options = options
145
- @matches = matches
146
- @server = strategy.server
147
- @input = strategy.input
148
- @socket = @server.socket
149
- @sockets = @server.sockets
150
- @session = @server.session
151
- call
152
- end
153
- end
154
- end
155
-
156
- # strategy classes
157
- class Exit
158
- def call
159
- @socket.puts "Bye!"
160
- # mark the session as continuous to not wipe the log file
161
- @session.continuous = true
162
- Logger.log "Closing connection to #{@socket.peeraddr[2]}"
163
- @server.remote_connection = false
164
- if !@session.tracker.empty?
165
- Logger.log "Tracking: #{@session.tracker.keys.join ', '}"
166
- end
167
- # to look pretty when multiple connections per loop
168
- Logger.log ""
169
- @sockets.delete(@socket)
170
- @socket.close
171
- end
172
- end
173
-
174
- class Shutdown
175
- def call
176
- Logger.log "Closing connection to #{@socket.peeraddr[2]}"
177
- Logger.log "Shutting down... (#{::Hubeye::Server::NOW})"
178
- Logger.log ""
179
- Logger.log ""
180
- @socket.puts("Shutting down server")
181
- @sockets.delete(@socket)
182
- @socket.close
183
- unless @server.daemonized
184
- STDOUT.puts "Shutting down gracefully."
185
- end
186
- exit 0
187
- end
188
- end
189
-
190
- class SaveHook
191
- def call
192
- hooks = @session.hooks
193
- if !hooks.empty?
194
- file = "#{ENV['HOME']}/.hubeye/hooks/#{@matches[2]}.yml"
195
- if File.exists? file
196
- override?
197
- end
198
- File.open(file, "w") do |f_out|
199
- ::YAML.dump(hooks, f_out)
200
- end
201
- @socket.puts("Saved hook#{@matches[1]} as #{@matches[2]}")
202
- else
203
- @socket.puts("No hook#{@matches[1]} to save")
204
- end
205
- end
206
-
207
- private
208
- def override?
209
- end
210
- end
211
-
212
- class SaveRepo
213
- def call
214
- if !@session.tracker.empty?
215
- file = "#{ENV['HOME']}/.hubeye/repos/#{@matches[2]}.yml"
216
- if File.exists? file
217
- override?
218
- end
219
- # dump only the repository names, not the shas
220
- File.open(file, "w") do |f_out|
221
- ::YAML.dump(@session.tracker.keys, f_out)
222
- end
223
- @socket.puts("Saved repo#{@matches[1]} as #{@matches[2]}")
224
- else
225
- @socket.puts("No remote repos are being tracked")
226
- end
227
- end
228
-
229
- private
230
- def override?
231
- end
232
- end
233
-
234
- class LoadHook
235
- def call
236
- if @options[:internal]
237
- @silent = @options[:internal]
238
- end
239
- hookfile = "#{ENV['HOME']}/.hubeye/hooks/#{@matches[2]}.yml"
240
- new_hooks = nil
241
- if File.exists?(hookfile)
242
- File.open(hookfile) do |f|
243
- new_hooks = ::YAML.load(f)
244
- end
245
- @session.hooks.merge!(new_hooks)
246
- unless @silent
247
- @socket.puts("Loaded #{@matches[1]} #{@matches[2]}")
248
- end
249
- else
250
- unless @silent
251
- @socket.puts("No #{@matches[1]} file to load from")
252
- end
253
- end
254
- end
255
- end
256
-
257
- class LoadRepo
258
- def call
259
- if @options[:internal]
260
- @silent = @options[:internal]
261
- end
262
- if File.exists?(repo_file = "#{ENV['HOME']}/.hubeye/repos/#{@matches[2]}.yml")
263
- new_repos = nil
264
- File.open(repo_file) do |f|
265
- new_repos = ::YAML.load(f)
266
- end
267
- if !new_repos
268
- @socket.puts "Unable to load #{@matches[2]}: empty file" unless @silent
269
- return
270
- end
271
- new_repos.each do |r|
272
- # add the repo name to the hubeye tracker
273
- commit = @server.track(r)
274
- @session.tracker.add_or_replace!(commit.repo, commit.sha)
275
- end
276
- unless @silent
277
- @socket.puts "Loaded #{@matches[2]}.\nTracking:\n#{@session.tracker.keys.join ', '}"
278
- end
279
- else
280
- @socket.puts("No file to load from") unless @silent
281
- end
282
- end
283
- end
284
-
285
- class AddHook
286
- def call
287
- cwd = File.expand_path('.')
288
- repo = @matches[1]
289
- dir = @matches[3]
290
- cmd = @matches[4]
291
- if repo != nil and cmd != nil
292
- if @session.hooks[repo]
293
- if dir
294
- if @session.hooks[repo][dir]
295
- @session.hooks[repo][dir] << cmd
296
- else
297
- @session.hooks[repo][dir] = [cmd]
298
- end
299
- else
300
- if @session.hooks[repo][cwd]
301
- @session.hooks[repo][cwd] << cmd
302
- else
303
- @session.hooks[repo][cwd] = [cmd]
304
- end
305
- end
306
- else
307
- if dir
308
- @session.hooks[repo] = {dir => [cmd]}
309
- else
310
- @session.hooks[repo] = {cwd => [cmd]}
311
- end
312
- end
313
- @socket.puts("Hook added")
314
- else
315
- @socket.puts("Format: 'hook add user/repo [dir: /my/dir/repo ] cmd: git pull origin'")
316
- end
317
- end
318
- end
319
-
320
- class ListHooks
321
- def call
322
- unless @session.hooks.empty?
323
- pwd = File.expand_path('.')
324
- format_string = ""
325
- @session.hooks.each do |repo, hash|
326
- local_dir = nil
327
- command = nil
328
- hash.each do |dir,cmd|
329
- if dir.nil?
330
- local_dir = pwd
331
- command = cmd.join("\n" + (' ' * 8))
332
- else
333
- command = cmd
334
- local_dir = dir
335
- end
336
- end
337
- format_string << <<EOS
338
- remote: #{repo}
339
- dir: #{local_dir}
340
- cmds: #{command}\n
341
- EOS
342
- end
343
- @socket.puts(format_string)
344
- else
345
- @socket.puts("No hooks")
346
- end
347
- end
348
- end
349
-
350
- class ListTracking
351
- def call
352
- output = ''
353
- if @options[:details]
354
- commit_list = []
355
- @session.tracker.keys.each do |repo|
356
- commit = @server.track(repo, :list => true)
357
- commit_list << commit
358
- end
359
- commit_list.each do |c|
360
- output << c.repo + "\n"
361
- underline = '=' * c.repo.length
362
- output << underline + "\n"
363
- output << c.commit_message + "\n=> " +
364
- c.committer_name + "\n"
365
- output << "\n" unless c.repo == commit_list.last.repo
366
- end
367
- else
368
- output << @session.tracker.keys.join(', ')
369
- end
370
- output = "none" if output.empty?
371
- @socket.puts(output)
372
- end
373
- end
374
-
375
- class Next
376
- def call
377
- @socket.puts("")
378
- end
379
- end
380
-
381
- class RmRepo
382
- def call
383
- if @matches[1].include?("/")
384
- @session.username, @session.repo_name = @matches[1].split('/')
385
- else
386
- @session.repo_name = @matches[1]
387
- end
388
- rm = @session.tracker.delete("#{@session.username}/#{@session.repo_name}")
389
- if rm
390
- @socket.puts("Stopped watching repository #{@session.username}/#{@session.repo_name}")
391
- else
392
- @socket.puts("Repository #{@session.username}/#{@session.repo_name} not currently being watched")
393
- end
394
- end
395
- end
396
-
397
- class AddRepo
398
- def call
399
- if @options and @options[:pwd]
400
- @session.repo_name = File.dirname(File.expand_path('.'))
401
- elsif @options and @options[:fullpath]
402
- @session.username, @session.repo_name = @input.split('/')
403
- else
404
- @session.repo_name = @input
405
- end
406
- add_repo
407
- end
408
-
409
- private
410
- def add_repo
411
- full_repo_name = "#{@session.username}/#{@session.repo_name}"
412
- commit = @server.track(full_repo_name, :latest => true)
413
- new_sha = commit.sha
414
- commit_msg = commit.commit_message
415
- committer = commit.committer_name
416
- msg = "#{commit_msg}\n=> #{committer}"
417
- change = @session.tracker.add_or_replace!(full_repo_name, new_sha)
418
- # new repo to track
419
- if !change
420
- @socket.puts("Repository #{full_repo_name} has not changed")
421
- return
422
- elsif change[:add]
423
- # log the fact that the user added a repo to be tracked
424
- Logger.log("Added to tracker: #{full_repo_name} (#{::Hubeye::Server::NOW})")
425
- # show the user, via the client, the info and commit msg for the commit
426
- @socket.puts(msg)
427
- elsif change[:replace]
428
- change_msg = "New commit on #{full_repo_name}\n"
429
- change_msg << msg
430
- @socket.puts(change_msg)
431
- if @server.daemonized
432
- Logger.log_change(full_repo_name, commit_msg, committer)
433
- else
434
- Logger.log_change(full_repo_name, commit_msg, committer,
435
- :include_terminal => true)
436
- end
437
- end
438
- end
439
- end
440
-
441
- # STRATEGIES hash
442
- # ===============
443
- # keys: input matches
444
- # OR
445
- # lambda {|input| input.something?} => value
446
- #
447
- # values: lambda {|matchdata, basestrategy| SomeStrategy.new(matchdata, basestrategy)}
448
- STRATEGIES = {
449
- %r{\Ashutdown\Z} => lambda {|m, s| Shutdown.new(m, s)},
450
- %r{\Aquit|exit\Z} => lambda {|m, s| Exit.new(m, s)},
451
- %r{\A\s*save hook(s?) as (.+)\Z} => lambda {|m, s| SaveHook.new(m, s)},
452
- %r{\A\s*save repo(s?) as (.+)\Z} => lambda {|m, s| SaveRepo.new(m, s)},
453
- %r{\A\s*load hook(s?) (.+)\Z} => lambda {|m, s| LoadHook.new(m, s)},
454
- %r{\A\s*load repo(s?) (.+)\Z} => lambda {|m, s| LoadRepo.new(m, s)},
455
- %r{\A\s*internal load hook(s?) (.+)\Z} => lambda {|m, s| LoadHook.new(m, s, :internal => true)},
456
- %r{\A\s*internal load repo(s?) (.+)\Z} => lambda {|m, s| LoadRepo.new(m, s, :internal => true)},
457
- %r{\Ahook add ([-\w]+/[-\w]+) (dir:\s?(.*))?\s*cmd:\s?(.*)\Z} => lambda {|m, s| AddHook.new(m, s)},
458
- %r{\Ahook list\Z} => lambda {|m, s| ListHooks.new(m, s)},
459
- %r{\Atracking\s*\Z} => lambda {|m, s| ListTracking.new(m, s)},
460
- %r{\Atracking\s*-d\Z} => lambda {|m, s| ListTracking.new(m, s, :details => true)},
461
- %r{^pwd} => lambda {|m, s| AddRepo.new(m, s, :pwd => true)},
462
- %r{^\s*$} => lambda {|m, s| Next.new(m, s)},
463
- %r{\Arm ([-\w]+/?[-\w]*)\Z} => lambda {|m, s| RmRepo.new(m, s)},
464
- lambda {|inp| inp.include? '/'} => lambda {|m, s| AddRepo.new(m, s, :fullpath => true)},
465
- lambda {|inp| not inp.nil?} => lambda {|m, s| AddRepo.new(m, s)}
466
- }
467
-
468
- def call
469
- STRATEGIES.each do |inp,strat|
470
- if inp.respond_to? :match
471
- if m = @input.match(inp)
472
- return strat.call(m, self)
473
- end
474
- elsif inp.respond_to? :call
475
- if m = inp.call(@input)
476
- return strat.call(m, self)
477
- end
478
- end
479
- end
480
- raise UnknownStrategy
481
- end
482
- end
483
-
484
- class Session
485
- attr_accessor :repo_name, :username, :continuous
486
- attr_writer :tracker, :hooks
487
-
488
- def initialize
489
- setup_singleton_methods
490
- end
491
-
492
- def tracker
493
- @tracker ||= {}
494
- end
495
-
496
- def hooks
497
- @hooks ||= {}
498
- end
499
-
500
- def cleanup
501
- reset_username
502
- reset_repo_name
503
- end
504
-
505
- private
506
- def reset_username
507
- self.username = CONFIG[:username]
508
- end
509
-
510
- def reset_repo_name
511
- self.repo_name = ""
512
- end
513
-
514
- def setup_singleton_methods
515
- tracker.singleton_class.class_eval do
516
- def add_or_replace! repo_name, new_sha=nil
517
- if Hash === repo_name
518
- merge! repo_name
519
- return true
520
- else
521
- if keys.include? repo_name and self[repo_name] == new_sha
522
- return
523
- elsif keys.include? repo_name
524
- ret = {:replace => true}
525
- else
526
- ret = {:add => true}
527
- end
528
- end
529
- merge! repo_name => new_sha
530
- ret
531
- end
532
- end
533
- end
534
- end # end of Session class
535
-
536
- def start(port, options={})
537
- listen(port)
538
- setup_env(options)
539
- loop do
540
- waiting = catch(:connect) do
541
- look_for_changes unless @remote_connection
542
- end
543
- client_connect(@sockets) if waiting
544
- catch(:invalid_input) do
545
- strategy = Strategy.new(self)
546
- strategy.call
547
- end
548
- @session.cleanup
549
- end
550
- end
551
-
552
- # The track method closes over a list variable to store recent info on
553
- # tracked repositories.
554
- # Options: :sha, :latest, :full, :list (all boolean).
555
- # The :list => true option gives back the commit object from the list.
556
-
557
- list = []
558
-
559
- define_method :track do |repo, options={}|
560
- if repo.include? '/'
561
- username, repo_name = repo.split '/'
562
- full_repo_name = repo
563
- else
564
- username, repo_name = @session.username, repo
565
- full_repo_name = "#{username}/#{repo_name}"
566
- end
567
- unless options[:list]
568
- hist = nil
569
- begin
570
- open "https://api.github.com/repos/#{username}/" \
571
- "#{repo_name}/commits" do |f|
572
- hist = JSON.parse f.read
573
- end
574
- rescue
575
- @socket.puts "Not a Github repository name"
576
- throw(:invalid_input)
577
- end
578
- new_info =
579
- {full_repo_name =>
580
- {'sha' => hist.first['sha'],
581
- 'commit' =>
582
- {'message' => hist.first['commit']['message'],
583
- 'committer' => {'name' => hist.first['commit']['committer']['name']}
584
- }
585
- }
586
- }
587
- commit = Commit.new(new_info)
588
- # update the list
589
- list.reject! {|cmt| cmt.repo == full_repo_name}
590
- list << commit
591
- end
592
- if options[:full]
593
- # unsupported so far
594
- raise ArgumentError.new
595
- elsif options[:latest]
596
- commit.dup
597
- elsif options[:list]
598
- list.each {|c| return c if c.repo == full_repo_name}
599
- nil
600
- else
601
- # default
602
- Commit.new full_repo_name => {'sha' => hist.first['sha']}
603
- end
604
- end
605
-
606
- private
607
- def listen(port)
608
- @server = TCPServer.open(port)
609
- end
610
-
611
- def setup_env(options={})
612
- @daemonized = options[:daemon]
613
- @sockets = [@server] # An array of sockets we'll monitor
614
- ['INT', 'KILL'].each do |sig|
615
- trap(sig) do
616
- @sockets.each {|s| s.close}
617
- STDOUT.puts
618
- exit 1
619
- end
620
- end
621
- @session = Session.new
622
- unless CONFIG[:default_track].nil?
623
- CONFIG[:default_track].each do |repo|
624
- commit = track(repo)
625
- @session.tracker.merge! commit.repo => commit.sha
626
- end
627
- end
628
- unless CONFIG[:load_hooks].empty?
629
- hooks = CONFIG[:load_hooks].dup
630
- session_load :hooks => hooks
631
- end
632
- unless CONFIG[:load_repos].empty?
633
- repos = CONFIG[:load_repos].dup
634
- session_load :repos => repos
635
- end
636
- @session.username = CONFIG[:username]
637
- @remote_connection = false
638
- end
639
-
640
- def session_load options={}
641
- opts = {:hooks => nil, :repos => nil}.merge options
642
- if hooks = opts[:hooks]
643
- hooks.each do |h|
644
- strat = Strategy.new(self, :internal_input => "internal load hook #{h}")
645
- strat.call
646
- end
647
- elsif repos = opts[:repos]
648
- repos.each do |r|
649
- strat = Strategy.new(self, :internal_input => "internal load repo #{r}")
650
- strat.call
651
- end
652
- else
653
- raise ArgumentError.new "Must load either hooks or repos"
654
- end
655
- end
656
-
657
- #TODO: refactor this ugly, long method into a new class
658
- def look_for_changes
659
- # if no client is connected, but the commits array contains repos
660
- if @sockets.size == 1 and !@session.tracker.empty?
661
-
662
- loop do
663
- sleep_amt = CONFIG[:oncearound] / @session.tracker.length
664
- @session.tracker.each do |repo,sha|
665
- start_time = Time.now
666
- commit = track(repo, :latest => true)
667
- api_time = (Time.now - start_time).to_i
668
- if commit.sha == sha
669
- (sleep_amt - api_time).times do
670
- sleep 1
671
- @remote_connection = client_ready(@sockets) ? true : false
672
- throw(:connect, true) if @remote_connection
673
- end
674
- else
675
- # There was a change to a tracked repository.
676
- full_repo_name = commit.repo
677
- commit_msg = commit.commit_message
678
- committer = commit.committer_name
679
- new_sha = commit.sha
680
- change_msg = "Repo #{full_repo_name} has changed\nNew commit: " \
681
- "#{commit_msg}\n=> #{committer}"
682
- case CONFIG[:desktop_notification]
683
- when "libnotify"
684
- Notification::GnomeNotify.notify("Hubeye", change_msg)
685
- Logger.log_change(full_repo_name, commit_msg, committer)
686
- when "growl"
687
- Autotest::Growl.growl("Hubeye", change_msg)
688
- Logger.log_change(full_repo_name, commit_msg, committer)
689
- when nil
690
- if @daemonized
691
- Logger.log_change(full_repo_name, commit_msg, committer)
692
- else
693
- Logger.log_change(full_repo_name, commit_msg, committer, :include_terminal => true)
694
- end
695
- end
696
- # execute any hooks for that repository
697
- unless @session.hooks.nil? || @session.hooks.empty?
698
- if hooks = @session.hooks[full_repo_name]
699
- hooks.each do |dir,cmds|
700
- # execute() takes [commands], {options} where
701
- # options = :directory and :repo
702
- Hooks::Command.execute(cmds, :directory => dir, :repo => full_repo_name)
703
- end
704
- end
705
- end
706
- @session.tracker.add_or_replace!(full_repo_name, new_sha)
707
- end
708
- end
709
- end # end of (while remote_connection == false)
710
- else
711
- @remote_connection = client_ready(@sockets, :block => true) ? true : false
712
- throw(:connect, true) if @remote_connection
713
- end
714
- end
715
-
716
- def client_ready(sockets, options={})
717
- if options[:block]
718
- select(sockets, nil, nil)
719
- else
720
- select(sockets, nil, nil, 1)
721
- end
722
- end
723
-
724
- def client_connect(sockets)
725
- ready = select(sockets)
726
- readable = ready[0]
727
- readable.each do |socket|
728
- if socket == @server
729
- @socket = @server.accept
730
- sockets << @socket
731
- # Inform the client of connection
732
- basic_inform = "Hubeye running on #{Socket.gethostname} as #{@session.username}"
733
- if !@session.tracker.empty?
734
- @socket.puts "#{basic_inform}\nTracking: #{@session.tracker.keys.join ', '}"
735
- else
736
- @socket.puts basic_inform
737
- end
738
- if !@daemonized
739
- puts "Client connected at #{NOW}"
740
- end
741
- @socket.flush
742
- # And log the fact that the client connected
743
- # if the client quit, do not wipe the log file
744
- if @session.continuous
745
- Logger.log "Accepted connection from #{@socket.peeraddr[2]} (#{NOW})"
746
- else
747
- # wipe the log file and start anew
748
- Logger.relog "Accepted connection from #{@socket.peeraddr[2]} (#{NOW})"
749
- end
750
- Logger.log "local: #{@socket.addr}"
751
- Logger.log "peer : #{@socket.peeraddr}"
752
- end
753
- end
754
- end
755
-
756
- end # of Server module
757
-
758
- class HubeyeServer
759
- include Server
760
-
761
- def initialize(debug=true)
762
- @debug = debug
763
- end
764
-
765
- end
766
- end
767
-