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.remotefile;
019:
020: import java.io.FileNotFoundException;
021: import java.io.IOException;
022: import java.util.ArrayList;
023: import java.util.Collections;
024: import java.util.Iterator;
025: import java.util.List;
026: import net.sf.drftpd.NoAvailableSlaveException;
027: import net.sf.drftpd.master.BaseFtpConnection;
028:
029: import org.apache.log4j.Logger;
030: import org.drftpd.Bytes;
031: import org.drftpd.SFVFile;
032: import org.drftpd.SFVFile.SFVStatus;
033: import org.drftpd.commands.Reply;
034: import org.drftpd.id3.ID3Tag;
035: import org.drftpd.plugins.DIZFile;
036: import org.drftpd.plugins.DIZPlugin;
037: import org.tanesha.replacer.ReplacerEnvironment;
038:
039: /**
040: * @author mog
041: * @version $Id: ListUtils.java 894 2005-01-13 22:32:32Z zubov $
042: */
043: public class ListUtils {
044: private static final Logger logger = Logger
045: .getLogger(ListUtils.class);
046: public static final String PADDING = " ";
047:
048: private ListUtils() {
049: }
050:
051: public static boolean isLegalFileName(String fileName) {
052: if (fileName == null) {
053: throw new RuntimeException();
054: }
055:
056: return (fileName.indexOf("/") == -1)
057: && (fileName.indexOf('*') == -1)
058: && !fileName.equals(".") && !fileName.equals("..");
059: }
060:
061: public static List list(LinkedRemoteFileInterface directoryFile,
062: BaseFtpConnection conn) {
063: try {
064: return list(directoryFile, conn, null);
065: } catch (IOException e) {
066: logger.info("IOException while listing directory "
067: + directoryFile.getPath(), e);
068: return new ArrayList();
069: }
070: }
071:
072: public static List list(LinkedRemoteFileInterface dir,
073: BaseFtpConnection conn, Reply response) throws IOException {
074: ArrayList tempFileList = new ArrayList<RemoteFileInterface>(dir
075: .getFiles());
076: ArrayList<RemoteFileInterface> listFiles = new ArrayList<RemoteFileInterface>();
077: int numOnline = 0;
078: int numTotal = 0;
079: boolean id3found = false;
080: ID3Tag mp3tag = null;
081:
082: for (Iterator iter = tempFileList.iterator(); iter.hasNext();) {
083: LinkedRemoteFile element = (LinkedRemoteFile) iter.next();
084:
085: if ((conn.getGlobalContext().getConnectionManager()
086: .getGlobalContext().getConfig() != null)
087: && !conn.getGlobalContext().getConnectionManager()
088: .getGlobalContext().getConfig()
089: .checkPathPermission("privpath",
090: conn.getUserNull(), element, true)) {
091: // don't add it
092: continue;
093: }
094:
095: if (element.isFile()
096: && element.getName().toLowerCase().endsWith(".mp3")
097: && (id3found == false)) {
098: try {
099: mp3tag = element.getID3v1Tag();
100: id3found = true;
101: } catch (FileNotFoundException e) {
102: logger.warn("FileNotFoundException: "
103: + element.getPath(), e);
104: } catch (IOException e) {
105: logger.warn("IOException: " + element.getPath(), e);
106: } catch (NoAvailableSlaveException e) {
107: logger.warn("NoAvailableSlaveException: "
108: + element.getPath(), e);
109: }
110: }
111:
112: // if (element.isDirectory()) { // can slow listing
113: // try {
114: // int filesleft =
115: // element.lookupSFVFile().getStatus().getMissing();
116: // if (filesleft != 0)
117: // listFiles.add(
118: // new StaticRemoteFile(
119: // null,
120: // element.getName()
121: // + "-"
122: // + filesleft
123: // + "-FILES-MISSING",
124: // "drftpd",
125: // "drftpd",
126: // 0L,
127: // dir.lastModified()));
128: // } catch (IOException e) {
129: // } // errors getting SFV? FINE! We don't care!
130: // // is a directory
131: // // numOnline++; // do not want to include directories in the file count
132: // // numTotal++;
133: // listFiles.add(element);
134: // continue;
135: // } else if (
136: if (!element.isAvailable()
137: && conn.getGlobalContext().getZsConfig()
138: .offlineFilesEnabled()) { // directories are always available
139: ReplacerEnvironment env = new ReplacerEnvironment();
140: env.add("ofilename", element.getName());
141: String oFileName = conn.jprintf(ListUtils.class,
142: "files.offline.filename", env);
143: listFiles.add(new StaticRemoteFile(
144: Collections.EMPTY_LIST, oFileName, element
145: .getUsername(), element.getGroupname(),
146: element.length(), element.lastModified()));
147: numTotal++;
148:
149: // -OFFLINE and "ONLINE" files will both be present until someoe implements
150: // a way to reupload OFFLINE files.
151: // It could be confusing to the user and/or client if the file doesn't exist, but you can't upload it.
152: }
153:
154: //else element is a file, and is online
155: numOnline++;
156: numTotal++;
157: listFiles.add(element);
158: }
159:
160: String statusDirName = null;
161: try {
162: if (DIZPlugin.zipFilesOnline(dir) > 0) {
163: DIZFile diz = null;
164: diz = new DIZFile(DIZPlugin.getZipFile(dir));
165: if (diz.getDiz() != null && diz.getTotal() > 0) {
166: ReplacerEnvironment env = new ReplacerEnvironment();
167:
168: if ((diz.getTotal() - DIZPlugin
169: .zipFilesPresent(dir)) > 0) {
170: env.add("missing.number", ""
171: + (diz.getTotal() - DIZPlugin
172: .zipFilesPresent(dir)));
173: env
174: .add(
175: "missing.percent",
176: ""
177: + (((diz.getTotal() - DIZPlugin
178: .zipFilesPresent(dir)) * 100) / diz
179: .getTotal()));
180: env.add("missing", conn.jprintf(
181: ListUtils.class, "statusbar.missing",
182: env));
183: } else {
184: env.add("missing", "");
185: }
186:
187: if (DIZPlugin.zipFilesPresent(dir) > 0) {
188: env.add("complete.total", "" + diz.getTotal());
189: env.add("complete.number", ""
190: + DIZPlugin.zipFilesPresent(dir));
191: env
192: .add(
193: "complete.percent",
194: ""
195: + ((DIZPlugin
196: .zipFilesPresent(dir) * 100) / diz
197: .getTotal()));
198: env.add("complete.totalbytes", Bytes
199: .formatBytes(DIZPlugin.zipDirSize(diz
200: .getParent())));
201: } else {
202: env.add("complete.number", "0");
203: env.add("complete.percent", "0");
204: env.add("complete.totalbytes", "0");
205: }
206:
207: env.add("complete", conn.jprintf(ListUtils.class,
208: "statusbar.complete", env));
209:
210: if (DIZPlugin.zipFilesOffline(dir) > 0) {
211: env.add("offline.number", ""
212: + DIZPlugin.zipFilesOffline(dir));
213: env
214: .add(
215: "offline.percent",
216: ""
217: + (DIZPlugin
218: .zipFilesOffline(dir) * 100)
219: / DIZPlugin
220: .zipFilesPresent(dir));
221: env.add("online.number", ""
222: + DIZPlugin.zipFilesOnline(dir));
223: env.add("online.percent", ""
224: + (DIZPlugin.zipFilesOnline(dir) * 100)
225: / DIZPlugin.zipFilesPresent(dir));
226: env.add("offline", conn.jprintf(
227: ListUtils.class, "statusbar.offline",
228: env));
229: } else {
230: env.add("offline", "");
231: }
232:
233: env.add("id3tag", "");
234:
235: statusDirName = conn.jprintf(ListUtils.class,
236: "statusbar.format", env);
237:
238: if (statusDirName == null) {
239: throw new RuntimeException();
240: }
241:
242: if (conn.getGlobalContext().getZsConfig()
243: .statusBarEnabled()) {
244: listFiles.add(new StaticRemoteFile(null,
245: statusDirName, "drftpd", "drftpd", 0L,
246: dir.lastModified()));
247: }
248:
249: return listFiles;
250: }
251: }
252: } catch (FileNotFoundException e) {
253: } catch (NoAvailableSlaveException e) {
254: }
255:
256: try {
257: SFVFile sfvfile = dir.lookupSFVFile();
258: SFVStatus sfvstatus = sfvfile.getStatus();
259: ReplacerEnvironment env = new ReplacerEnvironment();
260:
261: if (sfvfile.size() != 0) {
262:
263: if (sfvstatus.getMissing() != 0) {
264: env.add("missing.number", ""
265: + sfvstatus.getMissing());
266: env.add("missing.percent", ""
267: + (sfvstatus.getMissing() * 100)
268: / sfvfile.size());
269: env.add("missing", conn.jprintf(ListUtils.class,
270: "statusbar.missing", env));
271: } else {
272: env.add("missing", "");
273: }
274:
275: env.add("complete.total", "" + sfvfile.size());
276: env.add("complete.number", "" + sfvstatus.getPresent());
277: env.add("complete.percent", ""
278: + (sfvstatus.getPresent() * 100)
279: / sfvfile.size());
280: env.add("complete.totalbytes", Bytes
281: .formatBytes(sfvfile.getTotalBytes()));
282: env.add("complete", conn.jprintf(ListUtils.class,
283: "statusbar.complete", env));
284:
285: if (sfvstatus.getOffline() != 0) {
286: env.add("offline.number", ""
287: + sfvstatus.getOffline());
288: env.add("offline.percent", ""
289: + (sfvstatus.getOffline() * 100)
290: / sfvstatus.getPresent());
291: env.add("online.number", ""
292: + sfvstatus.getPresent());
293: env.add("online.percent", ""
294: + (sfvstatus.getAvailable() * 100)
295: / sfvstatus.getPresent());
296: env.add("offline", conn.jprintf(ListUtils.class,
297: "statusbar.offline", env));
298: } else {
299: env.add("offline", "");
300: }
301:
302: //mp3tag info added by teflon artist, album, title, genre, year
303: if (id3found) {
304: env.add("artist", mp3tag.getArtist().trim());
305: env.add("album", mp3tag.getAlbum().trim());
306: env.add("title", mp3tag.getTitle().trim());
307: env.add("genre", mp3tag.getGenre().trim());
308: env.add("year", mp3tag.getYear().trim());
309: env.add("id3tag", conn.jprintf(ListUtils.class,
310: "statusbar.id3tag", env));
311: } else {
312: env.add("id3tag", "");
313: }
314:
315: statusDirName = conn.jprintf(ListUtils.class,
316: "statusbar.format", env);
317:
318: if (statusDirName == null) {
319: throw new RuntimeException();
320: }
321:
322: if (conn.getGlobalContext().getZsConfig()
323: .statusBarEnabled()) {
324: listFiles.add(new StaticRemoteFile(null,
325: statusDirName, "drftpd", "drftpd", 0L, dir
326: .lastModified()));
327: }
328:
329: if (conn.getGlobalContext().getZsConfig()
330: .missingFilesEnabled()) {
331: for (Iterator iter = sfvfile.getNames().iterator(); iter
332: .hasNext();) {
333: String filename = (String) iter.next();
334:
335: if (!dir.hasFile(filename)
336: || dir.getXfertime() == -1) {
337: //listFiles.remove()
338: env.add("mfilename", filename);
339: listFiles.add(new StaticRemoteFile(
340: Collections.EMPTY_LIST,
341: conn.jprintf(ListUtils.class,
342: "files.missing.filename",
343: env), "drftpd", "drftpd",
344: 0L, dir.lastModified()));
345: }
346: }
347: }
348: }
349: } catch (NoAvailableSlaveException e) {
350: logger.warn("No available slaves for SFV file", e);
351: } catch (FileNotFoundException e) {
352: // no sfv file in directory - just skip it
353: } catch (IOException e) {
354: logger.warn("IO error loading SFV file", e);
355: } catch (Throwable e) {
356: logger.warn("zipscript error", e);
357: }
358:
359: return listFiles;
360: }
361:
362: public static String padToLength(String value, int length) {
363: if (value.length() >= length) {
364: return value;
365: }
366:
367: if (PADDING.length() < length) {
368: throw new RuntimeException(
369: "padding must be longer than length");
370: }
371:
372: return PADDING.substring(0, length - value.length()) + value;
373: }
374: }
|