PSDropNew/CopyDropboxToLocal.cs
using System;
using System.Collections.Generic; using System.IO; using System.Linq; using System.Management.Automation; using DropNet.Exceptions; using DropNet.Models; namespace IntelliTect.PSDropbin { [Cmdlet( VerbsCommon.Copy, Noun, SupportsShouldProcess = true )] public class CopyDropboxToLocal : PSCmdlet { private const string Noun = "DropboxToLocal"; [Parameter( Position = 0, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true ) ] [ValidateNotNullOrEmpty] public string Path { get; set; } [Parameter( Position = 1, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true ) ] [ValidateNotNullOrEmpty] public string[] Destination { get; set; } // TODO: implement support for multiple files protected override void ProcessRecord() { ProviderInfo dropboxProvider; string sourceFile = GetResolvedProviderPathFromPSPath( Path, out dropboxProvider ).First(); string destination = GetUnresolvedProviderPathFromPSPath( Destination[0] ); DropboxDriveInfo primaryDrive = dropboxProvider.Drives.Cast<DropboxDriveInfo>().First(); if ( !ShouldProcess( sourceFile, "Copy-Item" ) ) { return; } try { var dropboxPath = DropboxFileHelper.NormalizePath( sourceFile ); var meta = primaryDrive.Client.GetMetaData( dropboxPath ); if ( meta.Is_Dir ) { // We append slashes so that our call to System.IO.Path.GetDirectoryName later works properly. dropboxPath += "\\"; var directories = new Stack<MetaData>(); directories.Push( meta ); while ( directories.Count > 0 ) { MetaData dir = primaryDrive.Client.GetMetaData( directories.Pop().Path ); if ( dir.Contents == null ) { continue; } foreach ( MetaData item in dir.Contents.Where( item => !item.Is_Deleted ) ) { if ( item.Is_Dir ) { directories.Push( item ); } else { item.Path = DropboxFileHelper.NormalizePath( item.Path ); var finalDest = destination + "\\" + item.Path.Remove( 0, System.IO.Path.GetDirectoryName( dropboxPath ).Length ) .Replace( '/', '\\' ); DownloadFile( item.Path, finalDest, primaryDrive ); } } } } else { DownloadFile( dropboxPath, destination, primaryDrive ); } } catch ( DropboxException e ) { ErrorRecord errorRecord = new ErrorRecord( new ArgumentException( "Unable to read Dropbox file '" + sourceFile + "'", e ), "FileReadError", ErrorCategory.InvalidArgument, null ); ThrowTerminatingError( errorRecord ); } } private void DownloadFile( string source, string destination, DropboxDriveInfo drive ) { var fileData = drive.Client.GetFile( source ); var parentDir = System.IO.Path.GetDirectoryName( destination ); if ( Directory.Exists( destination ) ) { destination += $"\\{System.IO.Path.GetFileName( source )}"; } if ( !Directory.Exists( parentDir ) ) { Directory.CreateDirectory( parentDir ); } using ( FileStream fs = new FileStream( destination, FileMode.Create ) ) { foreach ( byte t in fileData ) { fs.WriteByte( t ); } fs.Seek( 0, SeekOrigin.Begin ); // mismatched values if ( fileData.Any( t => t != fs.ReadByte() ) ) { ErrorRecord errorRecord = new ErrorRecord( new Exception( "Error writing file" ), "Error writing file", ErrorCategory.InvalidOperation, null ); ThrowTerminatingError( errorRecord ); } } } } } |