001: /*
002: * This file is part of DrFTPD, Distributed FTP Daemon.
003: *
004: * DrFTPD is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * DrFTPD is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with DrFTPD; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018: package org.drftpd.commands;
019:
020: import java.io.IOException;
021: import java.util.ArrayList;
022: import java.util.Collection;
023: import java.util.Collections;
024: import java.util.Date;
025: import java.util.Iterator;
026: import java.util.StringTokenizer;
027:
028: import net.sf.drftpd.master.BaseFtpConnection;
029: import net.sf.drftpd.master.FtpRequest;
030: import net.sf.drftpd.master.command.CommandManager;
031: import net.sf.drftpd.master.command.CommandManagerFactory;
032: import net.sf.drftpd.master.command.plugins.Textoutput;
033: import net.sf.drftpd.master.config.FtpConfig;
034: import net.sf.drftpd.util.UserComparator;
035:
036: import org.apache.log4j.Level;
037: import org.apache.log4j.Logger;
038: import org.drftpd.Bytes;
039: import org.drftpd.permissions.Permission;
040: import org.drftpd.plugins.Trial;
041: import org.drftpd.usermanager.NoSuchUserException;
042: import org.drftpd.usermanager.User;
043: import org.drftpd.usermanager.UserFileException;
044: import org.drftpd.usermanager.UserManager;
045: import org.tanesha.replacer.ReplacerEnvironment;
046:
047: /**
048: * @version $Id: TransferStatistics.java 953 2005-02-04 01:17:59Z teflon $
049: */
050: public class TransferStatistics implements CommandHandler,
051: CommandHandlerFactory {
052: private static final Logger logger = Logger
053: .getLogger(TransferStatistics.class);
054:
055: public static long getStats(String command, User user) {
056: // AL MONTH WK DAY
057: String period = command.substring(0, command.length() - 2)
058: .toUpperCase();
059:
060: // UP DN
061: String updn = command.substring(command.length() - 2)
062: .toUpperCase();
063:
064: if (updn.equals("UP")) {
065: if (period.equals("AL")) {
066: return user.getUploadedBytes();
067: }
068:
069: if (period.equals("DAY")) {
070: return user.getUploadedBytesDay();
071: }
072:
073: if (period.equals("WK")) {
074: return user.getUploadedBytesWeek();
075: }
076:
077: if (period.equals("MONTH")) {
078: return user.getUploadedBytesMonth();
079: }
080: } else if (updn.equals("DN")) {
081: if (period.equals("AL")) {
082: return user.getDownloadedBytes();
083: }
084:
085: if (period.equals("DAY")) {
086: return user.getDownloadedBytesDay();
087: }
088:
089: if (period.equals("WK")) {
090: return user.getDownloadedBytesWeek();
091: }
092:
093: if (period.equals("MONTH")) {
094: return user.getDownloadedBytesMonth();
095: }
096: }
097:
098: throw new RuntimeException(UnhandledCommandException.create(
099: TransferStatistics.class, command));
100: }
101:
102: public static long getFiles(String command, User user) {
103: // AL MONTH WK DAY
104: String period = command.substring(0, command.length() - 2);
105:
106: // UP DN
107: String updn = command.substring(command.length() - 2);
108:
109: if (updn.equals("UP")) {
110: if (period.equals("AL")) {
111: return user.getUploadedFiles();
112: }
113:
114: if (period.equals("DAY")) {
115: return user.getUploadedFilesDay();
116: }
117:
118: if (period.equals("WK")) {
119: return user.getUploadedFilesWeek();
120: }
121:
122: if (period.equals("MONTH")) {
123: return user.getUploadedFilesMonth();
124: }
125: } else if (updn.equals("DN")) {
126: if (period.equals("AL")) {
127: return user.getDownloadedFiles();
128: }
129:
130: if (period.equals("DAY")) {
131: return user.getDownloadedFilesDay();
132: }
133:
134: if (period.equals("WK")) {
135: return user.getDownloadedFilesWeek();
136: }
137:
138: if (period.equals("MONTH")) {
139: return user.getDownloadedFilesMonth();
140: }
141: }
142:
143: throw new RuntimeException(UnhandledCommandException.create(
144: TransferStatistics.class, command));
145: }
146:
147: public static int getStatsPlace(String command, User user,
148: UserManager userman) {
149: // AL MONTH WK DAY
150: int place = 1;
151: long bytes = getStats(command, user);
152: Collection users;
153:
154: try {
155: users = userman.getAllUsers();
156: } catch (UserFileException e) {
157: logger.error("IO error:", e);
158:
159: return 0;
160: }
161:
162: for (Iterator iter = users.iterator(); iter.hasNext();) {
163: User tempUser = (User) iter.next();
164: long tempBytes = getStats(command, tempUser);
165:
166: if (tempBytes > bytes) {
167: place++;
168: }
169: }
170:
171: return place;
172: }
173:
174: /**
175: * USAGE: site stats [<user>]
176: * Display a user's upload/download statistics.
177: */
178: public Reply doSITE_STATS(BaseFtpConnection conn) {
179: FtpRequest request = conn.getRequest();
180:
181: if (!request.hasArgument()) {
182: return Reply.RESPONSE_501_SYNTAX_ERROR;
183: }
184:
185: User user;
186:
187: if (!request.hasArgument()) {
188: user = conn.getUserNull();
189: } else {
190: try {
191: user = conn.getGlobalContext().getUserManager()
192: .getUserByName(request.getArgument());
193: } catch (NoSuchUserException e) {
194: return new Reply(200, "No such user: " + e.getMessage());
195: } catch (UserFileException e) {
196: logger.log(Level.WARN, "", e);
197:
198: return new Reply(200, e.getMessage());
199: }
200: }
201:
202: if (conn.getUserNull().isGroupAdmin()
203: && !conn.getUserNull().getGroup().equals(
204: user.getGroup())) {
205: return Reply.RESPONSE_530_ACCESS_DENIED;
206: } else if (!conn.getUserNull().isAdmin()
207: && !user.equals(conn.getUserNull())) {
208: return Reply.RESPONSE_530_ACCESS_DENIED;
209: }
210:
211: Reply response = (Reply) Reply.RESPONSE_200_COMMAND_OK.clone();
212: UserManager userman = conn.getGlobalContext().getUserManager();
213: response.addComment("created: "
214: + user.getKeyedMap().getObject(UserManagement.CREATED,
215: ""));
216: response.addComment("rank alup: "
217: + getStatsPlace("ALUP", user, userman));
218: response.addComment("rank aldn: "
219: + getStatsPlace("ALDN", user, userman));
220: response.addComment("rank monthup: "
221: + getStatsPlace("MONTHUP", user, userman));
222: response.addComment("rank monthdn: "
223: + getStatsPlace("MONTHDN", user, userman));
224: response.addComment("rank wkup: "
225: + getStatsPlace("WKUP", user, userman));
226: response.addComment("rank wkdn: "
227: + getStatsPlace("WKDN", user, userman));
228:
229: // response.addComment("races won: " + user.getObject2());
230: // response.addComment("races lost: " + user.getRacesLost());
231: // response.addComment("races helped: " + user.getRacesParticipated());
232: // response.addComment("requests made: " + user.getRequests());
233: // response.addComment("requests filled: " + user.getRequestsFilled());
234: // response.addComment("nuked " + user.getTimesNuked() + " times for " +
235: // user.getNukedBytes() + " bytes");
236: response.addComment(" FILES BYTES");
237: response.addComment("ALUP " + user.getUploadedFiles() + " "
238: + Bytes.formatBytes(user.getUploadedBytes()));
239: response.addComment("ALDN " + user.getDownloadedFiles() + " "
240: + Bytes.formatBytes(user.getDownloadedBytes()));
241: response
242: .addComment("MNUP "
243: + user.getUploadedFilesMonth()
244: + " "
245: + Bytes.formatBytes(user
246: .getUploadedBytesMonth()));
247: response.addComment("MNDN " + user.getDownloadedFilesMonth()
248: + " "
249: + Bytes.formatBytes(user.getDownloadedBytesMonth()));
250: response.addComment("WKUP " + user.getUploadedFilesWeek()
251: + " " + Bytes.formatBytes(user.getUploadedBytesWeek()));
252: response.addComment("WKDN " + user.getDownloadedFilesWeek()
253: + " "
254: + Bytes.formatBytes(user.getDownloadedBytesWeek()));
255: response.addComment("DAYUP " + user.getUploadedFilesDay()
256: + " "
257: + Bytes.formatBytes(user.getUploadedBytesDay()));
258: response.addComment("DAYDN " + user.getDownloadedFilesDay()
259: + " "
260: + Bytes.formatBytes(user.getDownloadedBytesDay()));
261:
262: return response;
263: }
264:
265: public Reply execute(BaseFtpConnection conn)
266: throws UnhandledCommandException {
267: FtpRequest request = conn.getRequest();
268:
269: if (request.getCommand().equals("SITE STATS")) {
270: return doSITE_STATS(conn);
271: }
272:
273: Collection users;
274:
275: try {
276: users = conn.getGlobalContext().getUserManager()
277: .getAllUsers();
278: } catch (UserFileException e) {
279: logger.warn("", e);
280:
281: return new Reply(200, "IO error: " + e.getMessage());
282: }
283:
284: int count = 10; // default # of users to list
285: request = conn.getRequest();
286:
287: if (request.hasArgument()) {
288: StringTokenizer st = new StringTokenizer(request
289: .getArgument());
290:
291: try {
292: count = Integer.parseInt(st.nextToken());
293: } catch (NumberFormatException ex) {
294: st = new StringTokenizer(request.getArgument());
295: }
296:
297: if (st.hasMoreTokens()) {
298: Permission perm = new Permission(FtpConfig
299: .makeUsers(st));
300:
301: for (Iterator iter = users.iterator(); iter.hasNext();) {
302: User user = (User) iter.next();
303:
304: if (!perm.check(user)) {
305: iter.remove();
306: }
307: }
308: }
309: }
310:
311: final String command = request.getCommand();
312: Reply response = new Reply(200);
313: String type = command.substring("SITE ".length()).toLowerCase();
314: ArrayList users2 = new ArrayList(users);
315: Collections.sort(users2, new UserComparator(type));
316:
317: try {
318: Textoutput.addTextToResponse(response, type + "_header");
319: } catch (IOException ioe) {
320: logger.warn("Error reading " + type + "_header", ioe);
321: }
322:
323: int i = 0;
324:
325: for (Iterator iter = users2.iterator(); iter.hasNext();) {
326: if (++i > count) {
327: break;
328: }
329:
330: User user = (User) iter.next();
331: ReplacerEnvironment env = new ReplacerEnvironment();
332: env.add("pos", "" + i);
333:
334: env.add("upbytesday", Bytes.formatBytes(user
335: .getUploadedBytesDay()));
336: env.add("upfilesday", "" + user.getUploadedFilesDay());
337: env.add("uprateday", getUpRate(user, Trial.PERIOD_DAILY));
338: env.add("upbytesweek", Bytes.formatBytes(user
339: .getUploadedBytesWeek()));
340: env.add("upfilesweek", "" + user.getUploadedFilesWeek());
341: env.add("uprateweek", getUpRate(user, Trial.PERIOD_WEEKLY));
342: env.add("upbytesmonth", Bytes.formatBytes(user
343: .getUploadedBytesMonth()));
344: env.add("upfilesmonth", "" + user.getUploadedFilesMonth());
345: env.add("upratemonth",
346: getUpRate(user, Trial.PERIOD_MONTHLY));
347: env.add("upbytes", Bytes.formatBytes(user
348: .getUploadedBytes()));
349: env.add("upfiles", "" + user.getUploadedFiles());
350: env.add("uprate", getUpRate(user, Trial.PERIOD_ALL));
351:
352: env.add("dnbytesday", Bytes.formatBytes(user
353: .getDownloadedBytesDay()));
354: env.add("dnfilesday", "" + user.getDownloadedFilesDay());
355: env.add("dnrateday", getDownRate(user, Trial.PERIOD_DAILY));
356: env.add("dnbytesweek", Bytes.formatBytes(user
357: .getDownloadedBytesWeek()));
358: env.add("dnfilesweek", "" + user.getDownloadedFilesWeek());
359: env.add("dnrateweek",
360: getDownRate(user, Trial.PERIOD_WEEKLY));
361: env.add("dnbytesmonth", Bytes.formatBytes(user
362: .getDownloadedBytesMonth()));
363: env
364: .add("dnfilesmonth", ""
365: + user.getDownloadedFilesMonth());
366: env.add("dnratemonth", getDownRate(user,
367: Trial.PERIOD_MONTHLY));
368: env.add("dnbytes", Bytes.formatBytes(user
369: .getDownloadedBytes()));
370: env.add("dnfiles", "" + user.getDownloadedFiles());
371: env.add("dnrate", getDownRate(user, Trial.PERIOD_ALL));
372:
373: response.addComment(BaseFtpConnection.jprintf(
374: TransferStatistics.class, "transferstatistics"
375: + type, env, user));
376:
377: // response.addComment(
378: // user.getUsername()
379: // + " "
380: // + Bytes.formatBytes(
381: // getStats(command.substring("SITE ".length()), user)));
382: }
383:
384: try {
385: Textoutput.addTextToResponse(response, type + "_footer");
386: } catch (IOException ioe) {
387: logger.warn("Error reading " + type + "_footer", ioe);
388: }
389:
390: return response;
391: }
392:
393: public static String getUpRate(User user, int period) {
394: double s = user.getUploadedTimeForTrialPeriod(period)
395: / (double) 1000.0;
396:
397: if (s <= 0) {
398: return "- k/s";
399: }
400:
401: double rate = user.getUploadedBytesForTrialPeriod(period) / s;
402:
403: return Bytes.formatBytes((long) rate) + "/s";
404: }
405:
406: public static String getDownRate(User user, int period) {
407: double s = user.getDownloadedTimeForTrialPeriod(period)
408: / (double) 1000.0;
409:
410: if (s <= 0) {
411: return "- k/s";
412: }
413:
414: double rate = user.getDownloadedBytesForTrialPeriod(period) / s;
415:
416: return Bytes.formatBytes((long) rate) + "/s";
417: }
418:
419: public String[] getFeatReplies() {
420: return null;
421: }
422:
423: public CommandHandler initialize(BaseFtpConnection conn,
424: CommandManager initializer) {
425: return this ;
426: }
427:
428: public void load(CommandManagerFactory initializer) {
429: }
430:
431: public void unload() {
432: }
433: }
|