1 18 package org.drftpd.plugins; 19 20 import java.io.File ; 21 import java.io.FileInputStream ; 22 import java.io.FileNotFoundException ; 23 import java.io.FileOutputStream ; 24 import java.io.IOException ; 25 import java.io.PrintStream ; 26 import java.net.UnknownHostException ; 27 import java.util.ArrayList ; 28 import java.util.Collection ; 29 import java.util.Collections ; 30 import java.util.Comparator ; 31 import java.util.Enumeration ; 32 import java.util.Hashtable ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 import java.util.Observable ; 36 import java.util.Observer ; 37 import java.util.Properties ; 38 import java.util.ResourceBundle ; 39 40 import net.sf.drftpd.Bytes; 41 import net.sf.drftpd.FatalException; 42 import net.sf.drftpd.NoAvailableSlaveException; 43 import net.sf.drftpd.Nukee; 44 import net.sf.drftpd.ObjectNotFoundException; 45 import net.sf.drftpd.SFVFile; 46 import net.sf.drftpd.SlaveUnavailableException; 47 import net.sf.drftpd.SFVFile.SFVStatus; 48 import net.sf.drftpd.event.DirectoryFtpEvent; 49 import net.sf.drftpd.event.Event; 50 import net.sf.drftpd.event.FtpListener; 51 import net.sf.drftpd.event.InviteEvent; 52 import net.sf.drftpd.event.MessageEvent; 53 import net.sf.drftpd.event.NukeEvent; 54 import net.sf.drftpd.event.SlaveEvent; 55 import net.sf.drftpd.event.TransferEvent; 56 import net.sf.drftpd.event.irc.IRCPluginInterface; 57 import net.sf.drftpd.master.ConnectionManager; 58 import net.sf.drftpd.master.GroupPosition; 59 import net.sf.drftpd.master.SlaveManagerImpl; 60 import net.sf.drftpd.master.UploaderPosition; 61 import net.sf.drftpd.master.command.plugins.Nuke; 62 import net.sf.drftpd.master.command.plugins.TransferStatistics; 63 import net.sf.drftpd.master.config.FtpConfig; 64 import net.sf.drftpd.master.usermanager.NoSuchUserException; 65 import net.sf.drftpd.master.usermanager.User; 66 import net.sf.drftpd.master.usermanager.UserFileException; 67 import net.sf.drftpd.remotefile.LinkedRemoteFile; 68 import net.sf.drftpd.remotefile.LinkedRemoteFileInterface; 69 import net.sf.drftpd.slave.SlaveStatus; 70 import net.sf.drftpd.util.ReplacerUtils; 71 import net.sf.drftpd.util.Time; 72 73 import org.apache.log4j.Level; 74 import org.apache.log4j.Logger; 75 import org.drftpd.sections.SectionInterface; 76 import org.tanesha.replacer.FormatterException; 77 import org.tanesha.replacer.ReplacerEnvironment; 78 import org.tanesha.replacer.ReplacerFormat; 79 import org.tanesha.replacer.SimplePrintf; 80 81 import f00f.net.irc.martyr.Debug; 82 import f00f.net.irc.martyr.IRCConnection; 83 import f00f.net.irc.martyr.clientstate.Channel; 84 import f00f.net.irc.martyr.commands.InviteCommand; 85 import f00f.net.irc.martyr.commands.MessageCommand; 86 import f00f.net.irc.martyr.commands.NickCommand; 87 import f00f.net.irc.martyr.services.AutoJoin; 88 import f00f.net.irc.martyr.services.AutoReconnect; 89 import f00f.net.irc.martyr.services.AutoRegister; 90 import f00f.net.irc.martyr.services.AutoResponder; 91 92 96 public class SiteBot implements FtpListener, Observer { 97 98 public static class Ret { 99 private String _format; 100 private SectionInterface _section; 101 102 public Ret(String string, SectionInterface sectionObj) { 103 _format = string; 104 _section = sectionObj; 105 } 106 107 public String getFormat() { 108 return _format; 109 } 110 111 public SectionInterface getSection() { 112 return _section; 113 } 114 } 115 116 public static class SectionSettings { 117 private String _channel; 118 private ReplacerEnvironment _env = new ReplacerEnvironment(); 119 public SectionSettings(Properties p, int i) { 120 121 } 122 123 public SectionSettings(Properties ircCfg, int i, String channel) { 124 _channel = channel; 125 } 126 public String getChannel() { 127 return _channel; 128 } 129 public ReplacerEnvironment getEnv() { 130 return _env; 131 } 132 } 133 134 public static final ReplacerEnvironment GLOBAL_ENV = 135 new ReplacerEnvironment(); 136 static { 137 GLOBAL_ENV.add("bold", "\u0002"); 138 GLOBAL_ENV.add("coloroff", "\u000f"); 139 GLOBAL_ENV.add("color", "\u0003"); 140 } 141 142 private static final Logger logger = Logger.getLogger(SiteBot.class); 143 144 public static ArrayList map2nukees(Map nukees) { 145 ArrayList ret = new ArrayList (); 146 for (Iterator iter = nukees.entrySet().iterator(); iter.hasNext();) { 147 Map.Entry element = (Map.Entry ) iter.next(); 148 ret.add( 149 new Nukee( 150 (String ) element.getKey(), 151 ((Long ) element.getValue()).longValue())); 152 } 153 Collections.sort(ret); 154 return ret; 155 } 156 157 public static Collection topFileGroup(Collection files) { 158 ArrayList ret = new ArrayList (); 159 for (Iterator iter = files.iterator(); iter.hasNext();) { 160 LinkedRemoteFile file = (LinkedRemoteFile) iter.next(); 161 String groupname = file.getGroupname(); 162 163 GroupPosition stat = null; 164 for (Iterator iter2 = ret.iterator(); iter2.hasNext();) { 165 GroupPosition stat2 = (GroupPosition) iter2.next(); 166 if (stat2.getGroupname().equals(groupname)) { 167 stat = stat2; 168 break; 169 } 170 } 171 if (stat == null) { 172 stat = 173 new GroupPosition( 174 groupname, 175 file.length(), 176 1, 177 file.getXfertime()); 178 ret.add(stat); 179 } else { 180 stat.updateBytes(file.length()); 181 stat.updateFiles(1); 182 stat.updateXfertime(file.getXfertime()); 183 } 184 } 185 Collections.sort(ret); 186 return ret; 187 } 188 189 public static Collection userSort( 190 Collection files, 191 String type, 192 String sort) { 193 ArrayList ret = new ArrayList (); 194 for (Iterator iter = files.iterator(); iter.hasNext();) { 195 LinkedRemoteFileInterface file = 196 (LinkedRemoteFileInterface) iter.next(); 197 UploaderPosition stat = null; 198 for (Iterator iter2 = ret.iterator(); iter2.hasNext();) { 199 UploaderPosition stat2 = (UploaderPosition) iter2.next(); 200 if (stat2.getUsername().equals(file.getUsername())) { 201 stat = stat2; 202 break; 203 } 204 } 205 if (stat == null) { 206 stat = 207 new UploaderPosition( 208 file.getUsername(), 209 file.length(), 210 1, 211 file.getXfertime()); 212 ret.add(stat); 213 } else { 214 stat.updateBytes(file.length()); 215 stat.updateFiles(1); 216 stat.updateXfertime(file.getXfertime()); 217 } 218 } 219 Collections.sort(ret, new UserComparator(type, sort)); 220 return ret; 221 } 222 223 225 private AutoReconnect _autoReconnect; 226 private AutoRegister _autoRegister; 227 private String _channelName; 228 229 private ConnectionManager _cm; 230 231 private String _commands; 232 233 protected IRCConnection _conn; 234 private boolean _enableAnnounce; 235 236 protected int _port; 238 239 private Hashtable _sections; 240 241 protected String _server; 242 243 public SiteBot() throws IOException { 244 new File ("logs").mkdirs(); 245 Debug.setOutputStream( 246 new PrintStream (new FileOutputStream ("logs/sitebot.log", true))); 247 } 249 250 public void actionPerformed(Event event) { 251 if (_enableAnnounce) { 252 try { 253 if (event instanceof DirectoryFtpEvent) { 254 actionPerformedDirectory((DirectoryFtpEvent) event); 255 } else if (event instanceof NukeEvent) { 256 actionPerformedNuke((NukeEvent) event); 257 } else if (event instanceof SlaveEvent) { 258 actionPerformedSlave((SlaveEvent) event); 259 } else if (event instanceof InviteEvent) { 260 actionPerformedInvite((InviteEvent) event); 261 } else if (event.getCommand().equals("RELOAD")) { 262 try { 263 reload(); 264 } catch (IOException e) { 265 logger.log(Level.WARN, "", e); 266 } 267 268 } else if (event.getCommand().equals("SHUTDOWN")) { 269 MessageEvent mevent = (MessageEvent) event; 270 ReplacerEnvironment env = 271 new ReplacerEnvironment(GLOBAL_ENV); 272 env.add("message", mevent.getMessage()); 273 274 sayGlobal( 275 ReplacerUtils.jprintf("shutdown", env, SiteBot.class)); 276 } 277 } catch (FormatterException ex) { 278 say( 279 null, 280 event.getCommand() 281 + " FormatterException: " 282 + ex.getMessage()); 283 logger.warn("", ex); 284 } 285 } 286 } 287 288 private void actionPerformedDirectory(DirectoryFtpEvent direvent) 289 throws FormatterException { 290 if (!getConfig() 291 .checkDirLog(direvent.getUser(), direvent.getDirectory())) { 292 return; 293 } 294 if ("MKD".equals(direvent.getCommand())) { 295 sayDirectorySection(direvent, "mkdir"); 296 } else if ("REQUEST".equals(direvent.getCommand())) { 297 sayDirectorySection(direvent, "request"); 298 } else if ("REQFILLED".equals(direvent.getCommand())) { 299 sayDirectorySection(direvent, "reqfilled"); 300 } else if ("RMD".equals(direvent.getCommand())) { 301 sayDirectorySection(direvent, "rmdir"); 302 } else if ("WIPE".equals(direvent.getCommand())) { 303 if (direvent.getDirectory().isDirectory()) { 304 sayDirectorySection(direvent, "wipe"); 305 } 306 } else if ("PRE".equals(direvent.getCommand())) { 307 sayDirectorySection(direvent, "pre"); 308 } else if ("STOR".equals(direvent.getCommand())) { 309 actionPerformedDirectorySTOR((TransferEvent)direvent); 310 } 311 } 312 313 private void actionPerformedDirectorySTOR(TransferEvent direvent) 314 throws FormatterException { 315 if(!direvent.isComplete()) return; 316 ReplacerEnvironment env = new ReplacerEnvironment(GLOBAL_ENV); 317 LinkedRemoteFile dir; 318 try { 319 dir = direvent.getDirectory().getParentFile(); 320 } catch (FileNotFoundException e) { 321 throw new FatalException(e); 322 } 323 SFVFile sfvfile; 324 try { 325 sfvfile = dir.lookupSFVFile(); 326 } catch (FileNotFoundException ex) { 328 logger.info( 329 "No sfv file in " 330 + direvent.getDirectory().getPath() 331 + ", can't publish race info"); 332 return; 333 } catch (NoAvailableSlaveException e) { 334 logger.info("No available slave with .sfv"); 335 return; 336 } catch (IOException e) { 337 logger.warn("IO error reading .sfv", e); 338 return; 339 } 340 341 if (!sfvfile.hasFile(direvent.getDirectory().getName())) 342 return; 343 344 int halfway = (int) Math.floor((double) sfvfile.size() / 2); 345 347 String username = direvent.getUser().getUsername(); 349 SFVStatus sfvstatus = sfvfile.getStatus(); 350 if (sfvfile.size() - sfvstatus.getMissing() != 1) { 351 for (Iterator iter = sfvfile.getFiles().iterator(); 352 iter.hasNext(); 353 ) { 354 LinkedRemoteFile sfvFileEntry = (LinkedRemoteFile) iter.next(); 355 if (sfvFileEntry == direvent.getDirectory()) 356 continue; 357 if (sfvFileEntry.getUsername().equals(username)) 358 break; 359 if (!iter.hasNext()) { 360 361 Ret ret = 362 getPropertyFileSuffix( 363 "store.embraces", 364 direvent.getDirectory()); 365 String format = ret.getFormat(); 366 LinkedRemoteFileInterface section = 367 ret.getSection().getFile(); 368 369 fillEnvSection( 372 env, 373 direvent, 374 section, 375 direvent.getDirectory()); 376 env.add( 377 "filesleft", 378 Integer.toString(sfvstatus.getMissing())); 379 380 say(ret.getSection(), SimplePrintf.jprintf(format, env)); 381 } 382 } 383 } 384 385 390 if (sfvstatus.isFinished()) { 392 Collection racers = userSort(sfvfile.getFiles(), "bytes", "high"); 393 Collection groups = topFileGroup(sfvfile.getFiles()); 394 Ret ret = getPropertyFileSuffix("store.complete", dir); 398 399 try { 400 fillEnvSection( 401 env, 402 direvent, 403 ret.getSection().getFile(), 404 direvent.getDirectory().getParentFile()); 405 } catch (FileNotFoundException e) { 406 throw new RuntimeException (e); 407 } 408 env.add("racers", Integer.toString(racers.size())); 409 env.add("groups", Integer.toString(groups.size())); 410 env.add("files", Integer.toString(sfvfile.size())); 411 env.add("size", Bytes.formatBytes(sfvfile.getTotalBytes())); 412 env.add("speed", Bytes.formatBytes(sfvfile.getXferspeed()) + "/s"); 413 say(ret.getSection(), SimplePrintf.jprintf(ret.getFormat(), env)); 414 415 ret = getPropertyFileSuffix("store.complete.racer", dir); 417 ReplacerFormat raceformat; 418 raceformat = ReplacerFormat.createFormat(ret.getFormat()); 420 try { 421 fillEnvSection( 422 env, 423 direvent, 424 ret.getSection().getFile(), 425 direvent.getDirectory().getParentFile()); 426 } catch (FileNotFoundException e) { 427 throw new RuntimeException (e); 428 } 429 int position = 1; 430 for (Iterator iter = racers.iterator(); iter.hasNext();) { 431 UploaderPosition stat = (UploaderPosition) iter.next(); 432 433 User raceuser; 434 try { 435 raceuser = 436 _cm.getUserManager().getUserByName(stat.getUsername()); 437 } catch (NoSuchUserException e2) { 438 continue; 439 } catch (UserFileException e2) { 440 logger.log(Level.FATAL, "Error reading userfile", e2); 441 continue; 442 } 443 ReplacerEnvironment raceenv = 444 new ReplacerEnvironment(GLOBAL_ENV); 445 446 raceenv.add("user", raceuser.getUsername()); 447 raceenv.add("group", raceuser.getGroupName()); 448 449 raceenv.add("position", new Integer (position++)); 450 raceenv.add("size", Bytes.formatBytes(stat.getBytes())); 451 raceenv.add("files", Integer.toString(stat.getFiles())); 452 raceenv.add( 453 "percent", 454 Integer.toString(stat.getFiles() * 100 / sfvfile.size()) 455 + "%"); 456 raceenv.add( 457 "speed", 458 Bytes.formatBytes(stat.getXferspeed()) + "/s"); 459 raceenv.add( 460 "alup", 461 new Integer ( 462 TransferStatistics.getStatsPlace( 463 "ALUP", 464 raceuser, 465 _cm.getUserManager()))); 466 raceenv.add( 467 "monthup", 468 new Integer ( 469 TransferStatistics.getStatsPlace( 470 "MONTHUP", 471 raceuser, 472 _cm.getUserManager()))); 473 raceenv.add( 474 "wkup", 475 new Integer ( 476 TransferStatistics.getStatsPlace( 477 "WKUP", 478 raceuser, 479 _cm.getUserManager()))); 480 raceenv.add( 481 "dayup", 482 new Integer ( 483 TransferStatistics.getStatsPlace( 484 "DAYUP", 485 raceuser, 486 _cm.getUserManager()))); 487 raceenv.add( 488 "aldn", 489 new Integer ( 490 TransferStatistics.getStatsPlace( 491 "ALDN", 492 raceuser, 493 _cm.getUserManager()))); 494 raceenv.add( 495 "monthdn", 496 new Integer ( 497 TransferStatistics.getStatsPlace( 498 "MONTHDN", 499 raceuser, 500 _cm.getUserManager()))); 501 raceenv.add( 502 "wkdn", 503 new Integer ( 504 TransferStatistics.getStatsPlace( 505 "WKDN", 506 raceuser, 507 _cm.getUserManager()))); 508 raceenv.add( 509 "daydn", 510 new Integer ( 511 TransferStatistics.getStatsPlace( 512 "DAYDN", 513 raceuser, 514 _cm.getUserManager()))); 515 516 say( 517 ret.getSection(), 518 SimplePrintf.jprintf(raceformat, raceenv)); 519 } 520 521 Ret ret3 = getPropertyFileSuffix("store.complete.group", dir); 522 raceformat = ReplacerFormat.createFormat(ret3.getFormat()); 524 say( 525 ret.getSection(), 526 SimplePrintf.jprintf( 527 getPropertyFileSuffix("store.complete.group.header", dir) 528 .getFormat(), 529 env)); 530 531 position = 1; 532 for (Iterator iter = groups.iterator(); iter.hasNext();) { 533 GroupPosition stat = (GroupPosition) iter.next(); 534 535 ReplacerEnvironment raceenv = 536 new ReplacerEnvironment(GLOBAL_ENV); 537 538 raceenv.add("group", stat.getGroupname()); 539 540 raceenv.add("position", new Integer (position++)); 541 raceenv.add("size", Bytes.formatBytes(stat.getBytes())); 542 raceenv.add("files", Integer.toString(stat.getFiles())); 543 raceenv.add( 544 "percent", 545 Integer.toString(stat.getFiles() * 100 / sfvfile.size()) 546 + "%"); 547 raceenv.add( 548 "speed", 549 Bytes.formatBytes(stat.getXferspeed()) + "/s"); 550 551 say( 552 ret.getSection(), 553 SimplePrintf.jprintf(raceformat, raceenv)); 554 } 555 } else if (sfvfile.size() >= 4 && sfvstatus.getMissing() == halfway) { 557 Collection uploaders = 558 userSort(sfvfile.getFiles(), "bytes", "high"); 559 UploaderPosition stat = 561 (UploaderPosition) uploaders.iterator().next(); 562 563 env.add("leadspeed", Bytes.formatBytes(stat.getXferspeed()) + "/s"); 564 env.add("leadfiles", Integer.toString(stat.getFiles())); 565 env.add("leadsize", Bytes.formatBytes(stat.getBytes())); 566 env.add( 567 "leadpercent", 568 Integer.toString(stat.getFiles() * 100 / sfvfile.size()) + "%"); 569 env.add("filesleft", Integer.toString(sfvstatus.getMissing())); 570 User leaduser; 571 try { 572 leaduser = 573 _cm.getUserManager().getUserByName(stat.getUsername()); 574 env.add("leaduser", leaduser.getUsername()); 575 env.add("leadgroup", leaduser.getGroupName()); 576 } catch (NoSuchUserException e3) { 577 logger.log(Level.WARN, "", e3); 578 } catch (UserFileException e3) { 579 logger.log(Level.WARN, "", e3); 580 } 581 582 Ret ret = getPropertyFileSuffix("store.halfway", dir); 583 String format = (String ) ret.getFormat(); 584 LinkedRemoteFileInterface section = ret.getSection().getFile(); 585 586 fillEnvSection(env, direvent, section); 587 588 say(ret.getSection(), SimplePrintf.jprintf(format, env)); 589 590 } 619 } 620 621 private void actionPerformedInvite(InviteEvent event) { 622 String user = event.getUser(); 623 logger.info("Invited " + user + " through SITE INVITE"); 624 for (Enumeration e = getIRCConnection().getClientState().getChannels(); 625 e.hasMoreElements(); 626 ) { 627 Channel chan = (Channel) e.nextElement(); 628 if (chan 629 .findMember(getIRCConnection().getClientState().getNick().getNick()) 630 .hasOps()) { 631 _conn.sendCommand(new InviteCommand(user, chan.getName())); 632 } 633 } 634 } 635 636 private void actionPerformedNuke(NukeEvent event) 637 throws FormatterException { 638 String cmd = event.getCommand(); 639 SectionInterface section = 640 _cm.getSectionManager().lookup(event.getPath()); 641 ReplacerEnvironment env = new ReplacerEnvironment(GLOBAL_ENV); 642 env.add("size", Bytes.formatBytes(event.getSize())); 643 env.add("section", section.getName()); 644 645 env.add("path", event.getPath()); 647 env.add("reason", event.getReason()); 648 env.add("multiplier", String.valueOf(event.getMultiplier())); 649 650 env.add("user", event.getUser().getUsername()); 651 env.add("group", event.getUser().getGroupName()); 652 653 655 if (cmd.equals("NUKE") || cmd.equals("UNNUKE")) { 656 String cmdName = cmd.toLowerCase(); 657 say( 658 section, 659 ReplacerUtils.jprintf(cmdName, env, SiteBot.class.getName())); 660 661 ReplacerFormat raceformat = 662 ReplacerUtils.finalFormat(SiteBot.class, cmdName + ".nukees"); 663 664 int position = 1; 665 long nobodyAmount = 0; 666 for (Iterator iter = event.getNukees2().iterator(); 667 iter.hasNext(); 668 ) { 669 Nukee stat = (Nukee) iter.next(); 670 671 User raceuser; 672 try { 673 raceuser = 674 _cm.getUserManager().getUserByName(stat.getUsername()); 675 } catch (NoSuchUserException e2) { 676 nobodyAmount += stat.getAmount(); 677 continue; 678 } catch (UserFileException e2) { 679 logger.log(Level.FATAL, "Error reading userfile", e2); 680 continue; 681 } 682 ReplacerEnvironment raceenv = 683 new ReplacerEnvironment(GLOBAL_ENV); 684 685 raceenv.add("user", raceuser.getUsername()); 686 raceenv.add("group", raceuser.getGroupName()); 687 688 raceenv.add("position", "" + position++); 689 raceenv.add("size", Bytes.formatBytes(stat.getAmount())); 690 691 long nukedamount = 692 Nuke.calculateNukedAmount( 693 stat.getAmount(), 694 raceuser.getRatio(), 695 event.getMultiplier()); 696 raceenv.add("nukedamount", Bytes.formatBytes(nukedamount)); 697 say(section, SimplePrintf.jprintf(raceformat, raceenv)); 698 699 } 700 if (nobodyAmount != 0) { 701 ReplacerEnvironment raceenv = 702 new ReplacerEnvironment(GLOBAL_ENV); 703 704 raceenv.add("user", "nobody"); 705 raceenv.add("group", "nogroup"); 706 707 raceenv.add("position", "?"); 708 raceenv.add("size", Bytes.formatBytes(nobodyAmount)); 709 710 say(section, SimplePrintf.jprintf(raceformat, raceenv)); 711 712 } 713 } 715 } 718 719 private void actionPerformedSlave(SlaveEvent event) 720 throws FormatterException { 721 SlaveEvent sevent = (SlaveEvent) event; 722 ReplacerEnvironment env = new ReplacerEnvironment(GLOBAL_ENV); 723 env.add("slave", sevent.getRSlave().getName()); 724 env.add("message", sevent.getMessage()); 725 if (event.getCommand().equals("ADDSLAVE")) { 726 SlaveStatus status; 727 try { 728 status = sevent.getRSlave().getStatus(); 729 } catch (SlaveUnavailableException e) { 730 logger.warn("in ADDSLAVE event handler", e); 731 return; 732 } 733 fillEnvSlaveStatus(env, status, getSlaveManager()); 734 735 sayGlobal(ReplacerUtils.jprintf("addslave", env, SiteBot.class)); 736 } else if (event.getCommand().equals("DELSLAVE")) { 737 sayGlobal(ReplacerUtils.jprintf("delslave", env, SiteBot.class)); 738 } 739 } 740 741 private AutoRegister addAutoRegister(Properties ircCfg) { 742 return new AutoRegister( 743 _conn, 744 FtpConfig.getProperty(ircCfg, "irc.nick"), 745 FtpConfig.getProperty(ircCfg, "irc.user"), 746 FtpConfig.getProperty(ircCfg, "irc.name")); 747 } 748 749 public void connect() throws UnknownHostException , IOException { 750 logger.info("connecting to " + _server + ":" + _port); 751 _conn.connect(_server, _port); 752 } 753 754 private void connect(Properties ircCfg) 755 throws UnknownHostException , IOException { 756 if (_conn != null) { 757 _autoReconnect.disable(); 758 _conn.disconnect(); 759 } 760 _conn = new IRCConnection(); 761 762 _autoReconnect = new AutoReconnect(_conn); 763 _autoRegister = addAutoRegister(ircCfg); 764 for (int i = 1;; i++) { 765 String channelName = ircCfg.getProperty("irc.channel." + i); 766 String key; 767 if (channelName == null) { 768 if (i == 1) { 769 channelName = FtpConfig.getProperty(ircCfg, "irc.channel"); 770 key = ircCfg.getProperty("irc.key"); 771 } else { 772 break; 773 } 774 } else { 775 key = ircCfg.getProperty("irc.channel." + i + ".key"); 776 } 777 if (i == 1) 778 _channelName = channelName; 779 new AutoJoin(_conn, channelName, key); 780 } 781 782 new AutoResponder(_conn); 784 _conn.addCommandObserver(this); 785 _commands = ""; 786 for (int i = 1;; i++) { 787 String classname = ircCfg.getProperty("irc.plugins." + i); 788 if (classname == null) 789 break; 790 Observer obs; 791 try { 792 logger.debug("Loading " + Class.forName(classname)); 793 obs = 794 (Observer ) Class 795 .forName(classname) 796 .getConstructor(new Class [] { SiteBot.class }) 797 .newInstance(new Object [] { this }); 798 IRCPluginInterface plugin = (IRCPluginInterface) obs; 800 if (plugin.getCommands() != null) { 801 _commands = _commands + plugin.getCommands() + " "; 802 } 803 } catch (Exception e) { 804 logger.warn("", e); 805 throw new RuntimeException ( 806 "Error loading IRC plugin :" + classname, 807 e); 808 } 809 } 810 connect(); 811 } 812 813 public void disconnect() { 814 _autoReconnect.disable(); 815 _conn.disconnect(); 816 } 817 818 private void fillEnvSection( 819 ReplacerEnvironment env, 820 DirectoryFtpEvent direvent, 821 LinkedRemoteFileInterface section) { 822 fillEnvSection(env, direvent, section, direvent.getDirectory()); 823 } 824 825 private void fillEnvSection( 826 ReplacerEnvironment env, 827 DirectoryFtpEvent direvent, 828 LinkedRemoteFileInterface section, 829 LinkedRemoteFileInterface file) { 830 env.add("user", direvent.getUser().getUsername()); 831 env.add("group", direvent.getUser().getGroupName()); 832 env.add("section", strippath(section.getPath())); 833 834 LinkedRemoteFileInterface dir = file; 835 if (dir.isFile()) 836 dir = dir.getParentFileNull(); 837 838 long starttime; 839 try { 840 starttime = dir.getOldestFile().lastModified(); 841 } catch (ObjectNotFoundException e) { 842 starttime = dir.lastModified(); 843 } 844 847 env.add("size", Bytes.formatBytes(file.length())); 848 env.add( 849 "path", 850 strippath(dir.getPath().substring(section.getPath().length()))); 851 env.add("file", file.getName()); 852 if (file.isFile()) { 853 env.add("speed", Bytes.formatBytes(file.getXferspeed()*1000) + "/s"); 854 file = file.getParentFileNull(); } 856 857 long elapsed = (direvent.getTime() - starttime); 858 859 env.add("secondstocomplete", Time.formatTime(elapsed)); 860 long elapsedSeconds = elapsed/1000; 861 env.add( 862 "averagespeed", 863 elapsedSeconds == 0 ? "n/a" : Bytes.formatBytes(dir.length() / elapsedSeconds) + "/s"); 864 865 SFVFile sfvfile; 874 try { 875 sfvfile = file.lookupSFVFile(); 876 env.add("totalfiles", "" + sfvfile.size()); 878 env.add( 879 "totalspeed", 880 Bytes.formatBytes(sfvfile.getXferspeed())); 881 } catch (Exception ex) { 882 logger.warn("Couldn't get SFV file in announce", ex); 884 env.add("totalfiles", "" + file.getFiles().size()); 886 } 887 } 888 889 public static void fillEnvSlaveStatus(ReplacerEnvironment env, SlaveStatus status, SlaveManagerImpl slaveManager) { 890 env.add("disktotal", Bytes.formatBytes(status.getDiskSpaceCapacity())); 891 env.add("diskfree", Bytes.formatBytes(status.getDiskSpaceAvailable())); 892 env.add("diskused", Bytes.formatBytes(status.getDiskSpaceUsed())); 893 894 if(status.getDiskSpaceCapacity() == 0) { 895 env.add("diskfreepercent", "n/a"); 896 env.add("diskusedpercent", "n/a"); 897 } else { 898 env.add( 899 "diskfreepercent", 900 status.getDiskSpaceAvailable() 901 * 100 902 / status.getDiskSpaceCapacity() 903 + "%"); 904 env.add( 905 "diskusedpercent", 906 status.getDiskSpaceUsed() * 100 / status.getDiskSpaceCapacity() 907 + "%"); 908 } 909 910 env.add("xfers", ""+status.getTransfers()); 911 env.add("xfersdn", ""+status.getTransfersSending()); 912 env.add("xfersup", ""+status.getTransfersReceiving()); 913 env.add("xfersdown", ""+status.getTransfersSending()); 914 915 env.add( 916 "throughput", 917 Bytes.formatBytes(status.getThroughput()) + "/s"); 918 919 env.add( 920 "throughputup", 921 Bytes.formatBytes(status.getThroughputReceiving()) + "/s"); 922 923 env.add( 924 "throughputdown", 925 Bytes.formatBytes(status.getThroughputSending())+"/s"); 926 try { 927 env.add("slaves", ""+slaveManager.getAvailableSlaves().size()); 928 } catch (NoAvailableSlaveException e2) { 929 env.add("slaves", "0"); 930 } 931 } 932 933 public String getChannelName() { 934 return _channelName; 935 } 936 937 public FtpConfig getConfig() { 938 return _cm.getConfig(); 939 } 940 941 public ConnectionManager getConnectionManager() { 942 return _cm; 943 } 944 public IRCConnection getIRCConnection() { 945 return _conn; 946 } 947 948 public Ret getPropertyFileSuffix(String prefix, LinkedRemoteFileInterface dir) { 949 SectionInterface sectionObj = 950 getConnectionManager().getSectionManager().lookup(dir.getPath()); 951 logger.debug("section = " + sectionObj.getName()); 952 return new Ret( 963 ResourceBundle.getBundle(SiteBot.class.getName()).getString(prefix), 964 sectionObj); 965 } 966 967 public SlaveManagerImpl getSlaveManager() { 968 return getConnectionManager().getSlaveManager(); 969 } 970 971 public void init(ConnectionManager mgr) { 972 _cm = mgr; 973 try { 974 reload(); 975 } catch (Exception e) { 976 throw new RuntimeException (e); 977 } 978 } 979 980 public void reconnect() { 981 _conn.disconnect(); 982 } 983 984 protected void reload() throws FileNotFoundException , IOException { 985 Properties ircCfg = new Properties (); 986 ircCfg.load(new FileInputStream ("conf/irc.conf")); 987 reload(ircCfg); 988 } 989 990 protected void reload(Properties ircCfg) throws IOException { 991 _server = FtpConfig.getProperty(ircCfg, "irc.server"); 992 _port = Integer.parseInt(FtpConfig.getProperty(ircCfg, "irc.port")); 993 _enableAnnounce = 997 ircCfg.getProperty("irc.enable.announce", "false").equals("true"); 998 Hashtable sections = new Hashtable (); 1001 for (int i = 1;; i++) { 1002 String name = ircCfg.getProperty("irc.section." + i); 1003 if (name == null) 1004 break; 1005 String chan = ircCfg.getProperty("irc.section." + i + ".channel"); 1006 if (chan == null) 1007 chan = _channelName; 1008 sections.put(name, new SectionSettings(ircCfg, i, chan)); 1009 } 1010 _sections = sections; 1011 if (_conn == null 1012 || !_conn.getClientState().getServer().equals(_server) 1013 || _conn.getClientState().getPort() != _port) { 1014 logger.info("Reconnecting due to server change"); 1015 connect(ircCfg); 1016 } else { 1017 if (!_conn 1018 .getClientState() 1019 .getNick() 1020 .getNick() 1021 .equals(FtpConfig.getProperty(ircCfg, "irc.nick"))) { 1022 logger.info("Switching to new nick"); 1023 _autoRegister.disable(); 1024 _autoRegister = addAutoRegister(ircCfg); 1025 _conn.sendCommand( 1026 new NickCommand(ircCfg.getProperty("irc.nick"))); 1027 } 1028 } 1035 } 1036 1037 public void say(SectionInterface section, String message) { 1038 SectionSettings sn = null; 1039 if (section != null) { 1040 sn = (SectionSettings) _sections.get(section.getName()); 1041 } 1042 sayChannel(sn != null ? sn.getChannel() : _channelName, message); 1043 } 1044 1045 public void sayChannel(String chan, String message) { 1046 if (message.equals("")) 1047 throw new IllegalArgumentException ("Cowardly refusing to send empty message"); 1048 1049 String lines[] = message.split("\n"); 1050 for (int i = 0; i < lines.length; i++) { 1051 _conn.sendCommand(new MessageCommand(chan, lines[i])); 1052 } 1053 } 1054 1055 private void sayDirectorySection(DirectoryFtpEvent direvent, String string) 1056 throws FormatterException { 1057 1058 Ret ret = getPropertyFileSuffix(string, direvent.getDirectory()); 1059 String format = ret.getFormat(); 1060 LinkedRemoteFileInterface section = ret.getSection().getFile(); 1061 1062 ReplacerEnvironment env = new ReplacerEnvironment(GLOBAL_ENV); 1063 fillEnvSection(env, direvent, section); 1064 1065 say(ret.getSection(), SimplePrintf.jprintf(format, env)); 1066 } 1067 1068 public void sayGlobal(String string) { 1069 for (Enumeration e = getIRCConnection().getClientState().getChannelNames(); 1070 e.hasMoreElements(); 1071 ) { 1072 sayChannel((String ) e.nextElement(), string); 1073 } 1074 } 1075 1076 public String strippath(String path) { 1077 if (!path.startsWith("/")) { 1078 return path; 1079 } 1080 return path.substring(1); 1081 } 1082 1083 public void unload() { 1084 disconnect(); 1085 } 1086 1087 public void update(Observable observer, Object updated) { 1088 if (!(updated instanceof MessageCommand)) 1089 return; 1090 1091 MessageCommand msgc = (MessageCommand) updated; 1092 if (msgc.isPrivateToUs(getIRCConnection().getClientState())) 1093 return; 1094 if (!msgc.getDest().equalsIgnoreCase(_channelName)) 1095 return; 1096 String msg = msgc.getMessage(); 1097 if (msg.equals("!help")) { 1098 sayChannel(msgc.getDest(), "Available commands: " + _commands); 1099 } 1100 1101 } 1102 1103} 1104 1105class UserComparator implements Comparator { 1106 1107 static long getType(String type, UploaderPosition user) { 1108 if (type.equals("bytes")) { 1109 return user.getBytes(); 1110 } else if (type.equals("xferspeed")) { 1111 return user.getXferspeed(); 1112 } else if (type.equals("xfertime")) { 1113 return user.getXfertime(); 1114 } 1115 return 0; 1116 } 1117 private String _sort; 1118 private String _type; 1119 1120 public UserComparator(String type, String sort) { 1121 _type = type; 1122 _sort = sort; 1123 } 1124 1125 public int compare(Object o1, Object o2) { 1126 UploaderPosition u1 = (UploaderPosition) o1; 1127 UploaderPosition u2 = (UploaderPosition) o2; 1128 1129 long thisVal = getType(_type, u1); 1130 long anotherVal = getType(_type, u2); 1131 if (_sort.equals("low")) { 1132 return ( 1133 thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1)); 1134 } else { 1135 return ( 1136 thisVal > anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1)); 1137 } 1138 } 1139} 1140 | Popular Tags |