Merge branch 'master' of https://github.com/owncloud/android into material_fab
[pub/Android/ownCloud.git] / src / com / owncloud / android / utils / FileStorageUtils.java
1 /**
2 * ownCloud Android client application
3 *
4 * @author David A. Velasco
5 * Copyright (C) 2015 ownCloud Inc.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2,
9 * as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 package com.owncloud.android.utils;
22
23 import java.io.File;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.Vector;
27
28 import third_parties.daveKoeller.AlphanumComparator;
29
30 import com.owncloud.android.MainApp;
31 import com.owncloud.android.R;
32 import com.owncloud.android.datamodel.OCFile;
33 import com.owncloud.android.lib.resources.files.RemoteFile;
34
35 import android.annotation.SuppressLint;
36 import android.content.Context;
37 import android.content.SharedPreferences;
38 import android.preference.PreferenceManager;
39 import android.net.Uri;
40 import android.os.Environment;
41 import android.os.StatFs;
42 import android.webkit.MimeTypeMap;
43
44
45 /**
46 * Static methods to help in access to local file system.
47 */
48 public class FileStorageUtils {
49 public static final Integer SORT_NAME = 0;
50 public static final Integer SORT_DATE = 1;
51 public static final Integer SORT_SIZE = 2;
52 public static Integer mSortOrder = SORT_NAME;
53 public static Boolean mSortAscending = true;
54
55
56 //private static final String LOG_TAG = "FileStorageUtils";
57
58 public static final String getSavePath(String accountName) {
59 File sdCard = Environment.getExternalStorageDirectory();
60 return sdCard.getAbsolutePath() + "/" + MainApp.getDataFolder() + "/" + Uri.encode(accountName, "@");
61 // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B
62 }
63
64 public static final String getDefaultSavePathFor(String accountName, OCFile file) {
65 return getSavePath(accountName) + file.getRemotePath();
66 }
67
68 public static final String getTemporalPath(String accountName) {
69 File sdCard = Environment.getExternalStorageDirectory();
70 return sdCard.getAbsolutePath() + "/" + MainApp.getDataFolder() + "/tmp/" + Uri.encode(accountName, "@");
71 // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B
72 }
73
74 @SuppressLint("NewApi")
75 public static final long getUsableSpace(String accountName) {
76 File savePath = Environment.getExternalStorageDirectory();
77 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
78 return savePath.getUsableSpace();
79
80 } else {
81 StatFs stats = new StatFs(savePath.getAbsolutePath());
82 return stats.getAvailableBlocks() * stats.getBlockSize();
83 }
84
85 }
86
87 public static final String getLogPath() {
88 return Environment.getExternalStorageDirectory() + File.separator + MainApp.getDataFolder() + File.separator + "log";
89 }
90
91 public static String getInstantUploadFilePath(Context context, String fileName) {
92 SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
93 String uploadPathdef = context.getString(R.string.instant_upload_path);
94 String uploadPath = pref.getString("instant_upload_path", uploadPathdef);
95 String value = uploadPath + OCFile.PATH_SEPARATOR + (fileName == null ? "" : fileName);
96 return value;
97 }
98
99 /**
100 * Gets the composed path when video is or must be stored
101 * @param context
102 * @param fileName: video file name
103 * @return String: video file path composed
104 */
105 public static String getInstantVideoUploadFilePath(Context context, String fileName) {
106 SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
107 String uploadVideoPathdef = context.getString(R.string.instant_upload_path);
108 String uploadVideoPath = pref.getString("instant_video_upload_path", uploadVideoPathdef);
109 String value = uploadVideoPath + OCFile.PATH_SEPARATOR + (fileName == null ? "" : fileName);
110 return value;
111 }
112
113 public static String getParentPath(String remotePath) {
114 String parentPath = new File(remotePath).getParent();
115 parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
116 return parentPath;
117 }
118
119 /**
120 * Creates and populates a new {@link OCFile} object with the data read from the server.
121 *
122 * @param remote remote file read from the server (remote file or folder).
123 * @return New OCFile instance representing the remote resource described by we.
124 */
125 public static OCFile fillOCFile(RemoteFile remote) {
126 OCFile file = new OCFile(remote.getRemotePath());
127 file.setCreationTimestamp(remote.getCreationTimestamp());
128 file.setFileLength(remote.getLength());
129 file.setMimetype(remote.getMimeType());
130 file.setModificationTimestamp(remote.getModifiedTimestamp());
131 file.setEtag(remote.getEtag());
132 file.setPermissions(remote.getPermissions());
133 file.setRemoteId(remote.getRemoteId());
134 return file;
135 }
136
137 /**
138 * Creates and populates a new {@link RemoteFile} object with the data read from an {@link OCFile}.
139 *
140 * @param ocFile OCFile
141 * @return New RemoteFile instance representing the resource described by ocFile.
142 */
143 public static RemoteFile fillRemoteFile(OCFile ocFile){
144 RemoteFile file = new RemoteFile(ocFile.getRemotePath());
145 file.setCreationTimestamp(ocFile.getCreationTimestamp());
146 file.setLength(ocFile.getFileLength());
147 file.setMimeType(ocFile.getMimetype());
148 file.setModifiedTimestamp(ocFile.getModificationTimestamp());
149 file.setEtag(ocFile.getEtag());
150 file.setPermissions(ocFile.getPermissions());
151 file.setRemoteId(ocFile.getRemoteId());
152 return file;
153 }
154
155 /**
156 * Sorts all filenames, regarding last user decision
157 */
158 public static Vector<OCFile> sortFolder(Vector<OCFile> files){
159 switch (mSortOrder){
160 case 0:
161 files = FileStorageUtils.sortByName(files);
162 break;
163 case 1:
164 files = FileStorageUtils.sortByDate(files);
165 break;
166 case 2:
167 // mFiles = FileStorageUtils.sortBySize(mSortAscending);
168 break;
169 }
170
171 return files;
172 }
173
174 /**
175 * Sorts list by Date
176 * @param files
177 */
178 public static Vector<OCFile> sortByDate(Vector<OCFile> files){
179 final Integer val;
180 if (mSortAscending){
181 val = 1;
182 } else {
183 val = -1;
184 }
185
186 Collections.sort(files, new Comparator<OCFile>() {
187 public int compare(OCFile o1, OCFile o2) {
188 if (o1.isFolder() && o2.isFolder()) {
189 Long obj1 = o1.getModificationTimestamp();
190 return val * obj1.compareTo(o2.getModificationTimestamp());
191 }
192 else if (o1.isFolder()) {
193 return -1;
194 } else if (o2.isFolder()) {
195 return 1;
196 } else if (o1.getModificationTimestamp() == 0 || o2.getModificationTimestamp() == 0){
197 return 0;
198 } else {
199 Long obj1 = o1.getModificationTimestamp();
200 return val * obj1.compareTo(o2.getModificationTimestamp());
201 }
202 }
203 });
204
205 return files;
206 }
207
208 // /**
209 // * Sorts list by Size
210 // * @param sortAscending true: ascending, false: descending
211 // */
212 // public static Vector<OCFile> sortBySize(Vector<OCFile> files){
213 // final Integer val;
214 // if (mSortAscending){
215 // val = 1;
216 // } else {
217 // val = -1;
218 // }
219 //
220 // Collections.sort(files, new Comparator<OCFile>() {
221 // public int compare(OCFile o1, OCFile o2) {
222 // if (o1.isFolder() && o2.isFolder()) {
223 // Long obj1 = getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o1)));
224 // return val * obj1.compareTo(getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o2))));
225 // }
226 // else if (o1.isFolder()) {
227 // return -1;
228 // } else if (o2.isFolder()) {
229 // return 1;
230 // } else if (o1.getFileLength() == 0 || o2.getFileLength() == 0){
231 // return 0;
232 // } else {
233 // Long obj1 = o1.getFileLength();
234 // return val * obj1.compareTo(o2.getFileLength());
235 // }
236 // }
237 // });
238 //
239 // return files;
240 // }
241
242 /**
243 * Sorts list by Name
244 * @param files files to sort
245 */
246 public static Vector<OCFile> sortByName(Vector<OCFile> files){
247 final Integer val;
248 if (mSortAscending){
249 val = 1;
250 } else {
251 val = -1;
252 }
253
254 Collections.sort(files, new Comparator<OCFile>() {
255 public int compare(OCFile o1, OCFile o2) {
256 if (o1.isFolder() && o2.isFolder()) {
257 return val * new AlphanumComparator().compare(o1, o2);
258 } else if (o1.isFolder()) {
259 return -1;
260 } else if (o2.isFolder()) {
261 return 1;
262 }
263 return val * new AlphanumComparator().compare(o1, o2);
264 }
265 });
266
267 return files;
268 }
269
270 /**
271 * Local Folder size
272 * @param dir File
273 * @return Size in bytes
274 */
275 public static long getFolderSize(File dir) {
276 if (dir.exists()) {
277 long result = 0;
278 File[] fileList = dir.listFiles();
279 for(int i = 0; i < fileList.length; i++) {
280 if(fileList[i].isDirectory()) {
281 result += getFolderSize(fileList[i]);
282 } else {
283 result += fileList[i].length();
284 }
285 }
286 return result;
287 }
288 return 0;
289 }
290
291 /**
292 * Mimetype String of a file
293 * @param path
294 * @return
295 */
296 public static String getMimeTypeFromName(String path) {
297 String extension = "";
298 int pos = path.lastIndexOf('.');
299 if (pos >= 0) {
300 extension = path.substring(pos + 1);
301 }
302 String result = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
303 return (result != null) ? result : "";
304 }
305
306 }