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 net.sf.drftpd.SlaveUnavailableException;
021: import net.sf.drftpd.master.BaseFtpConnection;
022: import net.sf.drftpd.master.FtpRequest;
023: import net.sf.drftpd.master.GroupPosition;
024: import net.sf.drftpd.master.command.CommandManager;
025: import net.sf.drftpd.master.command.CommandManagerFactory;
026: import net.sf.drftpd.master.command.plugins.Textoutput;
027: import net.sf.drftpd.util.ReplacerUtils;
028:
029: import org.apache.log4j.Logger;
030:
031: import org.drftpd.Bytes;
032: import org.drftpd.master.RemoteSlave;
033: import org.drftpd.plugins.RaceStatistics;
034:
035: import org.drftpd.slave.SlaveStatus;
036: import org.drftpd.usermanager.User;
037: import org.drftpd.usermanager.UserFileException;
038:
039: import org.tanesha.replacer.ReplacerEnvironment;
040:
041: import java.io.IOException;
042:
043: import java.util.ArrayList;
044: import java.util.Calendar;
045: import java.util.Collection;
046: import java.util.Collections;
047: import java.util.Iterator;
048:
049: /*
050: * @author iamn
051: * @version $Id: MoreStats.java 1246 2005-09-05 07:33:34Z teflon $
052: */
053: public class MoreStats implements CommandHandler, CommandHandlerFactory {
054: public static final int PERIOD_DAILY = Calendar.DAY_OF_MONTH; // = 5
055: public static final short PERIOD_MONTHLY = Calendar.MONTH; // = 2
056: public static final short PERIOD_WEEKLY = Calendar.WEEK_OF_YEAR; // = 3
057: private static final Logger logger = Logger
058: .getLogger(MoreStats.class);
059:
060: public void unload() {
061: }
062:
063: public void load(CommandManagerFactory initializer) {
064: }
065:
066: public CommandHandler initialize(BaseFtpConnection conn,
067: CommandManager initializer) {
068: return this ;
069: }
070:
071: public String[] getFeatReplies() {
072: return null;
073: }
074:
075: public SlaveStatus getStatusAvailable(RemoteSlave rslave)
076: throws SlaveUnavailableException {
077: return rslave.getSlaveStatusAvailable();
078: }
079:
080: public Reply execute(BaseFtpConnection conn)
081: throws UnhandledCommandException {
082: String cmd = conn.getRequest().getCommand();
083:
084: if ("SITE TRAFFIC".equals(cmd)) {
085: return doSITE_TRAFFIC(conn);
086: }
087:
088: return doSITE_GROUPSTATS(conn);
089:
090: /* throw UnhandledCommandException.create(MoreStats.class,
091: conn.getRequest());*/
092: }
093:
094: public static int getPeriod(String strperiod) {
095: int period = 0;
096:
097: if (strperiod.equals("AL")) {
098: period = 0;
099: }
100:
101: if (strperiod.equals("DAY")) {
102: period = PERIOD_DAILY;
103: }
104:
105: if (strperiod.equals("WK")) {
106: period = PERIOD_WEEKLY;
107: }
108:
109: if (strperiod.equals("MONTH")) {
110: period = PERIOD_MONTHLY;
111: }
112:
113: return period;
114: }
115:
116: public static long getStats(String command, User user) {
117: // AL MONTH WK DAY
118: int period = getPeriod(command.substring(0,
119: command.length() - 2));
120:
121: // UP DN
122: String updn = command.substring(command.length() - 2)
123: .toUpperCase();
124:
125: if (updn.equals("UP")) {
126: return user.getUploadedBytesForTrialPeriod(period);
127: } else if (updn.equals("DN")) {
128: return user.getDownloadedBytesForTrialPeriod(period);
129: }
130:
131: throw new RuntimeException(UnhandledCommandException.create(
132: MoreStats.class, command));
133: }
134:
135: public static int getFiles(String command, User user) {
136: // AL MONTH WK DAY
137: int period = getPeriod(command.substring(0,
138: command.length() - 2));
139:
140: // UP DN
141: String updn = command.substring(command.length() - 2);
142:
143: if (updn.equals("UP")) {
144: return user.getUploadedFilesForTrialPeriod(period);
145: } else if (updn.equals("DN")) {
146: return user.getDownloadedFilesForTrialPeriod(period);
147: }
148:
149: throw new RuntimeException(UnhandledCommandException.create(
150: MoreStats.class, command));
151: }
152:
153: public static long getTime(String command, User user) {
154: // AL MONTH WK DAY
155: int period = getPeriod(command.substring(0,
156: command.length() - 2));
157:
158: // UP DN
159: String updn = command.substring(command.length() - 2);
160:
161: if (updn.equals("UP")) {
162: return user.getUploadedTimeForTrialPeriod(period);
163: } else if (updn.equals("DN")) {
164: return user.getDownloadedTimeForTrialPeriod(period);
165: }
166:
167: throw new RuntimeException(UnhandledCommandException.create(
168: MoreStats.class, command));
169: }
170:
171: private Reply doSITE_GROUPSTATS(BaseFtpConnection conn) {
172: //if (!conn.getConfig().checkPermission("groupstats",conn.getUserNull())) {
173: FtpRequest request = conn.getRequest();
174: Reply response = new Reply(200, "OK");
175: String type = request.getCommand().substring("SITE G".length());
176: int count = 10;
177: if (request.hasArgument()) {
178: try {
179: count = Integer.parseInt(request.getArgument());
180: } catch (NumberFormatException e) {
181: //ignore input and use 10 as default
182: }
183: }
184: ArrayList<MyGroupPosition> grpList = new ArrayList<MyGroupPosition>();
185: Collection users;
186:
187: try {
188: users = conn.getGlobalContext().getConnectionManager()
189: .getGlobalContext().getUserManager().getAllUsers();
190: } catch (UserFileException e) {
191: logger.warn("", e);
192:
193: return new Reply(200, "IO error: " + e.getMessage());
194: }
195:
196: MyGroupPosition stat = null;
197: String groupname = "";
198:
199: for (Iterator iter = users.iterator(); iter.hasNext();) {
200: User user = (User) iter.next();
201: groupname = user.getGroup();
202:
203: for (Iterator iter2 = grpList.iterator(); iter2.hasNext();) {
204: MyGroupPosition stat2 = (MyGroupPosition) iter2.next();
205:
206: if (stat2.getGroupname().equals(groupname)) {
207: stat = stat2;
208:
209: break;
210: }
211: }
212:
213: if (stat == null) {
214: stat = new MyGroupPosition(groupname, 0, 0, 0, 0, 0);
215: grpList.add(stat);
216: }
217:
218: stat.updateBytes(getStats(type, user));
219: stat.updateFiles(getFiles(type, user));
220: stat.updateXfertime(getTime(type, user));
221: stat.updateRacesWon(user.getKeyedMap().getObjectInt(
222: RaceStatistics.RACESWON));
223: stat.updateMembers(1);
224: stat = null;
225: }
226:
227: Collections.sort(grpList);
228:
229: ReplacerEnvironment env = new ReplacerEnvironment();
230:
231: //morestats.grpstats=| ${grp,-15} |${grpname,7} |${files,8} | ${megs,9} | ${members,9} |
232: try {
233: Textoutput.addTextToResponse(response, "g"
234: + type.toLowerCase() + "_header");
235: } catch (IOException ioe) {
236: logger.warn("Error reading " + "g" + type.toLowerCase()
237: + "_header");
238: }
239:
240: int i = 0;
241:
242: for (Iterator iter = grpList.iterator(); iter.hasNext();) {
243: if (++i > count) {
244: break;
245: }
246:
247: MyGroupPosition grp = (MyGroupPosition) iter.next();
248: env.add("none", "");
249: env.add("pos", "" + i);
250: env.add("grp", grp.getGroupname());
251: env.add("files", Integer.toString(grp.getFiles()));
252: env.add("megs", Bytes.formatBytes(grp.getBytes()));
253:
254: double avrage = grp.getXfertime();
255: double s = avrage / (double) 1000.0;
256:
257: if (s <= 0) {
258: avrage = 0;
259: } else {
260: avrage = grp.getBytes() / s;
261: }
262:
263: env.add("average", Bytes.formatBytes((long) avrage));
264: env.add("raceswon", Integer.toString(grp.getRacesWon()));
265:
266: env.add("members", Integer.toString(grp.getMembers()));
267: response.addComment(ReplacerUtils.jprintf(
268: "morestats.grpstats", env, MoreStats.class));
269: }
270:
271: try {
272: Textoutput.addTextToResponse(response, "g"
273: + type.toLowerCase() + "_footer");
274: } catch (IOException ioe) {
275: logger.warn("Error reading " + "g" + type.toLowerCase()
276: + "_footer");
277: }
278:
279: return response;
280: }
281:
282: public static String getUpRate(User user, int period) {
283: double s = user.getUploadedTimeForTrialPeriod(period)
284: / (double) 1000.0;
285:
286: if (s <= 0) {
287: return "- k/s";
288: }
289:
290: double rate = user.getUploadedBytesForTrialPeriod(period) / s;
291:
292: return Bytes.formatBytes((long) rate) + "/s";
293: }
294:
295: public static String getDownRate(User user, int period) {
296: double s = user.getDownloadedTimeForTrialPeriod(period)
297: / (double) 1000.0;
298:
299: if (s <= 0) {
300: return "- k/s";
301: }
302:
303: double rate = user.getDownloadedBytesForTrialPeriod(period) / s;
304:
305: return Bytes.formatBytes((long) rate) + "/s";
306: }
307:
308: private void AddTrafficComment(String type, double avrage,
309: long megs, int files, Reply response) {
310: double s = avrage / (double) 1000.0;
311:
312: if (s <= 0) {
313: avrage = 0;
314: } else {
315: avrage = megs / s;
316: }
317:
318: ReplacerEnvironment env = new ReplacerEnvironment();
319: env.add("stat", type);
320: env.add("average", Bytes.formatBytes((long) avrage));
321: env.add("megs", Bytes.formatBytes(megs));
322: env.add("files", Integer.toString(files));
323: response.addComment(ReplacerUtils.jprintf(
324: "morestats.trafficstats", env, MoreStats.class));
325: }
326:
327: private Reply doSITE_TRAFFIC(BaseFtpConnection conn) {
328: Reply response = new Reply(200, "OK");
329:
330: Collection users;
331:
332: try {
333: users = conn.getGlobalContext().getConnectionManager()
334: .getGlobalContext().getUserManager().getAllUsers();
335: } catch (UserFileException e) {
336: logger.warn("", e);
337:
338: return new Reply(200, "IO error: " + e.getMessage());
339: }
340:
341: double MonthUpAvrage = 0;
342: double WeekUpAvrage = 0;
343: double DayUpAvrage = 0;
344: double TotalUpAvrage = 0.0;
345:
346: double MonthDnAvrage = 0;
347: double WeekDnAvrage = 0;
348: double DayDnAvrage = 0;
349: double TotalDnAvrage = 0;
350:
351: int MonthFilesUp = 0;
352: int WeekFilesUp = 0;
353: int DayFilesUp = 0;
354: int TotalFilesUp = 0;
355:
356: int MonthFilesDn = 0;
357: int WeekFilesDn = 0;
358: int DayFilesDn = 0;
359: int TotalFilesDn = 0;
360:
361: long MonthUp = 0;
362: long WeekUp = 0;
363: long DayUp = 0;
364: long TotalUp = 0;
365:
366: long MonthDn = 0;
367: long WeekDn = 0;
368: long DayDn = 0;
369: long TotalDn = 0;
370:
371: for (Iterator iter = users.iterator(); iter.hasNext();) {
372: User user = (User) iter.next();
373:
374: MonthFilesUp += user.getUploadedFilesMonth();
375: WeekFilesUp += user.getUploadedFilesWeek();
376: DayFilesUp += user.getUploadedFilesDay();
377: TotalFilesUp += user.getUploadedFiles();
378:
379: MonthFilesDn += user.getDownloadedFilesMonth();
380: WeekFilesDn += user.getDownloadedFilesWeek();
381: DayFilesDn += user.getDownloadedFilesDay();
382: TotalFilesDn += user.getDownloadedFiles();
383:
384: DayUp += user.getUploadedBytesDay();
385: WeekUp += user.getUploadedBytesWeek();
386: MonthUp += user.getUploadedBytesMonth();
387: TotalUp += user.getUploadedBytes();
388:
389: DayDn += user.getDownloadedBytesDay();
390: WeekDn += user.getDownloadedBytesWeek();
391: MonthDn += user.getDownloadedBytesMonth();
392: TotalDn += user.getDownloadedBytes();
393:
394: MonthUpAvrage += user
395: .getUploadedTimeForTrialPeriod(PERIOD_MONTHLY);
396: WeekUpAvrage += user
397: .getUploadedTimeForTrialPeriod(PERIOD_WEEKLY);
398: DayUpAvrage += user
399: .getUploadedTimeForTrialPeriod(PERIOD_DAILY);
400: TotalUpAvrage += user.getUploadedTime();
401:
402: MonthDnAvrage += user
403: .getDownloadedTimeForTrialPeriod(PERIOD_MONTHLY);
404: WeekDnAvrage += user
405: .getDownloadedTimeForTrialPeriod(PERIOD_WEEKLY);
406: DayDnAvrage += user
407: .getDownloadedTimeForTrialPeriod(PERIOD_DAILY);
408: TotalDnAvrage += user.getDownloadedTime();
409: }
410:
411: try {
412: Textoutput.addTextToResponse(response, "traffic_header");
413: } catch (IOException ioe) {
414: logger.warn("Error reading traffic_header - "
415: + ioe.getMessage());
416: }
417:
418: AddTrafficComment("Total Uploads", TotalUpAvrage, TotalUp,
419: TotalFilesUp, response);
420: AddTrafficComment("Total Downloads", TotalDnAvrage, TotalDn,
421: TotalFilesDn, response);
422: AddTrafficComment("Month Uploads", MonthUpAvrage, MonthUp,
423: MonthFilesUp, response);
424: AddTrafficComment("Month Downloads", MonthDnAvrage, MonthDn,
425: MonthFilesDn, response);
426: AddTrafficComment("Week Uploads", WeekUpAvrage, WeekUp,
427: WeekFilesUp, response);
428: AddTrafficComment("Week Downloads", WeekDnAvrage, WeekDn,
429: WeekFilesDn, response);
430: AddTrafficComment("Day Uploads", DayUpAvrage, DayUp,
431: DayFilesUp, response);
432: AddTrafficComment("Day Downloads", DayDnAvrage, DayDn,
433: DayFilesDn, response);
434:
435: try {
436: Textoutput.addTextToResponse(response, "traffic_footer");
437: } catch (IOException ioe) {
438: logger.warn("Error reading traffic_footer - "
439: + ioe.getMessage());
440: }
441:
442: return response;
443: }
444:
445: public class MyGroupPosition extends GroupPosition {
446: int members;
447: int racesWon;
448:
449: public MyGroupPosition(String groupname, long bytes, int files,
450: long xfertime, int members, int racesWon) {
451: super (groupname, bytes, files, xfertime);
452: this .members = members;
453: this .racesWon = racesWon;
454:
455: //this.groupname = groupname;
456:
457: /*this.bytes = bytes;
458: this.files = files;
459: this.xfertime = xfertime;*/
460: }
461:
462: public int getMembers() {
463: return this .members;
464: }
465:
466: public void updateMembers(int members) {
467: this .members += members;
468: }
469:
470: public int getRacesWon() {
471: return this .racesWon;
472: }
473:
474: public void updateRacesWon(int races) {
475: this.racesWon += races;
476: }
477: }
478: }
|