1 /* 2 * Hunt - A high-level D Programming Language Web framework that encourages rapid development and clean, pragmatic design. 3 * 4 * Copyright (C) 2015-2019, HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.framework.file.File; 13 14 import hunt.framework.file.Exceptions; 15 import hunt.framework.Simplify; 16 import hunt.framework.util.String; 17 18 import std.path : dirName, buildPath; 19 import std.file : getSize, rename, isFile, isDir, exists; 20 import std.format; 21 22 class File 23 { 24 private string _path; 25 26 /** 27 * Constructs a new file from the given path. 28 * 29 * @param string $path The path to the file 30 * @param bool $checkPath Whether to check the path or not 31 * 32 * @throws FileNotFoundException If the given path is not a file 33 */ 34 public this(string path, bool checkPath = true) 35 { 36 if (checkPath && isFile(path)) { 37 throw new FileNotFoundException(path); 38 } 39 40 this._path = buildPath(APP_PATH, path); 41 } 42 43 public string path() 44 { 45 return this._path; 46 } 47 48 public long size() 49 { 50 return getSize(this._path); 51 } 52 53 /** 54 * Returns the extension based on the mime type. 55 * 56 * If the mime type is unknown, returns null. 57 * 58 * This method uses the mime type as guessed by getMimeType() 59 * to guess the file extension. 60 * 61 * @return string|null The guessed extension or null if it cannot be guessed 62 * 63 * @see MimeTypes 64 * @see getMimeType() 65 */ 66 public string extension() 67 { 68 // return MimeTypes::getDefault().getExtensions(this.getMimeType())[0] ?? null; 69 return null; 70 } 71 72 /** 73 * Returns the mime type of the file. 74 * 75 * The mime type is guessed using a MimeTypeGuesserInterface instance, 76 * which uses finfo_file() then the "file" system binary, 77 * depending on which of those are available. 78 * 79 * @return string|null The guessed mime type (e.g. "application/pdf") 80 * 81 * @see MimeTypes 82 */ 83 public string mimeType() 84 { 85 return getMimeTypeByFilename(this.path()); 86 } 87 88 /** 89 * Moves the file to a new location. 90 * 91 * @param string $path The file realpath 92 * 93 * @return self A File object representing the new file 94 * 95 * @throws FileException if the target file could not be created 96 */ 97 public bool move(string path) 98 { 99 string target = this.getTargetFile(path); 100 101 // error to throw FileException 102 rename(this.path(), target); 103 104 version (Posix) 105 { 106 import std.exception : assertNotThrown; 107 import std.conv : octal; 108 import std.file : setAttributes; 109 110 assertNotThrown!FileException(target.setAttributes(octal!644)); 111 } 112 113 return true; 114 } 115 116 protected string getTargetFile(string path) 117 { 118 string target = buildPath(APP_PATH, path); 119 // if (isDir(target)) { 120 // throw new FileException(format("Unable to create the \"%s\" directory.", target)); 121 // } 122 123 if (exists(target)) 124 { 125 throw new FileException(format("The file or directory \"%s\" exists.", target)); 126 } 127 128 return target; 129 } 130 131 /** 132 * Returns locale independent base name of the given path. 133 * 134 * @param string $name The new file name 135 * 136 * @return string containing 137 */ 138 protected string getName(string name = null) 139 { 140 import std.string : lastIndexOf, replace; 141 142 string originalName; 143 144 if (name.length == 0) 145 { 146 originalName = this._path; 147 } 148 else 149 { 150 originalName = name; 151 } 152 153 originalName = originalName.replace("\\", "/"); 154 ptrdiff_t index = lastIndexOf(originalName, '/'); 155 if(index>=0) { 156 originalName = originalName[index..$]; 157 } 158 159 return originalName; 160 } 161 }