hubeye 0.3.0 → 0.3.2

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,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
-