├── src
├── CodeOwls.PowerShell.Dropbox
│ ├── DropboxRootFolderNode.cs
│ ├── packages.config
│ ├── DropboxPathResolver.cs
│ ├── DropboxDrive.cs
│ ├── DropboxFolderResultCache.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── codeowls.powershell.dropbox.sln
│ ├── AuthenticationDialog.xaml
│ ├── EngineIdleHandler.cs
│ ├── AuthenticationData.cs
│ ├── DropboxFileNode.cs
│ ├── DropboxFolderNode.cs
│ ├── AuthenticationDialog.xaml.cs
│ ├── DropboxStreamContentReader.cs
│ ├── DropboxProvider.cs
│ └── CodeOwls.PowerShell.Dropbox.csproj
└── Modules
│ └── Dropbox
│ ├── en-US
│ ├── about_Dropbox_Version.help.txt
│ └── about_Dropbox.help.txt
│ ├── Dropbox.psd1
│ ├── Formats
│ └── Dropbox.Formats.ps1xml
│ └── Dropbox-functions.psm1
├── README.md
├── LICENSE
├── .gitignore
└── default.ps1
/src/CodeOwls.PowerShell.Dropbox/DropboxRootFolderNode.cs:
--------------------------------------------------------------------------------
1 | using Dropbox.Api;
2 |
3 | namespace CodeOwls.PowerShell.Dropbox
4 | {
5 | public class DropboxRootFolderNode : DropboxFolderNode
6 | {
7 | public DropboxRootFolderNode( DropboxClient client ) : base( client, null, null, null )
8 | {
9 |
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Dropbox PowerShell Module
3 |
4 | A powershell module used to mount Dropbox accounts through a provider.
5 |
6 | # Example Usage
7 |
8 | ```powershell
9 | import-module dropbox
10 | new-psdrive dbox -psprovider dropbox -root ""
11 | ## at this point powershell will ask you to authenticate with dropbox
12 | cd dbox:\
13 | dir
14 | ```
15 |
16 | # Supported Operations
17 |
18 | Check the about_Dropbox_Version help topic for specific feature availability.
19 |
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/DropboxPathResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Linq;
5 | using System.Management.Automation;
6 | using System.Text.RegularExpressions;
7 | using CodeOwls.PowerShell.Paths.Processors;
8 | using CodeOwls.PowerShell.Provider.PathNodeProcessors;
9 | using CodeOwls.PowerShell.Provider.PathNodes;
10 |
11 | namespace CodeOwls.PowerShell.Dropbox
12 | {
13 | public class DropboxPathResolver : PSProviderPathResolver
14 | {
15 | public DropboxPathResolver(IEnumerable drives) : base(drives)
16 | {
17 | }
18 |
19 | protected override IPathNode Root { get { return new DropboxRootFolderNode( ActiveDrive.Client ); } }
20 | }
21 | }
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/DropboxDrive.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Management.Automation;
3 | using CodeOwls.PowerShell.Provider;
4 | using Dropbox.Api;
5 |
6 | namespace CodeOwls.PowerShell.Dropbox
7 | {
8 | public class DropboxDrive : Drive
9 | {
10 | private readonly AuthenticationData _authenticationData;
11 |
12 | public DropboxClient Client { get; }
13 |
14 | public string UserId { get { return _authenticationData.UserId; } }
15 |
16 | internal DropboxDrive(PSDriveInfo driveInfo, AuthenticationData authenticationData ) : base(driveInfo)
17 | {
18 | _authenticationData = authenticationData;
19 | Client = new DropboxClient( _authenticationData.AccessToken );
20 | }
21 |
22 | public string GetSecuredAccessToken()
23 | {
24 | return _authenticationData.Encrypt();
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/DropboxFolderResultCache.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Dropbox.Api;
3 | using Dropbox.Api.Files;
4 |
5 | namespace CodeOwls.PowerShell.Dropbox
6 | {
7 | static class DropboxFolderResultCache
8 | {
9 | static Dictionary Cache = new Dictionary();
10 |
11 | static DropboxFolderResultCache()
12 | {
13 | EngineIdleManager.OnEngineIdle += (sender, args) => Clear();
14 | }
15 |
16 | public static ListFolderResult GetFolderChildren(DropboxClient client, string path)
17 | {
18 | var lowerPath = path.ToLowerInvariant();
19 | if (Cache.ContainsKey(lowerPath))
20 | {
21 | return Cache[lowerPath];
22 | }
23 |
24 | var result = client.Files.ListFolderAsync(path).Result;
25 | Cache[lowerPath] = result;
26 | return result;
27 | }
28 |
29 | static void Clear()
30 | {
31 | Cache = new Dictionary();
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Jim Christopher
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/Modules/Dropbox/en-US/about_Dropbox_Version.help.txt:
--------------------------------------------------------------------------------
1 | TOPIC
2 | about_Dropbox_Version
3 |
4 | VERSION
5 | You are running version 1.1 of the Dropbox Provider.
6 |
7 | CHANGE LOG
8 | Description
9 | The changelog documents the changes in each release of the
10 | Simplex PowerShell module.
11 |
12 | Coming Features
13 | new-item support
14 | set-item support
15 | remove-item support
16 | sticky access token management
17 |
18 | 1.1
19 | Features Added:
20 | Internal module functions added as file transfer helpers
21 | Added ability to export DPAPI-protected access token and re-use on
22 | subsequent drives. The exported token is encrypted for the
23 | current user only. Specify the protected token in the
24 | -accessToken dynamic parameter of the new-psdrive cmdlet
25 |
26 | Issues Resolved:
27 | Added userid to dropbox path structure to allow full psprovider
28 | path support
29 | Path caching mechanism now resets once the powershell engine
30 | goes idle
31 | Path caching mechanism now properly ignores path casing
32 |
33 | 1.0.0
34 | Initial Release
35 | Support for:
36 | navigating folders
37 | listing contents
38 | get/set-content for files
39 |
40 | SEE ALSO
41 | https://github.com/beefarino/powershell.dropbox
42 | http://www.codeowls.com/
43 | about_dropbox
44 |
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CodeOwls.PowerShell.Dropbox")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("CodeOwls.PowerShell.Dropbox")]
13 | [assembly: AssemblyCopyright("Copyright © 2016 Code Owls LLC, All Rights Reserved.")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // Version information for an assembly consists of the following four values:
23 | //
24 | // Major Version
25 | // Minor Version
26 | // Build Number
27 | // Revision
28 | //
29 | // You can specify all the values or you can default the Build and Revision Numbers
30 | // by using the '*' as shown below:
31 | // [assembly: AssemblyVersion("1.0.*")]
32 | [assembly: AssemblyVersion("1.2.0.0")]
33 | [assembly: AssemblyFileVersion("1.2.0.0")]
34 |
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/codeowls.powershell.dropbox.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25123.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeOwls.PowerShell.Dropbox", "CodeOwls.PowerShell.Dropbox.csproj", "{07F81797-16E5-4818-A9AB-DA344A40356D}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x86 = Debug|x86
12 | Release|Any CPU = Release|Any CPU
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {07F81797-16E5-4818-A9AB-DA344A40356D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {07F81797-16E5-4818-A9AB-DA344A40356D}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {07F81797-16E5-4818-A9AB-DA344A40356D}.Debug|x86.ActiveCfg = Debug|Any CPU
19 | {07F81797-16E5-4818-A9AB-DA344A40356D}.Debug|x86.Build.0 = Debug|Any CPU
20 | {07F81797-16E5-4818-A9AB-DA344A40356D}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {07F81797-16E5-4818-A9AB-DA344A40356D}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {07F81797-16E5-4818-A9AB-DA344A40356D}.Release|x86.ActiveCfg = Release|Any CPU
23 | {07F81797-16E5-4818-A9AB-DA344A40356D}.Release|x86.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/AuthenticationDialog.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
23 |
24 |
25 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/EngineIdleHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Linq;
4 | using System.Management.Automation;
5 | using System.Management.Automation.Runspaces;
6 |
7 | namespace CodeOwls.PowerShell.Dropbox
8 | {
9 | public static class EngineIdleManager
10 | {
11 | public static event EventHandler OnEngineIdle;
12 | public static bool IsRegistered = false;
13 |
14 | public static object CurrentEventJob { get; private set; } = null;
15 |
16 | public static void RegisterForNextEngineIdle(SessionState sessionState )
17 | {
18 | if (IsRegistered)
19 | {
20 | return;
21 | }
22 |
23 | IsRegistered = true;
24 | var results = sessionState.InvokeCommand.InvokeScript(RegistrationScript);
25 | CurrentEventJob = results.FirstOrDefault()?.BaseObject;
26 | }
27 |
28 | const string RegistrationScript =
29 | @"register-engineEvent -sourceIdentifier PowerShell.OnIdle -action {
30 | try {
31 | [CodeOwls.PowerShell.Dropbox.EngineIdleManager]::NotifyEngineIdle( $host.runspace.sessionstateproxy );
32 | }
33 | finally {
34 | unregister-event -sourceIdentifier ([CodeOwls.PowerShell.Dropbox.EngineIdleManager]::CurrentEventJob.Name);
35 | [CodeOwls.PowerShell.Dropbox.EngineIdleManager]::IsRegistered = $false;
36 | }
37 | }";
38 |
39 | public static void NotifyEngineIdle(SessionStateProxy sessionState)
40 | {
41 | OnEngineIdle?.Invoke(null, EventArgs.Empty);
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/AuthenticationData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Management.Automation.Runspaces;
6 | using System.Net;
7 | using System.Runtime.InteropServices;
8 | using System.Security;
9 | using System.Security.Cryptography;
10 | using System.Text;
11 | using System.Threading.Tasks;
12 |
13 | namespace CodeOwls.PowerShell.Dropbox
14 | {
15 | class AuthenticationData
16 | {
17 | static readonly byte[] _entropy = { 115,176,255,214,172,82,90,67,185,113,136,68,211,32,50,14 };
18 |
19 | public string AccessToken { get; }
20 | public string UserId { get; }
21 |
22 | public static string AppKey = "tyye144bh9zf59y";
23 | public static string AppSecret = "3y3amtu2n9v31j4";
24 |
25 | public AuthenticationData( string accessToken, string userId )
26 | {
27 | AccessToken = accessToken;
28 | UserId = userId;
29 | }
30 |
31 | internal string Encrypt()
32 | {
33 | var plainText = Encoding.UTF8.GetBytes( AccessToken + "|" + UserId );
34 |
35 | var cipher = ProtectedData.Protect(plainText, _entropy, DataProtectionScope.CurrentUser);
36 | return Convert.ToBase64String(cipher);
37 | }
38 |
39 | public static AuthenticationData FromSecuredData(string cipher)
40 | {
41 | var plainText = ProtectedData.Unprotect(Convert.FromBase64String(cipher), _entropy, DataProtectionScope.CurrentUser);
42 | var data = Encoding.UTF8.GetString(plainText);
43 | var items = data.Split('|');
44 | return new AuthenticationData( items[0], items[1]);
45 |
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Modules/Dropbox/en-US/about_Dropbox.help.txt:
--------------------------------------------------------------------------------
1 | TOPIC
2 | about_Dropbox
3 |
4 | COPYRIGHT
5 | Copyright (c) 2016 Code Owls LLC, All Rights Reserved.
6 |
7 | LICENSE
8 | The MIT License (MIT)
9 |
10 | Copyright (c) 2016 Code Owls LLC
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining a copy
13 | of this software and associated documentation files (the "Software"), to deal
14 | in the Software without restriction, including without limitation the rights
15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 | copies of the Software, and to permit persons to whom the Software is
17 | furnished to do so, subject to the following conditions:
18 |
19 | The above copyright notice and this permission notice shall be included in all
20 | copies or substantial portions of the Software.
21 |
22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 | SOFTWARE.
29 |
30 | SHORT DESCRIPTION
31 | Provides access to Dropbox services through a PowerShell provider.
32 |
33 | LONG DESCRIPTION
34 | Provides access to Dropbox services through a PowerShell provider.
35 |
36 | QUICK EXAMPLE
37 | import-module dropbox
38 | new-psdrive -name dbox -psprovider dropbox -root ""
39 | ## at this point powershell will ask you to authenticate with
40 | ## dropbox before proceeding
41 | cd dbox:
42 | dir
43 |
44 | SEE ALSO
45 | https://github.com/beefarino/PowerShell.Dropbox
46 | http://www.codeowls.com/
47 | about_Dropbox_Version
48 |
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/DropboxFileNode.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 | using System.Management.Automation.Provider;
4 | using CodeOwls.PowerShell.Paths;
5 | using CodeOwls.PowerShell.Provider.PathNodeProcessors;
6 | using CodeOwls.PowerShell.Provider.PathNodes;
7 | using Dropbox.Api;
8 | using Dropbox.Api.Files;
9 |
10 | namespace CodeOwls.PowerShell.Dropbox
11 | {
12 | public class DropboxFileNode : PathNodeBase, IGetItemContent, ISetItemContent
13 | {
14 | private readonly DropboxClient _client;
15 | private readonly Metadata _metadata;
16 |
17 | public DropboxFileNode(DropboxClient client, Metadata metadata, string name, string path)
18 | {
19 | _client = client;
20 | _metadata = metadata;
21 | Name = name;
22 | Path = path;
23 | }
24 |
25 | public override IPathValue GetNodeValue()
26 | {
27 | return new LeafPathValue( _metadata, Name );
28 | }
29 |
30 | public override string Name { get; }
31 |
32 | string Path { get; }
33 |
34 | public IContentReader GetContentReader(IProviderContext providerContext)
35 | {
36 | var download = _client.Files.DownloadAsync(Path).Result;
37 | var stream = download.GetContentAsStreamAsync().Result;
38 | return new StreamContentReader(stream);
39 | }
40 |
41 | public object GetContentReaderDynamicParameters(IProviderContext providerContext)
42 | {
43 | return null;
44 | }
45 |
46 | public IContentWriter GetContentWriter(IProviderContext providerContext)
47 | {
48 | var writer = new StreamContentWriter( new MemoryStream() );
49 | writer.WriteComplete += (sender, stream) =>
50 | {
51 | stream.Position = 0L;
52 | var result = _client.Files.UploadAsync(Path, WriteMode.Overwrite.Instance, false, null, false, stream).Result;
53 | };
54 | return writer;
55 |
56 | }
57 |
58 | public object GetContentWriterDynamicParameters(IProviderContext providerContext)
59 | {
60 | return null;
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/DropboxFolderNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using CodeOwls.PowerShell.Provider.PathNodeProcessors;
5 | using CodeOwls.PowerShell.Provider.PathNodes;
6 | using Dropbox.Api;
7 | using Dropbox.Api.Files;
8 |
9 | namespace CodeOwls.PowerShell.Dropbox
10 | {
11 | public class DropboxFolderNode : PathNodeBase
12 | {
13 | private readonly DropboxClient _client;
14 | private readonly Metadata _metadata;
15 |
16 | public DropboxFolderNode(DropboxClient client, Metadata metadata, string name, string path )
17 | {
18 | _client = client;
19 | _metadata = metadata;
20 | Name = name ?? String.Empty;
21 | Path = path ?? String.Empty;
22 | }
23 |
24 | public override IEnumerable GetNodeChildren(IProviderContext providerContext)
25 | {
26 | try
27 | {
28 | var children = DropboxFolderResultCache.GetFolderChildren(_client, Path);
29 |
30 | var folders =
31 | children.Entries.Where(m => m.IsFolder)
32 | .ToList()
33 | .ConvertAll(m => new DropboxFolderNode(_client, m, m.Name, Path + "/" + m.Name));
34 |
35 | folders.Sort((a, b) => StringComparer.OrdinalIgnoreCase.Compare(a.Name, b.Name));
36 |
37 | var files =
38 | children.Entries.Where(m => m.IsFile)
39 | .ToList()
40 | .ConvertAll(m => new DropboxFileNode(_client, m, m.Name, Path + "/" + m.Name));
41 |
42 | files.Sort((a, b) => StringComparer.OrdinalIgnoreCase.Compare(a.Name, b.Name));
43 |
44 | var pathNodes = new List();
45 | pathNodes.AddRange(folders);
46 | pathNodes.AddRange(files);
47 | return pathNodes;
48 | }
49 | catch
50 | {
51 | return null;
52 | }
53 | }
54 |
55 | public override IPathValue GetNodeValue()
56 | {
57 | return new ContainerPathValue(_metadata, Name);
58 | }
59 |
60 | public override string Name { get; }
61 |
62 |
63 | string Path { get; }
64 | }
65 | }
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/AuthenticationDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 | using Dropbox.Api;
16 |
17 | namespace CodeOwls.PowerShell.Dropbox
18 | {
19 | ///
20 | /// Interaction logic for AuthenticationDialog.xaml
21 | ///
22 | public partial class AuthenticationDialog
23 | {
24 | const string RedirectUri = "https://localhost/authorize";
25 | private string _state;
26 |
27 | public AuthenticationDialog( string appKey )
28 | {
29 | InitializeComponent();
30 | Dispatcher.BeginInvoke(new Action(this.Start), appKey);
31 | }
32 |
33 | public string AccessToken { get; private set; }
34 | public string UserId { get; private set; }
35 | public bool Result { get; private set; }
36 |
37 | void Start(string appKey)
38 | {
39 | _state = Guid.NewGuid().ToString("N");
40 | var authUrl = DropboxOAuth2Helper.GetAuthorizeUri(
41 | OAuthResponseType.Token,
42 | appKey,
43 | new Uri(RedirectUri),
44 | _state
45 | );
46 |
47 | Browser.Navigate(authUrl);
48 | }
49 |
50 | void BrowserNavigating(object sender, NavigatingCancelEventArgs args)
51 | {
52 | if (!args.Uri.ToString().StartsWith(RedirectUri, StringComparison.OrdinalIgnoreCase))
53 | {
54 | return;
55 | }
56 |
57 | try
58 | {
59 | OAuth2Response response = DropboxOAuth2Helper.ParseTokenFragment(args.Uri);
60 | if (response.State != _state)
61 | {
62 | return;
63 | }
64 |
65 | this.AccessToken = response.AccessToken;
66 | this.UserId = response.Uid;
67 | this.Result = true;
68 | }
69 | catch (ArgumentException)
70 | {
71 | }
72 | finally
73 | {
74 | args.Cancel = true;
75 | this.Close();
76 | }
77 | }
78 |
79 | void CancelClick(object sender, RoutedEventArgs e)
80 | {
81 | this.Close();
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/DropboxStreamContentReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Management.Automation.Provider;
6 |
7 | namespace CodeOwls.PowerShell.Dropbox
8 | {
9 | class StreamContentWriter : IContentWriter
10 | {
11 | private readonly Stream _stream;
12 |
13 | public StreamContentWriter( Stream stream )
14 | {
15 | _stream = stream;
16 | }
17 |
18 | public void Dispose()
19 | {
20 | _stream.Dispose();
21 | }
22 |
23 | public IList Write(IList content)
24 | {
25 | var buffer = new List();
26 | foreach (byte b in content)
27 | {
28 | buffer.Add(b);
29 | }
30 |
31 | _stream.Write(buffer.ToArray(), 0, buffer.Count);
32 | return buffer;
33 | }
34 |
35 | public void Seek(long offset, SeekOrigin origin)
36 | {
37 | _stream.Seek(offset, origin);
38 | }
39 |
40 | public void Close()
41 | {
42 | _stream.Flush();
43 | _stream.Close();
44 | }
45 |
46 | public event EventHandler WriteComplete;
47 |
48 | protected virtual void OnWriteComplete(Stream e)
49 | {
50 | WriteComplete?.Invoke(this, e);
51 | }
52 | }
53 | internal class StreamContentReader : IContentReader
54 | {
55 | private readonly Stream _stream;
56 |
57 | public StreamContentReader(Stream stream)
58 | {
59 | _stream = stream;
60 | }
61 |
62 | public void Dispose()
63 | {
64 | _stream.Dispose();
65 | }
66 |
67 | public IList Read(long readCount)
68 | {
69 | var actualReadCount = readCount > 0 ? readCount : _stream.Length;
70 |
71 | ArrayList list = new ArrayList();
72 |
73 | var buffer = new byte[actualReadCount];
74 | var thisCount = _stream.Read(buffer, 0, (int) actualReadCount);
75 | if (thisCount != actualReadCount)
76 | {
77 | var thisBuffer = new byte[thisCount];
78 | Array.Copy( buffer, thisBuffer, thisCount );
79 | buffer = thisBuffer;
80 | }
81 | list.AddRange( buffer );
82 |
83 | return list;
84 | }
85 |
86 | public void Close()
87 | {
88 | _stream.Close();
89 | }
90 |
91 | public void Seek(long offset, SeekOrigin origin)
92 | {
93 | _stream.Seek(offset, origin);
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | *~
3 | *.bin
4 | *.DotSettings
5 | _local
6 |
7 | ## Ignore Visual Studio temporary files, build results, and
8 | ## files generated by popular Visual Studio add-ons.
9 |
10 | # User-specific files
11 | *.suo
12 | *.user
13 | *.sln.docstates
14 |
15 | # Build results
16 |
17 | [Dd]ebug/
18 | [Rr]elease/
19 | x64/
20 | build/
21 | [Bb]in/
22 | [Oo]bj/
23 |
24 | # MSTest test Results
25 | [Tt]est[Rr]esult*/
26 | [Bb]uild[Ll]og.*
27 |
28 | *_i.c
29 | *_p.c
30 | *.ilk
31 | *.meta
32 | *.obj
33 | *.pch
34 | *.pdb
35 | *.pgc
36 | *.pgd
37 | *.rsp
38 | *.sbr
39 | *.tlb
40 | *.tli
41 | *.tlh
42 | *.tmp
43 | *.tmp_proj
44 | *.log
45 | *.vspscc
46 | *.vssscc
47 | .builds
48 | *.pidb
49 | *.log
50 | *.scc
51 |
52 | # Visual C++ cache files
53 | ipch/
54 | *.aps
55 | *.ncb
56 | *.opensdf
57 | *.sdf
58 | *.cachefile
59 |
60 | # Visual Studio profiler
61 | *.psess
62 | *.vsp
63 | *.vspx
64 |
65 | # Guidance Automation Toolkit
66 | *.gpState
67 |
68 | # ReSharper is a .NET coding add-in
69 | _ReSharper*/
70 | *.[Rr]e[Ss]harper
71 |
72 | # TeamCity is a build add-in
73 | _TeamCity*
74 |
75 | # DotCover is a Code Coverage Tool
76 | *.dotCover
77 |
78 | # NCrunch
79 | *.ncrunch*
80 | .*crunch*.local.xml
81 |
82 | # Installshield output folder
83 | [Ee]xpress/
84 |
85 | # DocProject is a documentation generator add-in
86 | DocProject/buildhelp/
87 | DocProject/Help/*.HxT
88 | DocProject/Help/*.HxC
89 | DocProject/Help/*.hhc
90 | DocProject/Help/*.hhk
91 | DocProject/Help/*.hhp
92 | DocProject/Help/Html2
93 | DocProject/Help/html
94 |
95 | # Click-Once directory
96 | publish/
97 |
98 | # Publish Web Output
99 | *.Publish.xml
100 | *.pubxml
101 |
102 | # NuGet Packages Directory
103 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
104 | packages/
105 |
106 | # Windows Azure Build Output
107 | csx
108 | *.build.csdef
109 |
110 | # Windows Store app package directory
111 | AppPackages/
112 |
113 | # Others
114 | sql/
115 | *.Cache
116 | ClientBin/
117 | [Ss]tyle[Cc]op.*
118 | ~$*
119 | *~
120 | *.dbmdl
121 | *.[Pp]ublish.xml
122 | *.pfx
123 | *.publishsettings
124 |
125 | # RIA/Silverlight projects
126 | Generated_Code/
127 |
128 | # Backup & report files from converting an old project file to a newer
129 | # Visual Studio version. Backup files are not needed, because we have git ;-)
130 | _UpgradeReport_Files/
131 | Backup*/
132 | UpgradeLog*.XML
133 | UpgradeLog*.htm
134 |
135 | # SQL Server files
136 | App_Data/*.mdf
137 | App_Data/*.ldf
138 |
139 | # =========================
140 | # Windows detritus
141 | # =========================
142 |
143 | # Windows image file caches
144 | Thumbs.db
145 | ehthumbs.db
146 |
147 | # Folder config file
148 | Desktop.ini
149 |
150 | # Recycle Bin used on file shares
151 | $RECYCLE.BIN/
152 |
153 | # Mac crap
154 | .DS_Store
155 |
--------------------------------------------------------------------------------
/src/Modules/Dropbox/Dropbox.psd1:
--------------------------------------------------------------------------------
1 | <#
2 | Copyright (c) 2016 Code Owls LLC, All Rights Reserved.
3 | #>
4 |
5 | @{
6 | # Script module or binary module file associated with this manifest
7 | ModuleToProcess = 'bin/codeowls.powershell.dropbox.dll'
8 |
9 | # Version number of this module.
10 | ModuleVersion = '1.0.0.0'
11 |
12 | # ID used to uniquely identify this module
13 | GUID = '30cff6b6c70d4d53a17dc86d1b27201b'
14 |
15 | # Author of this module
16 | Author = 'Jim Christopher'
17 |
18 | # Company or vendor of this module
19 | CompanyName = 'Code Owls LLC'
20 |
21 | # Copyright statement for this module
22 | Copyright = 'Copyright (c) 2016 Code Owls LLC, All Rights Reserved'
23 |
24 | # Description of the functionality provided by this module
25 | Description = 'A powershell provider for dropbox access.'
26 |
27 | # Minimum version of the Windows PowerShell engine required by this module
28 | PowerShellVersion = '4.0'
29 |
30 | # Name of the Windows PowerShell host required by this module
31 | PowerShellHostName = ''
32 |
33 | # Minimum version of the Windows PowerShell host required by this module
34 | PowerShellHostVersion = ''
35 |
36 | # Minimum version of the .NET Framework required by this module
37 | DotNetFrameworkVersion = ''
38 |
39 | # Minimum version of the common language runtime (CLR) required by this module
40 | CLRVersion = '4.0'
41 |
42 | # Processor architecture (None, X86, Amd64, IA64) required by this module
43 | ProcessorArchitecture = ''
44 |
45 | # Modules that must be imported into the global environment prior to importing this module
46 | RequiredModules = @()
47 |
48 | # Assemblies that must be loaded prior to importing this module
49 | RequiredAssemblies = @()
50 |
51 | # Script files (.ps1) that are run in the caller's environment prior to importing this module
52 | ScriptsToProcess = @()
53 |
54 | # Type files (.ps1xml) to be loaded when importing this module
55 | TypesToProcess = @()
56 |
57 | # Format files (.ps1xml) to be loaded when importing this module
58 | FormatsToProcess = @( './formats/dropbox.formats.ps1xml' )
59 |
60 | # Modules to import as nested modules of the module specified in ModuleToProcess
61 | NestedModules = 'Dropbox-functions.psm1'
62 |
63 |
64 | # Functions to export from this module
65 | FunctionsToExport = '*'
66 |
67 | # Cmdlets to export from this module
68 | CmdletsToExport = '*'
69 |
70 | # Variables to export from this module
71 | VariablesToExport = '*'
72 |
73 | # Aliases to export from this module
74 | AliasesToExport = '*'
75 |
76 | # List of all modules packaged with this module
77 | ModuleList = @()
78 |
79 | # List of all files packaged with this module
80 | FileList = @()
81 |
82 | # Private data to pass to the module specified in ModuleToProcess
83 | PrivateData = ''
84 | }
85 |
--------------------------------------------------------------------------------
/src/Modules/Dropbox/Formats/Dropbox.Formats.ps1xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | GenericCollection-GroupingFormat
6 |
7 |
8 |
9 |
10 |
11 | 4
12 |
13 | Container:
14 |
15 | PSParentPath
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | CollectionChildren
30 |
31 | Dropbox.Api.Files.FolderMetadata
32 | Dropbox.Api.Files.FileMetadata
33 |
34 |
35 | PSParentPath
36 | GenericCollection-GroupingFormat
37 |
38 |
39 |
40 |
41 | 10
42 |
43 | Left
44 |
45 |
46 | 24
47 |
48 | Right
49 |
50 |
51 | 14
52 |
53 | Right
54 |
55 |
56 |
57 | Left
58 |
59 |
60 |
61 |
62 |
63 |
64 | SSItemMode
65 |
66 |
67 | ServerModified
68 |
69 |
70 | Size
71 |
72 |
73 | PSChildName
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/DropboxProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Management.Automation;
3 | using System.Management.Automation.Provider;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using CodeOwls.PowerShell.Paths.Processors;
7 | using CodeOwls.PowerShell.Provider;
8 | using CodeOwls.PowerShell.Provider.PathNodeProcessors;
9 | using Dropbox.Api.Sharing;
10 |
11 | namespace CodeOwls.PowerShell.Dropbox
12 | {
13 | [CmdletProvider( "Dropbox", ProviderCapabilities.Filter)]
14 | public class DropboxProvider : Provider.Provider
15 | {
16 | protected override PSDriveInfo NewDrive(PSDriveInfo drive)
17 | {
18 | if (drive is DropboxDrive) return drive;
19 | AuthenticationData data = null;
20 | var param = this.DynamicParameters as NewDriveParameters;
21 | if (!String.IsNullOrWhiteSpace(param?.AccessToken))
22 | {
23 | data = AuthenticationData.FromSecuredData(param.AccessToken);
24 | }
25 | else
26 | {
27 | data = Authenticate();
28 | }
29 |
30 | var root = $"[{data.UserId}]";
31 | if (! String.IsNullOrEmpty(drive.Root))
32 | {
33 | root += $"\\{drive.Root}";
34 | }
35 |
36 | var newInfo = new PSDriveInfo(
37 | drive.Name,
38 | drive.Provider,
39 | root,
40 | drive.Description,
41 | drive.Credential,
42 | drive.DisplayRoot
43 | );
44 |
45 | return new DropboxDrive( newInfo, data );
46 | }
47 |
48 | public class NewDriveParameters
49 | {
50 | [Parameter]
51 | public string AccessToken { get; set; }
52 | }
53 |
54 | protected override object NewDriveDynamicParameters()
55 | {
56 | return new NewDriveParameters();
57 | }
58 |
59 | protected override IPathResolver PathResolver
60 | {
61 | get
62 | {
63 | var drives = this.SessionState.Drive.GetAllForProvider(this.ProviderInfo.Name);
64 | EngineIdleManager.RegisterForNextEngineIdle(this.SessionState);
65 | return new DropboxPathResolver(drives);
66 | }
67 | }
68 |
69 | AuthenticationData Authenticate()
70 | {
71 | var completion = new TaskCompletionSource();
72 |
73 | var thread = new Thread(() =>
74 | {
75 | try
76 | {
77 | var app = System.Windows.Application.Current;
78 | if (null == app)
79 | {
80 | app = new System.Windows.Application();
81 | }
82 | var login = new AuthenticationDialog( AuthenticationData.AppKey);
83 | app.Run(login);
84 | if (login.Result)
85 | {
86 | completion.TrySetResult(new AuthenticationData(login.AccessToken, login.UserId));
87 | }
88 | else
89 | {
90 | completion.TrySetCanceled();
91 | }
92 | }
93 | catch (Exception e)
94 | {
95 | completion.TrySetException(e);
96 | }
97 | });
98 | thread.SetApartmentState(ApartmentState.STA);
99 | thread.Start();
100 |
101 | var result = completion.Task.Result;
102 |
103 | return result;
104 | }
105 | }
106 | }
--------------------------------------------------------------------------------
/src/CodeOwls.PowerShell.Dropbox/CodeOwls.PowerShell.Dropbox.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {07F81797-16E5-4818-A9AB-DA344A40356D}
8 | Library
9 | Properties
10 | CodeOwls.PowerShell.Dropbox
11 | CodeOwls.PowerShell.Dropbox
12 | v4.5.2
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 | packages\P2F.1.6.1\lib\net45\CodeOwls.PowerShell.Paths.dll
36 | True
37 | False
38 |
39 |
40 | packages\P2F.1.6.1\lib\net45\CodeOwls.PowerShell.Provider.dll
41 | True
42 | False
43 |
44 |
45 | packages\Dropbox.Api.3.4.0\lib\net45\Dropbox.Api.dll
46 | True
47 |
48 |
49 | packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
50 | True
51 |
52 |
53 |
54 |
55 |
56 |
57 | packages\System.Management.Automation.dll.10.0.10586.0\lib\net40\System.Management.Automation.dll
58 | False
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | AuthenticationDialog.xaml
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | Designer
89 |
90 |
91 |
92 |
93 | Designer
94 | MSBuild:Compile
95 |
96 |
97 |
98 |
105 |
106 |
--------------------------------------------------------------------------------
/src/Modules/Dropbox/Dropbox-functions.psm1:
--------------------------------------------------------------------------------
1 | <#
2 | Copyright (c) 2016 Code Owls LLC, All Rights Reserved.
3 | #>
4 |
5 | function copy-dropBoxItem {
6 | param(
7 | [parameter(position=0, mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
8 | [alias("path", "dropboxFilePath")]
9 | [string]
10 | # the path to the dropbox item; this must point to a Dropbox provider path
11 | $pspath,
12 |
13 | [parameter(position=1, mandatory=$true, ValueFromPipelineByPropertyName=$true)]
14 | [alias("filepath")]
15 | [string]
16 | # the path to the local file; this must point to a Filesystem provider path
17 | $localFilePath,
18 |
19 | [parameter( mandatory=$false)]
20 | [switch]
21 | # overwrites the local file if it already exists
22 | $force,
23 |
24 | [parameter( mandatory=$false)]
25 | [int]
26 | # the number of bytes to read from the file in a given iteration; set this number higher to speed up reading of larger files
27 | $readCount = 1
28 | )
29 |
30 | process {
31 | $d = '';
32 | [system.management.automation.providerinfo] $providerInfo = $null;
33 | [system.management.automation.psdriveinfo] $driveInfo = $null;
34 |
35 |
36 | $pathInfo = $ExecutionContext.SessionState.Path;
37 | $isAbsFilePath = $pathInfo.IsPSAbsolute($localFilePath, [ref]$d);
38 | if( -not $isAbsFilePath ) {
39 | $d = $pathInfo.CurrentFileSystemLocation.Drive.Name;
40 | $localFilePath = $pathInfo.GetUnresolvedProviderPathFromPSPath(
41 | "${d}:" + $localFilePath
42 | )
43 | }
44 |
45 | $pathInfo.GetUnresolvedProviderPathFromPSPath(
46 | $pspath,
47 | [ref]$providerInfo,
48 | [ref]$driveInfo
49 | ) | out-null;
50 |
51 | if( $providerInfo.Name -notmatch 'dropbox' ) {
52 | write-error -message "the -pspath parameter must point to a dropbox provider location" -targetObject $pspath
53 | return;
54 | }
55 |
56 | $pathInfo.GetUnresolvedProviderPathFromPSPath(
57 | $localFilePath,
58 | [ref]$providerInfo,
59 | [ref]$driveInfo
60 | ) | out-null;
61 |
62 | if( $providerInfo.Name -notmatch 'filesystem' ) {
63 | write-error -message "the -localFilePath parameter must point to a file system location" -targetObject $localFilePath
64 | return;
65 | }
66 |
67 | $bytes = get-content -literalpath $pspath -readcount $readCount | foreach {$_};
68 | if( (Test-Path $localFilePath) -and (-not $force) ) {
69 | write-error -message "local file $localFilePath exists, and -force was not specified" -targetObject $localFilePath
70 | return;
71 | }
72 |
73 | [system.io.file]::writeAllBytes( $localFilePath, $bytes );
74 |
75 | get-item $localFilePath;
76 | }
77 |
78 | <#
79 | .SYNOPSIS
80 | Copies one or more files from the mounted Dropbox account to the local
81 | file system.
82 |
83 | .DESCRIPTION
84 | Copies one or more files from the mounted Dropbox account to the local
85 | file system. The PSPath parameter specifies the path to the Dropbox
86 | item, and the LocalFilePath parameter identifies where to save the file
87 | locally.
88 |
89 | .INPUTS
90 | The Dropbox item to copy, either as a provider object with a PSPath property,
91 | or a String containing the PSPath to the Dropbox object.
92 |
93 | .OUTPUTS
94 | The local file system object copied from Dropbox.
95 |
96 | .EXAMPLE
97 | C:\PS> copy-dropBoxItem dp:/transcripts/audit.txt -localFilePath ./audit.txt
98 |
99 | This example copies the audit.txt file from the transcripts hive on Dropbox
100 | to a file named audit.txt in the current file system provider location.
101 |
102 | .EXAMPLE
103 | DP:\transcripts> dir | copy-dropBoxItem -localFilePath {$_.name} -force
104 |
105 | This example copies all items from the current location in the Dropbox
106 | provider to the local file system. The force parameter is specified, so the
107 | command will overwrite any existing files.
108 |
109 | .LINK
110 | about_Dropbox
111 |
112 | .LINK
113 | about_Dropbox_Version
114 | #>
115 | }
116 |
117 | function get-DropboxProtectedAccessToken
118 | {
119 | param(
120 | [parameter(position=0, mandatory=$false, ValueFromPipelineByPropertyName=$true)]
121 | [alias("path")]
122 | [string]
123 | # the path of a dropbox item; the access token for that hive will be encrypted and returned
124 | $pspath = '.'
125 | )
126 |
127 | process {
128 | [system.management.automation.providerinfo] $providerInfo = $null;
129 | [system.management.automation.psdriveinfo] $driveInfo = $null;
130 |
131 | $pathInfo = $ExecutionContext.SessionState.Path;
132 | $pathInfo.GetUnresolvedProviderPathFromPSPath(
133 | $pspath,
134 | [ref]$providerInfo,
135 | [ref]$driveInfo
136 | ) | out-null;
137 |
138 | if( $providerInfo.Name -notmatch "dropbox" ) {
139 | write-error "the -pspath parameter must point to a dropbox provider location" -targetObject $pspath
140 | }
141 |
142 | $driveInfo.GetSecuredAccessToken();
143 | }
144 |
145 | <#
146 | .SYNOPSIS
147 | Retrieves an protected access token for the specifid mounted Dropbox account.
148 |
149 | .DESCRIPTION
150 | Retrieves an protected access token for the specifid mounted Dropbox account.
151 | The token is encrypted such that only the current user may reuse the token.
152 | The protected access token can be passed to the AccessToken dynamic parameter
153 | of new-psdrive when mounting a Dropbox. See Examples.
154 |
155 | .INPUTS
156 | Any Dropbox provider item; the access token for the account backing the
157 | item will be returned.
158 |
159 | .OUTPUTS
160 | The encrypted access token.
161 |
162 | .EXAMPLE
163 | C:\PS> get-DropboxProtectedAccessToken dp:/
164 |
165 | This example displays the encrypted access token for the dp: Dropbox provider
166 | drive.
167 |
168 | .EXAMPLE
169 | DP:\transcripts> $t = get-DropboxProtectedAccessToken dp:/
170 | DP:\transcripts> new-psdrive -name other -psp Dropbox -accessToken $t -root ''
171 |
172 | In this example, the access token for drive dp:/ is re-used to create another
173 | mounted instance of the Dropbox account.
174 |
175 | .LINK
176 | about_Dropbox
177 |
178 | .LINK
179 | about_Dropbox_Version
180 | #>
181 | }
182 |
--------------------------------------------------------------------------------
/default.ps1:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2016 Code Owls LLC
3 | #
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to
6 | # deal in the Software without restriction, including without limitation the
7 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | # sell copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 | #
11 | # The above copyright notice and this permission notice shall be included in
12 | # all copies or substantial portions of the Software.
13 | #
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | # IN THE SOFTWARE.
21 | #
22 | # psake build script for the Dropbox module
23 | #
24 | # valid configurations:
25 | # Debug
26 | # Release
27 | #
28 | # notes:
29 | #
30 |
31 | properties {
32 | $config = 'Debug';
33 | $slnFile = @(
34 | './src/CodeOwls.PowerShell.Dropbox/CodeOwls.PowerShell.Dropbox.sln'
35 | );
36 | $targetPath = "./src/CodeOwls.PowerShell.Dropbox/bin";
37 |
38 | $moduleName = "Dropbox";
39 | $moduleSource = "./src/Modules";
40 | $metadataAssembly = 'CodeOwls.PowerShell.Dropbox.dll'
41 | $currentReleaseNotesPath = '.\src\Modules\$moduleName\en-US\about_Dropbox_Version.help.txt'
42 | };
43 |
44 | framework '4.5.1'
45 |
46 | $private = "this is a private task not meant for external use";
47 |
48 | task default -depends Install;
49 |
50 | # private tasks
51 |
52 | task __InitializeBuild -description $private {
53 | $error.clear();
54 | }
55 |
56 | task __VerifyConfiguration -depends __InitializeBuild -description $private {
57 | Assert ( @('Debug', 'Release') -contains $config ) "Unknown configuration, $config; expecting 'Debug' or 'Release'";
58 | Assert ( Test-Path $slnFile ) "Cannot find solution, $slnFile";
59 |
60 | Write-Verbose ("packageDirectory: " + ( get-packageDirectory ));
61 | }
62 |
63 | task __CreatePackageDirectory -description $private {
64 | get-packageDirectory | create-packageDirectory;
65 | }
66 |
67 | task __CreateModulePackageDirectory -description $private {
68 | get-modulePackageDirectory | create-packageDirectory;
69 | }
70 |
71 | # primary targets
72 |
73 | task Build -depends __VerifyConfiguration -description "builds any outdated dependencies from source" {
74 | exec {
75 | msbuild $slnFile /p:Configuration=$config /t:Build
76 | }
77 | }
78 |
79 | task Clean -depends __VerifyConfiguration,CleanModule -description "deletes all temporary build artifacts" {
80 | exec {
81 | msbuild $slnFile /p:Configuration=$config /t:Clean
82 | }
83 | }
84 |
85 | task Rebuild -depends Clean,Build -description "runs a clean build";
86 |
87 | task Package -depends PackageModule -description "assembles distributions in the source hive"
88 |
89 | # clean tasks
90 |
91 | task CleanModule -depends __CreateModulePackageDirectory -description "clears the module package staging area" {
92 | get-modulePackageDirectory |
93 | remove-item -recurse -force;
94 | }
95 |
96 | # package tasks
97 |
98 | task PackageModule -depends CleanModule,Build,__CreateModulePackageDirectory -description "assembles module distribution file hive" -action {
99 | $mp = get-modulePackageDirectory;
100 | $psdFile = "$mp/$moduleName/$moduleName.psd1";
101 | $bin = "$mp/$moduleName/bin";
102 | $version = get-packageVersion;
103 |
104 | write-verbose "package module $moduleName in $mp with version $version";
105 |
106 | # copy module src hive to distribution hive
107 | Copy-Item $moduleSource -container -recurse -Destination $mp -Force;
108 |
109 | # copy bins to module bin area
110 | mkdir $bin -force | out-null;
111 | get-targetOutputPath | ls | copy-item -dest $bin -recurse -force;
112 |
113 | $psd = get-content $psdFile;
114 | $psd -replace "ModuleVersion = '[\d\.]+'","ModuleVersion = '$version'" | out-file $psdFile;
115 | }
116 |
117 | # install tasks
118 |
119 | task Uninstall -description "uninstalls the module from the local user module repository" {
120 | $modulePath = $Env:PSModulePath -split ';' | select -First 1 | Join-Path -ChildPath $moduleName;
121 | if( Test-Path $modulePath )
122 | {
123 | Write-Verbose "uninstalling from local module repository at $modulePath";
124 |
125 | $modulePath | ri -Recurse -force;
126 | }
127 | }
128 |
129 | task Install -depends InstallModule -description "installs the module to the local machine";
130 |
131 | task InstallModule -depends PackageModule -description "installs the module to the local user module repository" {
132 | $packagePath = get-modulePackageDirectory;
133 | $modulePath = $Env:PSModulePath -split ';' | select -First 1;
134 | Write-Verbose "installing to local module repository at $modulePath";
135 |
136 | ls $packagePath | Copy-Item -recurse -Destination $modulePath -Force;
137 | }
138 |
139 | function get-packageDirectory
140 | {
141 | return "." | resolve-path | join-path -child "/build/$config";
142 | }
143 |
144 | function get-modulePackageDirectory
145 | {
146 | return "." | resolve-path | join-path -child "/build/$config/Modules";
147 | }
148 |
149 | function create-PackageDirectory( [Parameter(ValueFromPipeline=$true)]$packageDirectory )
150 | {
151 | process
152 | {
153 | write-verbose "checking for package path $packageDirectory ..."
154 | if( !(Test-Path $packageDirectory ) )
155 | {
156 | Write-Verbose "creating package directory at $packageDirectory ...";
157 | mkdir $packageDirectory | Out-Null;
158 | }
159 | }
160 | }
161 |
162 | function get-targetOutputPath
163 | {
164 | $targetPath | join-path -childPath $config
165 | }
166 |
167 | function get-packageVersion
168 | {
169 | $md = $targetPath | join-path -childPath $config | join-path -ChildPath $metadataAssembly;
170 | ( get-item $md | select -exp versioninfo | select -exp productversion )
171 | }
172 |
--------------------------------------------------------------------------------