def getFoldersAndFiles(self, folder=''): """ list: Return a list of all folders. """ storage = FileSystemStorage(os.path.join(settings.MEDIA_ROOT, 'models')) result = list() base_path = "" if folder.startswith("/"): base_path = folder[1:] elif folder: base_path = f"{folder}/" items = storage.listdir(base_path) denied_folders = [] if not self.current_user.has_perm('pyplan.change_group_permissions'): denied_folders = self._getDeniedFolders() # folders for item in sorted(items[0], key=str.lower): full_path = f"{base_path}{item}" if not denied_folders or not item in denied_folders: result.append( FileEntry( show=not item.startswith('.'), text=item, type=eFileTypes.MY_FOLDER, data=FileEntryData( fileSize=None, fullPath=full_path, # specialFolderType=eSpecialFolder.MODELS_PATH lastUpdateTime=storage.get_modified_time( full_path), ))) # files for item in sorted(items[1], key=str.lower): full_path = f"{base_path}{item}" specialFileType = eSpecialFileType.FILE lowerItem = item.lower() if lowerItem.endswith('.ppl') | lowerItem.endswith('.cbpy') | \ lowerItem.endswith('.model') | lowerItem.endswith('.ana'): specialFileType = eSpecialFileType.MODEL elif lowerItem.endswith('.zip'): specialFileType = eSpecialFileType.ZIP result.append( FileEntry( text=item, type=eFileTypes.PUBLIC, data=FileEntryData( fileSize=storage.size(full_path), fullPath=full_path, extension=full_path[full_path.rfind('.') + 1:], specialFileType=specialFileType, lastUpdateTime=storage.get_modified_time(full_path), ))) return result
def getModelInfo(self): """Navigate Diagram""" session = self.client_session if not session is None: modelInfo = session.modelInfo storage = FileSystemStorage() file_path = join(settings.MEDIA_ROOT, "models", modelInfo.uri) file_size = storage.size(file_path) if file_size > 1e+6: file_size = f"{round(file_size / 1024 / 1024, 2)} MB" else: if file_size > 1e+3: file_size = f"{round(file_size / 1024, 2)} kB" else: file_size = f"{file_size} B" created_time = storage.get_created_time(file_path) modified_time = storage.get_modified_time(file_path) modelInfo.uri res = [ { "Key": "modelinfo_model_id", "Value": modelInfo.modelId }, { "Key": "modelinfo_model_name", "Value": modelInfo.name }, { "Key": "modelinfo_model_file", "Value": modelInfo.uri }, { "Key": "modelinfo_file_size", "Value": file_size }, { "Key": "modelinfo_created_date", "Value": f"{created_time.strftime('%Y-%m-%d %H:%M')} hs." }, { "Key": "modelinfo_updated_date", "Value": f"{modified_time.strftime('%Y-%m-%d %H:%M')} hs." }, ] return res else: raise exceptions.NotAcceptable("Can't find session")
def list(request, id): fs = FileSystemStorage() allFiles = [] if fs.exists(id): list = fs.listdir(id)[1] for file in list: entry = { 'dir': '.', 'date': fs.get_modified_time(join( id, file)).strftime("%a, %d %b %Y %H:%M:%S"), 'name': file } allFiles.append(entry) print(allFiles) return JsonResponse(allFiles, safe=False)
def platform(request, platform_name): platform_name = urllib.parse.unquote(platform_name) platform_path = os.path.join(UED_CONTENT_PATH, platform_name) if not os.path.exists(platform_path): raise Http404() version_list = os.listdir(platform_path) version_time_list = [] fs = FileSystemStorage() for version in version_list: change_log_path = os.path.join(UED_CONTENT_RELATIVE_PATH, platform_name, version, 'change_log.html') format_time = '' if fs.exists(change_log_path): format_time = fs.get_modified_time(change_log_path).strftime( '%Y.%m.%d') version_time_list.append([version, format_time]) context = { 'platform_name': platform_name, 'version_time_list': version_time_list } return render(request, 'ued/platform.html', context=context)
def explore(request, f_path=''): ''' View that returns the information of the current directory in the filesystem. :param request: request information. :param f_path: relative filepath from the URL. :return: an array of JSON objects that represent the characteristics of the files/directories in the current path. ''' f_path = f_path.split( '/') # splitting just in case the OS doesn't use unix current_folder_path = path.join(settings.MEDIA_ROOT, *f_path) # open the current folder using Django specific classes. current_folder = FileSystemStorage(location=current_folder_path, file_permissions_mode=0o644, directory_permissions_mode=0o644) # current_folder_info: [[folder1, folder2, ...], [file1, file2, ...]] current_folder_info = [[], []] try: current_folder_info = current_folder.listdir(path='.') except NotADirectoryError: raise Http404('Not a Directory') # store data of present folder folder_data = [] for f_name in current_folder_info[0]: # reading folders folder_data.append({ 'name': f_name, 'is_folder': True, 'created': current_folder.get_created_time(name=f_name), 'modified': current_folder.get_modified_time(name=f_name), 'accessed': current_folder.get_accessed_time(name=f_name), }) # update file's information for f_name in current_folder_info[1]: # reading files file_path = path.join(current_folder_path, f_name) ## Fetch tags try: obj = Dataset.objects.get(path=file_path) obj_tags = DatasetTag.objects.filter(dataset_id=obj.id) tags = [Tag.objects.get(id=el.tag_id).tag_name for el in obj_tags] except ObjectDoesNotExist: tags = [] # get file type using specific library type_file = magic_unix.from_file(filename=file_path) type_file_mime = magic_unix.from_file(filename=file_path, mime=True) folder_data.append({ 'name': f_name, 'is_folder': False, 'created': current_folder.get_created_time(name=f_name), 'modified': current_folder.get_modified_time(name=f_name), 'accessed': current_folder.get_accessed_time(name=f_name), 'size': current_folder.size(name=f_name), 'type': type_file, 'type/mime': type_file_mime, 'tags': tags }) return JsonResponse({'response': folder_data}, safe=True)
class FileManager(object): current_user = None user_directory = None user_trash = None user_storage = None trash_storage = None def __init__(self, user=None): self.current_user = user if self.current_user != None: self.user_directory = settings.MEDIA_ROOT + "/" + self.current_user.user_id self.user_trash = settings.TRASH_ROOT + "/" + self.current_user.user_id # For security, limit access to user directory only self.user_storage = FileSystemStorage(location=self.user_directory) self.trash_storage = FileSystemStorage(location=self.user_trash) else: # Handle none logged in user user_storage = None self.update_path(None) def set_share_path(self, path): self.user_directory = settings.MEDIA_ROOT + "/" + self.current_user.user_id self.user_trash = settings.TRASH_ROOT + "/" + self.current_user.user_id self.user_storage = FileSystemStorage(location=self.user_directory) self.trash_storage = FileSystemStorage(location=self.user_trash) if os.path.isfile(self.user_storage.path(path)): return 1 # File else: self.update_path(path) return 0 # Directory def update_path(self, path): if path is None or len(path) == 0: self.path = '' self.abspath = self.user_storage.path(self.user_directory) else: self.path = self.clean_path(path) self.abspath = os.path.join( self.user_storage.path(self.user_directory), self.path) self.location = self.abspath # self.url = os.path.join(settings.MEDIA_URL, self.path) def clean_path(self, path): # replace backslash with slash path = path.replace('\\', '/') # remove leading and trailing slashes path = '/'.join([i for i in path.split('/') if i]) return path def get_breadcrumbs(self): breadcrumbs = [{ 'label': 'fm-home', 'path': '', }] parts = [e for e in self.path.split('/') if e] path = '' for part in parts: path = os.path.join(path, part) breadcrumbs.append({ 'label': part, 'path': path, }) return breadcrumbs def update_context_data(self, context): context.update({ 'path': self.path, 'breadcrumbs': self.get_breadcrumbs(), }) def file_details(self, file_path): file_path = self.user_storage.path(file_path) filename = smart_str(os.path.split(file_path)[1]) # Extract filemame if os.path.isfile(file_path): return { 'md5checksum': md5_checksum(file_path), 'directory': os.path.dirname(file_path), 'filename': filename, 'filesize': file_size_formatted(self.user_storage.size(file_path)), 'filedate': self.user_storage.get_modified_time(file_path), 'fileurl': file_path, } else: return {} def directory_list(self, include_files=True): listing = [] directories, files = self.user_storage.listdir(self.location) def _helper(name, filetype): return { 'filepath': os.path.join(self.path, name), 'filetype': filetype, 'filename': name, 'filedate': self.user_storage.get_modified_time( os.path.join(self.path, name)), 'filesize': file_size_formatted( self.user_storage.size(os.path.join(self.path, name))), } for directoryname in directories: listing.append(_helper(directoryname, 'directory')) if include_files: mimetypes.init() for filename in files: guessed_mime = mimetypes.guess_type(filename)[0] if (guessed_mime == None): file_mime = "unknown" else: file_mime = str(guessed_mime) listing.append(_helper(filename, file_mime)) return listing def trash_list(self): listing = [] directories, files = self.trash_storage.listdir(self.user_trash) def _helper(name, filetype): return { 'filepath': self.trash_storage.get_valid_name(name), 'filetype': filetype, 'filename': name, 'filedate': self.trash_storage.get_modified_time( os.path.join(self.user_trash, name)), 'filesize': file_size_formatted( self.trash_storage.size(os.path.join( self.user_trash, name))), } for directoryname in directories: listing.append(_helper(directoryname, 'directory')) mimetypes.init() for filename in files: guessed_mime = mimetypes.guess_type(filename)[0] if (guessed_mime == None): file_mime = "unknown" else: file_mime = str(guessed_mime) listing.append(_helper(filename, file_mime)) return listing def delete_item(self, item_path): res_path = item_path i = 0 try: delete_path = os.path.join( self.user_storage.path(self.user_directory), item_path) while os.path.exists( self.trash_storage.path(os.path.basename(res_path))): i = i + 1 res_path = str(i) + "_" + os.path.basename(item_path) new_delete_path = os.path.join( self.user_storage.path(self.user_directory), res_path) os.rename(delete_path, new_delete_path) delete_path = new_delete_path except Exception: return HttpResponseNotFound("File not found") # Move to trash shutil.move(delete_path, self.trash_storage.path(self.user_trash)) # Unshare item if it is shared if ShareUrl.objects.filter(owner=self.current_user, path=item_path).exists(): share_url = get_object_or_404(ShareUrl, owner=self.current_user, path=item_path) share_url.delete() return JsonResponse({'result': 0}) def purge_item(self, item_path): try: delete_path = os.path.join( self.trash_storage.path(self.user_trash), item_path) except Exception: return HttpResponseNotFound("File not found") # Permanantly delete file total_size = 0 if os.path.isdir(delete_path): # Get the size of the file for path, dirs, files in os.walk(delete_path): for f in files: fp = os.path.join(path, f) total_size += os.path.getsize(fp) for fold in dirs: total_size += 4096 shutil.rmtree(delete_path, ignore_errors=True) # Delete selected directory # Update Quota user_db = get_object_or_404(User, pk=self.current_user.user_id) user_db.used_quota = user_db.used_quota - int(total_size) user_db.save() else: total_size = os.path.getsize(delete_path) os.remove(delete_path) # Delete file # Update Quota user_db = get_object_or_404(User, pk=self.current_user.user_id) user_db.used_quota = user_db.used_quota - int(total_size) user_db.save() return JsonResponse({'result': 0}) def upload_file(self, file_data): filename = self.user_storage.get_valid_name(file_data.name) upload_path = os.path.join(self.user_storage.path(self.location), filename) # Check if user has sufficient space if file_data.size > self.current_user.get_remaining_quota(): # Insufficent space return False else: if os.path.exists(self.user_storage.path(upload_path)): # Overwrite existing file and remove from quota user_db = get_object_or_404(User, pk=self.current_user.user_id) user_db.used_quota = user_db.used_quota - int( os.path.getsize(self.user_storage.path(upload_path))) user_db.save() os.remove(self.user_storage.path(upload_path)) try: # Set max_length as a safety precaution to not go over-quota self.user_storage.save( upload_path, file_data, max_length=self.current_user.get_remaining_quota()) user_db = get_object_or_404(User, pk=self.current_user.user_id) # Update Quota user_db.used_quota = user_db.used_quota + int(file_data.size) user_db.save() return True except Exception as ex: # Upload failed. Not enough space return False def empty_trash(self): # Delete trsah folder and recreate it delete_path = self.user_trash # Get the size of the trash total_size = 0 for path, dirs, files in os.walk(delete_path): for f in files: fp = os.path.join(path, f) total_size += os.path.getsize(fp) for fold in dirs: total_size += 4096 shutil.rmtree(delete_path, ignore_errors=True) # Delete selected directory os.mkdir(delete_path) # Update Quota user_db = get_object_or_404(User, pk=self.current_user.user_id) user_db.used_quota = user_db.used_quota - int(total_size) user_db.save() return JsonResponse({'result': 0}) def restore_item(self, item_path): res_path = item_path i = 0 try: restore_path = os.path.join( self.trash_storage.path(self.user_trash), item_path) user_dir_path = os.path.join( self.user_storage.path(self.user_directory)) # Rename if item already exists while os.path.exists(self.user_storage.path(res_path)): i = i + 1 res_path = str(i) + "_" + item_path new_restore_path = os.path.join( self.trash_storage.path(self.user_trash), res_path) os.rename(restore_path, new_restore_path) restore_path = new_restore_path except Exception: return HttpResponseNotFound("File not found") # Move item back to user directory res_location = shutil.move(restore_path, user_dir_path) return JsonResponse({ 'result': 0, 'location': res_location.replace(self.user_storage.path(""), "") }) def download_file(self, filename): download_path = '' try: download_path = os.path.join( self.user_storage.path(self.user_directory), filename) except Exception: return HttpResponseNotFound("File not found") if os.path.isdir(download_path): # Cannot download directory return HttpResponseForbidden("Not allowed") else: file_wrapper = FileWrapper(open(download_path, 'rb')) file_mimetype = mimetypes.guess_type(download_path)[0] response = HttpResponse(file_wrapper, content_type=file_mimetype) response['X-Sendfile'] = download_path response['Content-Length'] = self.user_storage.size(download_path) # Extract filename only response[ 'Content-Disposition'] = 'attachment; filename=%s' % smart_str( os.path.split(filename)[1]) return response def create_directory(self, dir_name): """ Create directory by creating temp file in the directory FileStorageAPI will create the directory while saving the empty temp file then delete the temp file leaving behind the empty new directory """ new_directory = os.path.join(self.location, dir_name) if os.path.exists(self.user_storage.path(new_directory)): # Directory already exists return False else: new_path = self.user_storage.path(new_directory) temp_file = os.path.join(new_path, '.tmp') self.user_storage.save(temp_file, ContentFile('')) self.user_storage.delete(temp_file) user_db = get_object_or_404(User, pk=self.current_user.user_id) # Update Quota - 4KB per directory user_db.used_quota = user_db.used_quota + int(4096) user_db.save() return True def move(self, old_path, new_path): """ Moves a given file to the provided destination """ current_path = os.path.join( self.user_storage.path(self.user_directory), old_path) move_path = os.path.join(self.user_storage.path(self.user_directory), new_path) if current_path == move_path: return JsonResponse({ "result": 1, "message": "Cannot move '" + current_path.replace(self.user_storage.path(""), "") + "' into itself" }) # Error try: shutil.move(current_path, move_path) if ShareUrl.objects.filter(owner=self.current_user, path=old_path).exists(): share_url = get_object_or_404(ShareUrl, owner=self.current_user, path=old_path) # Remove leading slash new_url_path = move_path.replace( self.user_storage.path(""), "") + "/" + os.path.basename( os.path.normpath(old_path)) while new_url_path.startswith("/"): new_url_path = new_url_path[1:] share_url.path = new_url_path share_url.save() except shutil.Error as ex: # Strip user directory location and return error return JsonResponse({ "result": 1, "message": str(ex).replace(self.user_storage.path(""), "") }) # Some sort of error return JsonResponse({"result": 0, "message": "success"}) # Success def rename(self, file_path, new_name): try: rename_path = os.path.join( self.user_storage.path(self.user_directory), file_path) except Exception: # File not found return False new_name_path = os.path.join(self.user_storage.path(rename_path), "../") new_name_path = os.path.join(self.user_storage.path(new_name_path), new_name) if os.path.exists(new_name_path): return False else: os.rename(rename_path, new_name_path) # Update links if necessary if ShareUrl.objects.filter(owner=self.current_user, path=file_path).exists(): share_url = get_object_or_404(ShareUrl, owner=self.current_user, path=file_path) # Remove leading slash new_url_path = new_name_path.replace( self.user_storage.path(""), "") while new_url_path.startswith("/"): new_url_path = new_url_path[1:] share_url.path = new_url_path share_url.save() return True def file_search(self, search_item): file_list = [] # Recursively search through user directory for filename in Path(self.user_storage.path("")).glob('**/' + search_item): file_list.append( str(filename).replace( self.user_storage.path(""), "")) # Remove absolute path to home directory return JsonResponse({ 'result': 0, 'files': file_list, 'search_query': search_item })