diff --git a/src/plugins/org.drftpd.plugins.linkmanager.latestdir/build.xml b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/build.xml
new file mode 100644
index 0000000..f72d6d2
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/build.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/org.drftpd.plugins.linkmanager.latestdir/plugin.xml b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/plugin.xml
new file mode 100644
index 0000000..a5acda7
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/plugin.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+ This plugin provides LatestDir to the Link Manager
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/org.drftpd.plugins.linkmanager.latestdir/resources/conf/plugins/latestdir.conf.dist b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/resources/conf/plugins/latestdir.conf.dist
new file mode 100644
index 0000000..b170218
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/resources/conf/plugins/latestdir.conf.dist
@@ -0,0 +1,2 @@
+#how much links shall be produced
+maxcount=1
\ No newline at end of file
diff --git a/src/plugins/org.drftpd.plugins.linkmanager.latestdir/resources/conf/plugins/linkmanager.conf.dist b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/resources/conf/plugins/linkmanager.conf.dist
new file mode 100644
index 0000000..5584ebd
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/resources/conf/plugins/linkmanager.conf.dist
@@ -0,0 +1,15 @@
+################################################################################
+# LATESTDIR:
+#
+# This will just make links of last races
+#
+# x.type=LATESTDIR
+# x.dirname=/_LAST_RACES_
+# x.section=*
+# x.exclude=
+# x.sectionexclude=^(?i)(pre|staff|speedtests)$
+# x.deleteon=*
+# x.linkname=(last)-${dirname}
+# x.addparentdir=^(?i)(((cd|dvd|dis[ck])[1-9])|sample|subs|rarfix)$
+#
+################################################################################
\ No newline at end of file
diff --git a/src/plugins/org.drftpd.plugins.linkmanager.latestdir/src/org/drftpd/plugins/linkmanager/types/latestdir/LatestDir.java b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/src/org/drftpd/plugins/linkmanager/types/latestdir/LatestDir.java
new file mode 100644
index 0000000..cc40aff
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/src/org/drftpd/plugins/linkmanager/types/latestdir/LatestDir.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of DrFTPD, Distributed FTP Daemon.
+ *
+ * DrFTPD is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * DrFTPD is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * DrFTPD; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ */
+package org.drftpd.plugins.linkmanager.types.latestdir;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.drftpd.commands.zipscript.vfs.ZipscriptVFSDataSFV;
+import org.drftpd.exceptions.NoAvailableSlaveException;
+import org.drftpd.exceptions.SlaveUnavailableException;
+import org.drftpd.plugins.linkmanager.LinkType;
+import org.drftpd.vfs.DirectoryHandle;
+
+/**
+ * @author freasy
+ * @version $Id: LatestDir.java freasy $
+ */
+
+public class LatestDir extends LinkType {
+
+ public LatestDir(Properties p, int confnum, String type) {
+ super(p, confnum, type);
+ }
+
+ /*
+ * This just passes the target dir through to creating the Link
+ * No special setup is needed for this type.
+ */
+ @Override
+ public void doCreateLink(DirectoryHandle targetDir) {
+ createLink(targetDir,targetDir.getPath(),targetDir.getName());
+ }
+
+ /*
+ * This just passes the target dir through to creating the Link
+ * No special setup is needed for this type.
+ */
+ @Override
+ public void doDeleteLink(DirectoryHandle targetDir) {
+ deleteLink(targetDir,targetDir.getPath(),targetDir.getName());
+
+ }
+
+ public void doFixLink(DirectoryHandle dirHandle) {
+
+ }
+}
diff --git a/src/plugins/org.drftpd.plugins.linkmanager.latestdir/src/org/drftpd/plugins/linkmanager/types/latestdir/LatestDirManager.java b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/src/org/drftpd/plugins/linkmanager/types/latestdir/LatestDirManager.java
new file mode 100644
index 0000000..8848f22
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.latestdir/src/org/drftpd/plugins/linkmanager/types/latestdir/LatestDirManager.java
@@ -0,0 +1,130 @@
+/*
+ * This file is part of DrFTPD, Distributed FTP Daemon.
+ *
+ * DrFTPD is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * DrFTPD is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * DrFTPD; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ */
+package org.drftpd.plugins.linkmanager.types.latestdir;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.drftpd.PropertyHelper;
+import org.drftpd.GlobalContext;
+
+
+import org.bushe.swing.event.annotation.AnnotationProcessor;
+import org.bushe.swing.event.annotation.EventSubscriber;
+import org.drftpd.PluginInterface;
+import org.drftpd.commands.zipscript.vfs.ZipscriptVFSDataSFV;
+import org.drftpd.event.ReloadEvent;
+import org.drftpd.event.DirectoryFtpEvent;
+import org.drftpd.exceptions.NoAvailableSlaveException;
+import org.drftpd.exceptions.SlaveUnavailableException;
+import org.drftpd.plugins.linkmanager.LinkManager;
+import org.drftpd.plugins.linkmanager.LinkType;
+import org.drftpd.vfs.event.VirtualFileSystemInodeDeletedEvent;
+import org.drftpd.vfs.DirectoryHandle;
+import org.drftpd.vfs.LinkHandle;
+/**
+ * @author freasy
+ * @version $Id: LatestDirManager.java freasy $
+ */
+
+public class LatestDirManager implements PluginInterface {
+ private LinkManager _linkmanager;
+
+ private ArrayList _links;
+
+ private HashMap _map;
+
+ private int _count;
+
+ @Override
+ public void startPlugin() {
+ AnnotationProcessor.process(this);
+ loadManager();
+ }
+
+ @Override
+ public void stopPlugin(String reason) {
+ AnnotationProcessor.unprocess(this);
+ }
+
+ @EventSubscriber
+ public void onReloadEvent(ReloadEvent event) {
+ loadManager();
+ }
+
+ private void loadManager() {
+ _linkmanager = LinkManager.getLinkManager();
+ _links = new ArrayList();
+ _map = new HashMap();
+ Properties _props = GlobalContext.getGlobalContext().getPluginsConfig().getPropertiesForPlugin("latestdir.conf");
+ _count = Integer.parseInt(PropertyHelper.getProperty(_props, "maxcount","10"));
+ for (LinkType link : _linkmanager.getLinks()) {
+ if (link.getEventType().equals("latestdir")) {
+ DirectoryHandle dir = new DirectoryHandle(link.getDirName(null));
+ try {
+ for(LinkHandle linkH : dir.getSortedLinksUnchecked())
+ {
+ _links.add(linkH.getTargetDirectoryUnchecked());
+ _map.put(linkH.getTargetDirectoryUnchecked().getPath(), linkH.getTargetDirectoryUnchecked());
+ }
+
+ while(_links.size() > _count)
+ {
+ link.doDeleteLink(_links.get(0));
+ _map.remove(_links.get(0).getPath());
+ _links.remove(0);
+ }
+ } catch (Exception e) {}
+ }
+ }
+ }
+
+ /*
+ * Handle the MKD command to make links
+ */
+ @EventSubscriber
+ public void onDirectoryFtpEvent(DirectoryFtpEvent event)
+ {
+ if(!event.getCommand().equalsIgnoreCase("MKD"))
+ return;
+
+ String rls = event.getDirectory().getPath().replaceAll(".*/(.*)", "$1");
+
+ for (LinkType link : _linkmanager.getLinks()) {
+ if (link.getEventType().equals("latestdir")) {
+ if(!rls.matches(link.getExclude()))
+ {
+ if(_map.get(event.getDirectory().getPath()) == null)
+ {
+ link.doCreateLink(event.getDirectory());
+ _links.add(event.getDirectory());
+ _map.put(event.getDirectory().getPath(), event.getDirectory());
+ }
+ if(_links.size() > _count)
+ {
+ link.doDeleteLink(_links.get(0));
+ _links.remove(0);
+ _map.remove(event.getDirectory().getPath());
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/build.xml b/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/build.xml
new file mode 100644
index 0000000..8c802e9
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/build.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/plugin.xml b/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/plugin.xml
new file mode 100644
index 0000000..f7358a6
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/plugin.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+ This plugin provides NfoMissing to the Link Manager
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/resources/conf/plugins/linkmanager.conf.dist b/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/resources/conf/plugins/linkmanager.conf.dist
new file mode 100644
index 0000000..1db267d
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/resources/conf/plugins/linkmanager.conf.dist
@@ -0,0 +1,20 @@
+################################################################################
+# NFOMISSING:
+#
+# This will find all directories excluding the REGEX set that do not
+# have an NFO and place a create a link to said directory in /_NO_NFO_
+#
+# x.addparentdir is used for only adding a missing link to folders
+# that have a match here, or a folder with no subfolders.
+# IE: /section1/sub-section1/rls1 - we don't want a no-nfo for sub-section1
+#
+# x.type=NFOMISSING
+# x.dirname=/_NO_NFO_
+# x.section=*
+# x.exclude=^/(.*)/(?i)(((cd|dvd|dis[ck])[1-9])|sample|subs|rarfix)$
+# x.sectionexclude=^(?i)(pre|staff|speedtests)$
+# x.deleteon=*
+# x.linkname=(no-nfo)-${dirname}
+# x.addparentdir=^(?i)(((cd|dvd|dis[ck])[1-9])|sample|subs|rarfix)$
+#
+################################################################################
\ No newline at end of file
diff --git a/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/src/org/drftpd/plugins/linkmanager/types/nfomissing/NFOMissing.java b/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/src/org/drftpd/plugins/linkmanager/types/nfomissing/NFOMissing.java
new file mode 100644
index 0000000..36bbaa0
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/src/org/drftpd/plugins/linkmanager/types/nfomissing/NFOMissing.java
@@ -0,0 +1,95 @@
+/*
+ * This file is part of DrFTPD, Distributed FTP Daemon.
+ *
+ * DrFTPD is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * DrFTPD is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * DrFTPD; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ */
+package org.drftpd.plugins.linkmanager.types.nfomissing;
+
+import java.io.FileNotFoundException;
+import java.util.Properties;
+import java.util.Set;
+
+import org.drftpd.plugins.linkmanager.LinkType;
+import org.drftpd.vfs.DirectoryHandle;
+import org.drftpd.vfs.FileHandle;
+
+/**
+ * @author CyBeR
+ * @version $Id: NFOMissing.java 1925 2009-06-15 21:46:05Z CyBeR $
+ */
+
+public class NFOMissing extends LinkType {
+
+ public NFOMissing(Properties p, int confnum, String type) {
+ super(p, confnum, type);
+ }
+
+ /*
+ * This checks if any Dir from inside the targetDir matches
+ * AddParentDir, and if it does, add the link, if not don't create one
+ *
+ * IE: /section/subsection/rls - we do not want a no nfo for /section/subsection
+ */
+ @Override
+ public void doCreateLink(DirectoryHandle targetDir) {
+ boolean foundMatch = false;
+ try {
+ Set dirs = targetDir.getDirectoriesUnchecked();
+ if (dirs.size() > 0) {
+ for (DirectoryHandle dir : dirs) {
+ if (dir.getPath().matches(getAddParentDir())) {
+ foundMatch = true;
+ }
+ }
+ } else {
+ // No SubDirs found - Create Link
+ foundMatch = true;
+ }
+ } catch (FileNotFoundException e) {
+ // targetDir No Longer Exists
+ }
+ if (foundMatch) {
+ createLink(targetDir,targetDir.getPath(),targetDir.getName());
+ }
+ }
+
+ /*
+ * This just passes the target dir through to creating the Link
+ * No special setup is needed for this type.
+ */
+ @Override
+ public void doDeleteLink(DirectoryHandle targetDir) {
+ deleteLink(targetDir,targetDir.getPath(),targetDir.getName());
+ }
+
+ /*
+ * This loops though the files, and checks to see if any end with .nfo
+ * If one does, it creates the link, if not, it deletes the link
+ */
+ @Override
+ public void doFixLink(DirectoryHandle targetDir) {
+ try {
+ for (FileHandle file : targetDir.getFilesUnchecked()) {
+ if (file.getName().toLowerCase().endsWith(".nfo")) {
+ doDeleteLink(targetDir);
+ return;
+ }
+ }
+ doCreateLink(targetDir);
+ } catch (FileNotFoundException e) {
+ // No Files found - Ignore
+ }
+ }
+
+}
diff --git a/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/src/org/drftpd/plugins/linkmanager/types/nfomissing/NFOMissingManager.java b/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/src/org/drftpd/plugins/linkmanager/types/nfomissing/NFOMissingManager.java
new file mode 100644
index 0000000..e57e513
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.linkmanager.nfomissing/src/org/drftpd/plugins/linkmanager/types/nfomissing/NFOMissingManager.java
@@ -0,0 +1,127 @@
+/*
+ * This file is part of DrFTPD, Distributed FTP Daemon.
+ *
+ * DrFTPD is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * DrFTPD is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * DrFTPD; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ */
+package org.drftpd.plugins.linkmanager.types.nfomissing;
+
+import java.io.FileNotFoundException;
+
+import org.bushe.swing.event.annotation.AnnotationProcessor;
+import org.bushe.swing.event.annotation.EventSubscriber;
+import org.drftpd.PluginInterface;
+import org.drftpd.event.DirectoryFtpEvent;
+import org.drftpd.event.ReloadEvent;
+import org.drftpd.event.TransferEvent;
+import org.drftpd.plugins.linkmanager.LinkManager;
+import org.drftpd.plugins.linkmanager.LinkType;
+import org.drftpd.vfs.FileHandle;
+import org.drftpd.vfs.event.VirtualFileSystemInodeDeletedEvent;
+
+/**
+ * @author CyBeR
+ * @version $Id: NFOMissingManager.java 1925 2009-06-15 21:46:05Z CyBeR $
+ */
+
+public class NFOMissingManager implements PluginInterface {
+ private LinkManager _linkmanager;
+
+ @Override
+ public void startPlugin() {
+ AnnotationProcessor.process(this);
+ loadManager();
+ }
+
+ @Override
+ public void stopPlugin(String reason) {
+ AnnotationProcessor.unprocess(this);
+ }
+
+ @EventSubscriber
+ public void onReloadEvent(ReloadEvent event) {
+ loadManager();
+ }
+
+ private void loadManager() {
+ _linkmanager = LinkManager.getLinkManager();
+ }
+
+ /*
+ * Checks to see if the file uploaded ends with .nfo
+ * If it does, it deletes the link associated with this folder
+ */
+ @EventSubscriber
+ public void onTransferEvent(TransferEvent event) {
+ if (!event.getCommand().equals("STOR")) {
+ return;
+ }
+
+ if (event.getTransferFile().getName().toLowerCase().endsWith(".nfo")) {
+ for (LinkType link : _linkmanager.getLinks()) {
+ if (link.getEventType().equals("nfomissing")) {
+ link.doDeleteLink(event.getDirectory());
+ }
+ }
+ }
+ }
+
+ /*
+ * Creates missing NFO on new DIR creation
+ *
+ * Using DirectryFtpEvent vs VirtualFileSystemInodeCreatedEvent because
+ * the VFS event is only called AFTER the dir is created in the VFS, which
+ * could cause a problem if the .nfo file was uploaded first, and the asyncevent
+ * for the .nfo was before vfs event.
+ */
+ @EventSubscriber
+ public void onDirectoryFtpEvent(DirectoryFtpEvent direvent) {
+ if ("MKD".equals(direvent.getCommand())) {
+ for (LinkType link : _linkmanager.getLinks()) {
+ if (link.getEventType().equals("nfomissing")) {
+ link.doCreateLink(direvent.getDirectory());
+ }
+ }
+ }
+ }
+
+
+ /*
+ * This checks to see if there is first a SECOND nfo file in the dir. If there is is
+ * promptly exists. If there isn't after the delete event, it re-adds a link
+ * for this directory.
+ */
+ @EventSubscriber
+ public void onVirtualFileSystemInodeDeletedEvent(VirtualFileSystemInodeDeletedEvent vfsevent) {
+ if (vfsevent.getInode().isFile()) {
+ if (vfsevent.getInode().getParent().exists()) {
+ try {
+ for (FileHandle file : vfsevent.getInode().getParent().getFilesUnchecked()) {
+ if ((file.getPath().toLowerCase().endsWith(".nfo")) && (!file.getPath().equals(vfsevent.getInode().getPath()))) {
+ return;
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // files not found....dir must not longer exist - Ignore
+ }
+
+ }
+ for (LinkType link : _linkmanager.getLinks()) {
+ if (link.getEventType().equals("nfomissing")) {
+ link.doCreateLink(vfsevent.getInode().getParent());
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/plugins/org.drftpd.plugins.newlink/build.xml b/src/plugins/org.drftpd.plugins.newlink/build.xml
new file mode 100644
index 0000000..40f41ef
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newlink/build.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/org.drftpd.plugins.newlink/plugin.xml b/src/plugins/org.drftpd.plugins.newlink/plugin.xml
new file mode 100644
index 0000000..1a208fe
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newlink/plugin.xml
@@ -0,0 +1,34 @@
+
+
+
+
+ Creates symlink for last uploaded/pre
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/org.drftpd.plugins.newlink/resources/conf/plugins/newlink.conf.dist b/src/plugins/org.drftpd.plugins.newlink/resources/conf/plugins/newlink.conf.dist
new file mode 100644
index 0000000..da46cff
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newlink/resources/conf/plugins/newlink.conf.dist
@@ -0,0 +1,11 @@
+#Do not create link if dir name equals
+newlinks.exclude=cd1;cd2;cd3;cd4;cd5;disk1;disk2;disk3;disk4;disk5;sample;covers;cover;ac3;addon
+
+#do not create link for thoses sections
+newlinks.excludesec=pre;groups
+
+#where to store links
+newlinks.basefolder=/
+
+#max new links to keep
+newlinks.maxlinks=1
\ No newline at end of file
diff --git a/src/plugins/org.drftpd.plugins.newlink/src/org/drftpd/plugins/newlink/NewLinkPostHook.java b/src/plugins/org.drftpd.plugins.newlink/src/org/drftpd/plugins/newlink/NewLinkPostHook.java
new file mode 100644
index 0000000..e217e62
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newlink/src/org/drftpd/plugins/newlink/NewLinkPostHook.java
@@ -0,0 +1,235 @@
+package org.drftpd.plugins.newlink;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.bushe.swing.event.annotation.EventSubscriber;
+import org.drftpd.GlobalContext;
+import org.drftpd.TimeComparator;
+import org.drftpd.commandmanager.CommandRequest;
+import org.drftpd.commandmanager.CommandResponse;
+import org.drftpd.commandmanager.PostHookInterface;
+import org.drftpd.commandmanager.StandardCommandManager;
+import org.drftpd.event.ReloadEvent;
+import org.drftpd.exceptions.FileExistsException;
+import org.drftpd.sections.SectionInterface;
+import org.drftpd.vfs.DirectoryHandle;
+import org.drftpd.vfs.LinkHandle;
+import org.drftpd.vfs.ObjectNotValidException;
+import org.drftpd.vfs.VirtualFileSystem;
+
+public class NewLinkPostHook implements PostHookInterface {
+ private static final Logger logger = Logger
+ .getLogger(NewLinkPostHook.class);
+
+ private String[] _excludeDirs, _excludeSections;
+ private String _baseDir;
+ private int _maxLinks;
+ private boolean _preEnabled;
+
+ @Override
+ public void initialize(StandardCommandManager manager) {
+ // TODO Auto-generated method stub
+ logger.info("Starting NewDir plugin");
+ loadConf();
+ }
+
+ private void loadConf() {
+ // TODO Auto-generated method stub
+ Properties cfg = GlobalContext.getGlobalContext().getPluginsConfig()
+ .getPropertiesForPlugin("newlink.conf");
+ if (cfg == null) {
+ logger.fatal("conf/plugins/newlink.conf not found");
+ return;
+ }
+ _excludeDirs = cfg.getProperty("newlinks.exclude").trim().split(";");
+ _excludeSections = cfg.getProperty("newlinks.excludesec").trim().split(
+ ";");
+ _baseDir = cfg.getProperty("newlinks.basefolder").trim();
+ _preEnabled = Boolean.parseBoolean(cfg.getProperty("newlinks.showpre"));
+
+ try {
+ _maxLinks = Integer.parseInt(cfg.getProperty("newlinks.maxlinks")
+ .trim());
+ } catch (NumberFormatException e) {
+ _maxLinks = 1;
+ throw new RuntimeException(
+ "Unspecified value 'newlinks.maxlinks' in newlink.conf");
+ }
+
+ if (_excludeDirs == null) {
+ throw new RuntimeException(
+ "Unspecified value 'newlinks.exclude' in newlink.conf");
+ }
+ if (_excludeSections == null) {
+ throw new RuntimeException(
+ "Unspecified value 'newlinks.excludesec' in newlink.conf");
+ }
+ if (_baseDir == null) {
+ throw new RuntimeException(
+ "Unspecified value 'newlinks.basefolder' in newlink.conf");
+ }
+ if (!_baseDir.endsWith("/")) {
+ _baseDir += "/";
+ }
+ }
+
+ public void createLastRaceLink(CommandRequest request,
+ CommandResponse response) {
+ if (response.getCode() != 257) {
+ // MKD failed
+ return;
+ }
+
+ String newDir = request.getArgument();
+ String sectionName = null;
+ DirectoryHandle targetDir = null;
+
+ if (newDir.indexOf("/") != -1) {
+ newDir = newDir.substring(1);
+ newDir = newDir.substring(newDir.indexOf("/")+1, newDir.length());
+ sectionName = request.getArgument().substring(1);
+ sectionName = sectionName.substring(0, sectionName.indexOf("/"));
+ } else {
+ sectionName = request.getCurrentDirectory().getName();
+ }
+
+ for (int i = 0; i < _excludeSections.length; i++) {
+ if (sectionName.equalsIgnoreCase(_excludeSections[i]))
+ return;
+ }
+ for (int i = 0; i < _excludeDirs.length; i++) {
+ if (newDir.toLowerCase().contains(_excludeDirs[i]))
+ return;
+ }
+
+ SectionInterface section = GlobalContext.getGlobalContext()
+ .getSectionManager().getSection(sectionName);
+
+ try {
+ targetDir = section.getBaseDirectory().getDirectoryUnchecked(
+ newDir);
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ return;
+ } catch (ObjectNotValidException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ createLink(targetDir, sectionName, newDir, false);
+ }
+
+ public void createLastPreLink(CommandRequest request,
+ CommandResponse response) {
+ if (response.getCode() != 250) {
+ // PRE failed
+ return;
+ }
+
+ String newDir = null;
+ String sectionName = null;
+ DirectoryHandle targetDir = null;
+
+ String[] args = request.getArgument().split(" ");
+ newDir = args[0];
+ sectionName = args[1];
+
+ SectionInterface section = GlobalContext.getGlobalContext()
+ .getSectionManager().getSection(sectionName);
+ try {
+ targetDir = section.getCurrentDirectory()
+ .getDirectoryUnchecked(newDir);
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ return;
+ } catch (ObjectNotValidException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ createLink(targetDir, sectionName, newDir, true);
+ }
+
+ public void createLink(DirectoryHandle targetDir, String sectionName,
+ String newDir, boolean isPre) {
+
+ DirectoryHandle newLinkDir = null;
+ Set links = null;
+ ArrayList newDirLinks = new ArrayList();
+ ArrayList newPreLinks = new ArrayList();
+ try {
+
+ if (_baseDir.equals(VirtualFileSystem.separator)) {
+ newLinkDir = GlobalContext.getGlobalContext().getRoot();
+ } else {
+ newLinkDir = GlobalContext.getGlobalContext().getRoot()
+ .getDirectoryUnchecked(_baseDir);
+ }
+
+ links = newLinkDir.getLinksUnchecked();
+
+ Iterator iter = links.iterator();
+ while (iter.hasNext()) {
+ LinkHandle linkHandle = iter.next();
+ if (linkHandle.getName().startsWith("[LastPre]-")) {
+ newPreLinks.add(linkHandle);
+ } else if (linkHandle.getName().startsWith("[LastRace]-")) {
+ newDirLinks.add(linkHandle);
+ }
+ }
+
+ if (isPre && newPreLinks.size() >= _maxLinks) {
+ Collections.sort(newPreLinks, new TimeComparator());
+ LinkHandle oldestLink = newPreLinks.get(newPreLinks.size() - 1);
+ if (oldestLink.isLink()) {
+ try {
+ oldestLink.deleteUnchecked();
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ }
+ }
+ }
+
+ if (!isPre && newDirLinks.size() >= _maxLinks) {
+ Collections.sort(newDirLinks, new TimeComparator());
+ LinkHandle oldestLink = newDirLinks.get(newDirLinks.size() - 1);
+ if (oldestLink.isLink()) {
+ try {
+ oldestLink.deleteUnchecked();
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ }
+ }
+ }
+
+ if (isPre) {
+ newLinkDir.createLinkUnchecked("[LastPre]-[" + sectionName
+ + "]-" + newDir, targetDir.getPath(), "drftpd",
+ "drftpd");
+ } else {
+ newLinkDir.createLinkUnchecked("[LastRace]-[" + sectionName
+ + "]-" + newDir, targetDir.getPath(), "drftpd",
+ "drftpd");
+ }
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ logger.error("newlinkerror: " + e.getMessage());
+ } catch (ObjectNotValidException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (FileExistsException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @EventSubscriber
+ public void onReloadEvent(ReloadEvent event) {
+ loadConf();
+ }
+
+}
diff --git a/src/plugins/org.drftpd.plugins.newraceleader/build.xml b/src/plugins/org.drftpd.plugins.newraceleader/build.xml
new file mode 100644
index 0000000..4eac08a
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newraceleader/build.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/org.drftpd.plugins.newraceleader/plugin.xml b/src/plugins/org.drftpd.plugins.newraceleader/plugin.xml
new file mode 100644
index 0000000..522827f
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newraceleader/plugin.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+ This plugin provides New Race Leader Announces.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/NewRaceLeader.java b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/NewRaceLeader.java
new file mode 100644
index 0000000..a4dac41
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/NewRaceLeader.java
@@ -0,0 +1,82 @@
+/*
+ * This file is part of DrFTPD, Distributed FTP Daemon.
+ *
+ * DrFTPD is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by
+ * the Free Software Foundation; either version 2 of the
+ * License, or
+ * (at your option) any later version.
+ *
+ * DrFTPD is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General
+ * Public License
+ * along with DrFTPD; if not, write to the Free
+ * Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ */
+
+package org.drftpd.plugins.newraceleader;
+
+import java.util.Collection;
+
+import org.drftpd.GlobalContext;
+import org.drftpd.plugins.newraceleader.event.NewRaceLeaderEvent;
+import org.drftpd.util.UploaderPosition;
+import org.drftpd.vfs.DirectoryHandle;
+import org.drftpd.vfs.FileHandle;
+
+/**
+ * @author CyBeR
+ * @version $Id: NewRaceLeader.java 2393 2011-04-11 20:47:51Z cyber1331 $
+ */
+public class NewRaceLeader {
+ private DirectoryHandle _dir;
+ private long _time;
+ private String _winner;
+
+ public NewRaceLeader(FileHandle file,Collection uploaderposition, String nick) {
+ _dir = file.getParent();
+ _time = System.currentTimeMillis();
+
+ if (uploaderposition.iterator().hasNext()) {
+ _winner = uploaderposition.iterator().next().getUsername();
+ } else {
+ _winner = nick;
+ }
+
+ }
+
+ public DirectoryHandle getDir() {
+ return _dir;
+ }
+
+ public long getTime() {
+ return _time;
+ }
+
+ public String getWinner() {
+ return _winner;
+ }
+
+ public void check(String user, int missing, int files, Collection racers) {
+ UploaderPosition uploaderposition = racers.iterator().next();
+ if ((uploaderposition.getUsername().equals(user)) && (!user.equals(_winner))) {
+
+ // Ignore on halfway as we already announce leader during this point
+ int halfway = (int) Math.floor((double) files / 2);
+ if (missing != halfway) {
+ GlobalContext.getEventService().publishAsync(new NewRaceLeaderEvent(user,_winner,getDir(),uploaderposition, missing));
+ }
+
+ _winner = user;
+ }
+ }
+}
diff --git a/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/NewRaceLeaderHooks.java b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/NewRaceLeaderHooks.java
new file mode 100644
index 0000000..a3bc556
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/NewRaceLeaderHooks.java
@@ -0,0 +1,100 @@
+/*
+ * This file is part of DrFTPD, Distributed FTP Daemon.
+ *
+ * DrFTPD is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * DrFTPD is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * DrFTPD; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ */
+package org.drftpd.plugins.newraceleader;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Collection;
+
+import org.drftpd.RankUtils;
+import org.drftpd.commandmanager.CommandRequest;
+import org.drftpd.commandmanager.CommandResponse;
+import org.drftpd.commandmanager.PostHookInterface;
+import org.drftpd.commandmanager.StandardCommandManager;
+import org.drftpd.commands.dataconnection.DataConnectionHandler;
+import org.drftpd.commands.zipscript.SFVTools;
+import org.drftpd.commands.zipscript.vfs.ZipscriptVFSDataSFV;
+import org.drftpd.dynamicdata.KeyNotFoundException;
+import org.drftpd.exceptions.NoAvailableSlaveException;
+import org.drftpd.exceptions.SlaveUnavailableException;
+import org.drftpd.protocol.zipscript.common.SFVInfo;
+import org.drftpd.protocol.zipscript.common.SFVStatus;
+import org.drftpd.util.UploaderPosition;
+import org.drftpd.vfs.FileHandle;
+
+/**
+ * @author CyBeR
+ * @version $Id: NewRaceLeaderHooks.java 2393 2011-04-11 20:47:51Z cyber1331 $
+ */
+public class NewRaceLeaderHooks implements PostHookInterface {
+
+ private NewRaceLeaderManager _newraceleadermanager;
+
+ public void initialize(StandardCommandManager cManager) {
+ _newraceleadermanager = NewRaceLeaderManager.getNewRaceLeaderManager();
+ }
+
+ public void doSTORPostHook(CommandRequest request, CommandResponse response) {
+ if (response.getCode() != 226) {
+ // Transfer failed, abort checks
+ return;
+ }
+
+ FileHandle transferFile;
+ try {
+ transferFile = response.getObject(DataConnectionHandler.TRANSFER_FILE);
+ } catch (KeyNotFoundException e) {
+ // We don't have a file, we shouldn't have ended up here but return anyway
+ return;
+ }
+
+ if (transferFile.getName().contains(".*\\.(sfv|nfo|diz)$")) {
+ // no need to check as these files do not matter
+ return;
+ }
+
+ ZipscriptVFSDataSFV sfvData = new ZipscriptVFSDataSFV(transferFile.getParent());
+ try {
+ SFVInfo sfvinfo = sfvData.getSFVInfo();
+ // Make sure release is > 5 files (No point in spaming a small release
+ if (sfvinfo.getSize() > 5) {
+ SFVStatus sfvstatus = sfvData.getSFVStatus();
+ Collection racers = RankUtils.userSort(SFVTools.getSFVFiles(transferFile.getParent(), sfvData),"bytes", "high");
+
+ // Check if file uploaded is in SFV
+ if (sfvinfo.getEntries().get(transferFile.getName()) == null) {
+ return;
+ }
+
+ // Check if release is finished
+ if (sfvstatus.isFinished()) {
+ _newraceleadermanager.delete(transferFile.getParent());
+ } else {
+ _newraceleadermanager.check(transferFile,sfvstatus.getMissing(),sfvinfo.getSize(),racers);
+ }
+ }
+ } catch (FileNotFoundException ex) {
+ //no SFV file - Ignore
+ } catch (IOException ex) {
+ //cannot't read sfv file - Ignore
+ } catch (NoAvailableSlaveException e) {
+ //No slaves with SFV - Ignore
+ } catch (SlaveUnavailableException e) {
+ //No slaves with SFV - Ignore
+ }
+ }
+}
diff --git a/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/NewRaceLeaderManager.java b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/NewRaceLeaderManager.java
new file mode 100644
index 0000000..89c55f4
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/NewRaceLeaderManager.java
@@ -0,0 +1,145 @@
+/*
+ * This file is part of DrFTPD, Distributed FTP Daemon.
+ *
+ * DrFTPD is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by
+ * the Free Software Foundation; either version 2 of the
+ * License, or
+ * (at your option) any later version.
+ *
+ * DrFTPD is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General
+ * Public License
+ * along with DrFTPD; if not, write to the Free
+ * Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ */
+
+package org.drftpd.plugins.newraceleader;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.TimerTask;
+
+import org.apache.log4j.Logger;
+import org.bushe.swing.event.annotation.AnnotationProcessor;
+import org.drftpd.GlobalContext;
+import org.drftpd.PluginInterface;
+import org.drftpd.util.UploaderPosition;
+import org.drftpd.vfs.DirectoryHandle;
+import org.drftpd.vfs.FileHandle;
+
+/**
+ * @author CyBeR
+ * @version $Id: NewRaceLeaderManager.java 2393 2011-04-11 20:47:51Z cyber1331 $
+ */
+public class NewRaceLeaderManager implements PluginInterface {
+ private static final Logger logger = Logger.getLogger(NewRaceLeaderManager.class);
+
+ private static final long _delay = 1800000; // = 30 minutes
+
+ private ArrayList _newraceleader;
+ private TimerTask _newraceleaderTimer;
+
+ @Override
+ public void startPlugin() {
+ AnnotationProcessor.process(this);
+ _newraceleader = new ArrayList();
+
+ _newraceleaderTimer = new TimerTask() {
+ public void run() {
+ cleanOldRaces();
+ }
+ };
+
+ try {
+ GlobalContext.getGlobalContext().getTimer().schedule(_newraceleaderTimer,_delay,_delay);
+ } catch (IllegalArgumentException e) {
+ logger.error("Failed to start newraceleader timer: ",e);
+ } catch (IllegalStateException e) {
+ logger.error("Failed to restart newraceleader timer: ",e);
+ }
+ }
+
+ private void cleanOldRaces() {
+ synchronized (_newraceleader) {
+ for (Iterator iter = _newraceleader.iterator(); iter.hasNext();) {
+ NewRaceLeader nrl = iter.next();
+ if ((nrl.getTime() + _delay + 5000) < System.currentTimeMillis()) {
+ logger.debug("Successfully age-deleted NewRaceLeader for: " + nrl.getDir().getPath());
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void stopPlugin(String reason) {
+ AnnotationProcessor.unprocess(this);
+ synchronized (this) {
+ _newraceleader = new ArrayList();
+ }
+ if (_newraceleaderTimer != null) {
+ _newraceleaderTimer.cancel();
+ }
+ GlobalContext.getGlobalContext().getTimer().purge();
+ }
+
+ /*
+ * Get the NewRaceLEader Plugin
+ */
+ public static NewRaceLeaderManager getNewRaceLeaderManager() {
+ for (PluginInterface plugin : GlobalContext.getGlobalContext().getPlugins()) {
+ if (plugin instanceof NewRaceLeaderManager) {
+ return (NewRaceLeaderManager) plugin;
+ }
+ }
+ throw new RuntimeException("NewRaceLeaderManager plugin is not loaded.");
+ }
+
+ public void delete(DirectoryHandle dir) {
+ synchronized (_newraceleader) {
+ for (Iterator iter = _newraceleader.iterator(); iter.hasNext();) {
+ NewRaceLeader nrl = iter.next();
+ if (nrl.getDir().getPath().equals(dir.getPath())) {
+ logger.debug("Successfully deleted NewRaceLeader for: " + nrl.getDir().getPath());
+ iter.remove();
+ break;
+ }
+ }
+ }
+ }
+
+ public synchronized void check(FileHandle file, int missing, int files, Collection racers) {
+ for (NewRaceLeader nrl : _newraceleader) {
+ if (nrl.getDir().getPath().equals(file.getParent().getPath())) {
+ try {
+ if (racers.size() > 1) {
+ nrl.check(file.getUsername(),missing,files,racers);
+ }
+ return;
+ } catch (FileNotFoundException e) {
+ // File no longer exists??
+ return;
+ }
+ }
+ }
+ try {
+ _newraceleader.add(new NewRaceLeader(file,racers,file.getUsername()));
+ } catch (FileNotFoundException e) {
+ // File No longer exists
+ // Ignore
+ }
+
+ }
+}
diff --git a/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/announce/NewRaceLeaderAnnouncer.irc.properties b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/announce/NewRaceLeaderAnnouncer.irc.properties
new file mode 100644
index 0000000..3cfdc5f
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/announce/NewRaceLeaderAnnouncer.irc.properties
@@ -0,0 +1 @@
+store.newraceleader=${color}15${bold}NEW RACE LEADER${bold}${coloroff} in ${color}15${bold}${section}${bold}${coloroff}: -> ${bold}${dir} : ${prevuser}${bold} has been surpassed by ${bold}${leaduser}${bold} [${size}/${files}F/${percent}%/${speed}/s] with ${bold}${filesleft}${bold} files left.
\ No newline at end of file
diff --git a/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/announce/NewRaceLeaderAnnouncer.java b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/announce/NewRaceLeaderAnnouncer.java
new file mode 100644
index 0000000..dade6ca
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/announce/NewRaceLeaderAnnouncer.java
@@ -0,0 +1,94 @@
+/*
+ * This file is part of DrFTPD, Distributed FTP Daemon.
+ *
+ * DrFTPD is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrFTPD is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrFTPD; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package org.drftpd.plugins.newraceleader.announce;
+
+import java.util.ResourceBundle;
+
+import org.apache.log4j.Logger;
+import org.bushe.swing.event.annotation.AnnotationProcessor;
+import org.bushe.swing.event.annotation.EventSubscriber;
+
+import org.drftpd.Bytes;
+import org.drftpd.plugins.newraceleader.event.NewRaceLeaderEvent;
+import org.drftpd.plugins.sitebot.AbstractAnnouncer;
+import org.drftpd.plugins.sitebot.AnnounceWriter;
+import org.drftpd.plugins.sitebot.SiteBot;
+import org.drftpd.plugins.sitebot.config.AnnounceConfig;
+
+import org.drftpd.util.ReplacerUtils;
+
+import org.tanesha.replacer.ReplacerEnvironment;
+
+/**
+ * @author CyBeR
+ * @version $Id: NewRaceLeaderAnnouncer.java 2393 2011-04-11 20:47:51Z cyber1331 $
+ */
+public class NewRaceLeaderAnnouncer extends AbstractAnnouncer {
+
+ private static final Logger logger = Logger.getLogger(NewRaceLeaderAnnouncer.class);
+
+ private AnnounceConfig _config;
+
+ private ResourceBundle _bundle;
+
+ private String _keyPrefix;
+
+ public void initialise(AnnounceConfig config, ResourceBundle bundle) {
+ _config = config;
+ _bundle = bundle;
+ _keyPrefix = this.getClass().getName();
+ // Subscribe to events
+ AnnotationProcessor.process(this);
+ }
+
+ public void stop() {
+ AnnotationProcessor.unprocess(this);
+ logger.debug("Unloaded NewRaceLeader");
+ }
+
+ public String[] getEventTypes() {
+ String[] types = {"store.newraceleader"};
+ return types;
+ }
+
+ public void setResourceBundle(ResourceBundle bundle) {
+ _bundle = bundle;
+ }
+
+ @EventSubscriber
+ public void onNewRaceLeaderEvent(NewRaceLeaderEvent event) {
+ ReplacerEnvironment env = new ReplacerEnvironment(SiteBot.GLOBAL_ENV);
+ AnnounceWriter writer = _config.getPathWriter("store.newraceleader", event.getDirectory());
+ if (writer != null) {
+ env.add("section",writer.getSectionName(event.getDirectory()));
+ env.add("dir",writer.getPath(event.getDirectory()));
+
+ env.add("path",event.getDirectory().getPath());
+ env.add("filesleft", event.getFiles());
+ env.add("leaduser", event.getUser());
+ env.add("prevuser", event.getPrevUser());
+
+ env.add("size",Bytes.formatBytes(event.getUploaderPosition().getBytes()));
+ env.add("files", event.getUploaderPosition().getFiles());
+ env.add("speed", Bytes.formatBytes(event.getUploaderPosition().getXferspeed()));
+ env.add("percent", new Integer(event.getFiles() / event.getUploaderPosition().getFiles()));
+
+ sayOutput(ReplacerUtils.jprintf(_keyPrefix+".store.newraceleader", env, _bundle), writer);
+ }
+ }
+}
diff --git a/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/event/NewRaceLeaderEvent.java b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/event/NewRaceLeaderEvent.java
new file mode 100644
index 0000000..2ef453f
--- /dev/null
+++ b/src/plugins/org.drftpd.plugins.newraceleader/src/org/drftpd/plugins/newraceleader/event/NewRaceLeaderEvent.java
@@ -0,0 +1,61 @@
+/*
+ * This file is part of DrFTPD, Distributed FTP Daemon.
+ *
+ * DrFTPD is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * DrFTPD is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * DrFTPD; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ */
+package org.drftpd.plugins.newraceleader.event;
+
+import org.drftpd.util.UploaderPosition;
+import org.drftpd.vfs.DirectoryHandle;
+
+/**
+ * @author CyBeR
+ * @version $Id: NewRaceLeaderEvent.java 1925 2009-06-15 21:46:05Z CyBeR $
+ */
+public class NewRaceLeaderEvent {
+
+ private String _user;
+ private String _prevuser;
+ private DirectoryHandle _dir;
+ private UploaderPosition _uploaderposition;
+ private int _files;
+
+ public NewRaceLeaderEvent(String user, String prevuser, DirectoryHandle dir, UploaderPosition uploaderposition, int files) {
+ _user = user;
+ _prevuser = prevuser;
+ _dir = dir;
+ _files = files;
+ _uploaderposition = uploaderposition;
+ }
+
+ public String getUser() {
+ return _user;
+ }
+
+ public String getPrevUser() {
+ return _prevuser;
+ }
+
+ public DirectoryHandle getDirectory() {
+ return _dir;
+ }
+
+ public UploaderPosition getUploaderPosition() {
+ return _uploaderposition;
+ }
+
+ public int getFiles() {
+ return _files;
+ }
+}
\ No newline at end of file