├── PSReddit.format.ps1xml
├── PSReddit.ps1xml
├── PSReddit.psd1
├── PSReddit.psm1
├── PowerReddit_old
├── PowerReddit.format.ps1xml
├── PowerReddit.ps1xml
├── PowerReddit.psd1
└── PowerReddit.psm1
├── Private
├── Get-DecryptedValue.ps1
└── Show-oAuthWindow.ps1
├── Public
├── Connect-RedditAccount.ps1
├── Get-RedditAccount.ps1
├── Get-RedditComment.ps1
├── Get-RedditPost.ps1
├── New-RedditPost.ps1
├── Refresh-RedditToken.ps1
└── Send-RedditMessage.ps1
├── README.md
├── img
├── API.png
└── Approve.png
└── license
/PSReddit.format.ps1xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PowerReddit.Link
6 |
7 | PSReddit.Link
8 |
9 |
10 |
11 |
12 | 5
13 |
14 |
15 | 14
16 |
17 |
18 | 18
19 |
20 |
21 | 5
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | id
30 |
31 |
32 | subreddit
33 |
34 |
35 | author
36 |
37 |
38 | score
39 |
40 |
41 | title
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | PSReddit.Comment
51 |
52 | PSReddit.Comment
53 |
54 |
55 |
56 |
57 | 7
58 |
59 |
60 | 18
61 |
62 |
63 | 5
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | id
72 |
73 |
74 | author
75 |
76 |
77 | Score
78 |
79 |
80 | body
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | PSReddit.User
89 |
90 | PSReddit.User
91 |
92 |
93 |
94 |
95 | 7
96 |
97 |
98 | 18
99 |
100 |
101 | 5
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | name
110 |
111 |
112 | created
113 |
114 |
115 | comment_karma
116 |
117 |
118 | link_karma
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/PSReddit.ps1xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PowerReddit.Link
5 |
6 |
7 | GetComments
8 |
9 |
10 |
11 | OpenUrl
12 |
13 |
14 |
15 |
16 |
17 | PowerReddit.Comment
18 |
19 |
20 | score
21 |
22 | $this.ups - $this.downs
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/PSReddit.psd1:
--------------------------------------------------------------------------------
1 | #
2 | # Module manifest for module 'PowerReddit'
3 | #
4 |
5 | @{
6 |
7 | # Script module or binary module file associated with this manifest
8 | RootModule = 'PSReddit.psm1'
9 |
10 | # Version number of this module.
11 | ModuleVersion = '1.0'
12 |
13 | # ID used to uniquely identify this module
14 | GUID = '3dede632-fde4-4cc6-85df-9f5cfd6cd124'
15 |
16 | # Author of this module
17 | Author = 'Tobin Jones', 'Stephen Owen'
18 |
19 | # Copyright statement for this module
20 | Copyright = 'Licensed under the MIT license'
21 |
22 | # Description of the functionality provided by this module
23 | Description = 'Browsing and interacting with the Reddit API'
24 |
25 | # Minimum version of the Windows PowerShell engine required by this module
26 | PowerShellVersion = '3.0'
27 |
28 | # Name of the Windows PowerShell host required by this module
29 | # PowerShellHostName = ''
30 |
31 | # Minimum version of the Windows PowerShell host required by this module
32 | # PowerShellHostVersion = ''
33 |
34 | # Minimum version of the .NET Framework required by this module
35 | # DotNetFrameworkVersion = ''
36 |
37 | # Minimum version of the common language runtime (CLR) required by this module
38 | # CLRVersion = ''
39 |
40 | # Processor architecture (None, X86, Amd64) required by this module
41 | # ProcessorArchitecture = ''
42 |
43 | # Modules that must be imported into the global environment prior to importing this module
44 | # RequiredModules = @()
45 |
46 | # Assemblies that must be loaded prior to importing this module
47 | # RequiredAssemblies = @()
48 |
49 | # Script files (.ps1) that are run in the caller's environment prior to importing this module
50 | # ScriptsToProcess = @()
51 |
52 | # Type files (.ps1xml) to be loaded when importing this module
53 | TypesToProcess = @('PSReddit.ps1xml')
54 |
55 | # Format files (.ps1xml) to be loaded when importing this module
56 | FormatsToProcess = @('PSReddit.format.ps1xml')
57 |
58 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
59 | # NestedModules = @()
60 |
61 | # Functions to export from this module
62 | FunctionsToExport = '*'
63 |
64 | # Cmdlets to export from this module
65 | CmdletsToExport = '*'
66 |
67 | # Variables to export from this module
68 | VariablesToExport = '*'
69 |
70 | # Aliases to export from this module
71 | AliasesToExport = '*'
72 |
73 | # Commands to export from this module as Workflows
74 | # ExportAsWorkflow = @()
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 RootModule/ModuleToProcess
83 | # PrivateData = ''
84 |
85 | # HelpInfo URI of this module
86 | # HelpInfoURI = ''
87 |
88 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
89 | # DefaultCommandPrefix = ''
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/PSReddit.psm1:
--------------------------------------------------------------------------------
1 | [CmdletBinding()]
2 | #Get public and private function definition files.
3 | $PublicFunction = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -Exclude *tests* -ErrorAction SilentlyContinue )
4 | $PrivateFunction = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -Exclude *tests* -ErrorAction SilentlyContinue )
5 |
6 | #Dot source the files
7 | Foreach($import in @($PublicFunction + $PrivateFunction))
8 | {
9 | write-verbose "importing $import"
10 | Try
11 | {
12 | . $import.fullname
13 | }
14 | Catch
15 | {
16 | Write-Error -Message "Failed to import function $($import.fullname): $_"
17 | }
18 | }
19 |
20 | #Initialize our variables. I know, I know...
21 |
22 | $configDir = "$Env:AppData\WindowsPowerShell\Modules\PSReddit\0.1\Config.ps1xml"
23 | $refreshToken = "$Env:AppData\WindowsPowerShell\Modules\PSReddit\0.1\Config.Refresh.ps1xml"
24 |
25 |
26 | Try
27 | {
28 | #Import the config
29 | $password = Import-Clixml -Path $configDir -ErrorAction STOP | ConvertTo-SecureString
30 |
31 | }
32 | catch {
33 | Write-Warning "Corrupt Password file found, rerun with -Force to fix this"
34 | }
35 |
36 | Try
37 | {
38 | #Import the config
39 |
40 | $refreshToken = Import-Clixml -Path $refreshToken -ErrorAction STOP | ConvertTo-SecureString
41 | }
42 | catch {
43 | Write-Warning "Corrupt refresh token file found, rerun with -Force to fix this"
44 | }
45 |
46 | if ($password){Get-DecryptedValue -inputObj $password -name PSReddit_accessToken}
47 | if($refreshToken){Get-DecryptedValue -inputObj $refreshToken -name PSReddit_refreshToken}
48 |
49 |
50 |
51 | # Here I might...
52 | # Read in or create an initial config file and variable
53 | # Export Public functions ($Public.BaseName) for WIP modules
54 | # Set variables visible to the module and its functions only
55 |
56 | Export-ModuleMember -Function $PublicFunction.Basename
--------------------------------------------------------------------------------
/PowerReddit_old/PowerReddit.format.ps1xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PowerReddit.Link
6 |
7 | PowerReddit.Link
8 |
9 |
10 |
11 |
12 | 5
13 |
14 |
15 | 14
16 |
17 |
18 | 18
19 |
20 |
21 | 5
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | id
30 |
31 |
32 | subreddit
33 |
34 |
35 | author
36 |
37 |
38 | score
39 |
40 |
41 | title
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | PowerReddit.Comment
51 |
52 | PowerReddit.Comment
53 |
54 |
55 |
56 |
57 | 7
58 |
59 |
60 | 18
61 |
62 |
63 | 5
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | id
72 |
73 |
74 | author
75 |
76 |
77 | Score
78 |
79 |
80 | body
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/PowerReddit_old/PowerReddit.ps1xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PowerReddit.Link
5 |
6 |
7 | GetComments
8 |
9 |
10 |
11 | OpenUrl
12 |
13 |
14 |
15 |
16 |
17 | PowerReddit.Comment
18 |
19 |
20 | score
21 |
22 | $this.ups - $this.downs
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/PowerReddit_old/PowerReddit.psd1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1RedOne/PSReddit/5d887c04525409d3ff069ca66e29dea39cba9a55/PowerReddit_old/PowerReddit.psd1
--------------------------------------------------------------------------------
/PowerReddit_old/PowerReddit.psm1:
--------------------------------------------------------------------------------
1 | <#
2 | Script Variables
3 | #>
4 | [Microsoft.PowerShell.Commands.WebRequestSession] $script:currentRedditSession;
5 | [Uri] $script:loginUri = [uri] "http://www.reddit.com/api/login"
6 |
7 |
8 | <#
9 | .SYNOPSIS
10 | Authenticates to the Reddit API with provided credentials
11 |
12 | .DESCRIPTION
13 | After running this, all cmdlets will run in the scope of the logged in user
14 |
15 | .PARAMETER Credential
16 | Provide a PSCredential
17 |
18 | #>
19 | function Connect-RedditSession
20 | {
21 | [CmdletBinding()]
22 | Param (
23 | [Parameter(Position=1, Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
24 | [System.Management.Automation.PSCredential]
25 | $credential
26 | )
27 |
28 | if( $credential -eq $null )
29 | {
30 | $credential = Get-Credential -Message "Enter your Reddit login details:"
31 | }
32 |
33 | $userName = $credential.GetNetworkCredential().UserName
34 | $password = $credential.GetNetworkCredential().Password
35 |
36 | $parameters = "user={0}&passwd={1}" -f $userName, $password
37 | $buffer = [System.Text.Encoding]::UTF8.GetBytes($parameters);
38 |
39 | $request = [System.Net.HTTPWebRequest]::Create($script:loginUri)
40 | $request.CookieContainer = New-Object System.Net.CookieContainer
41 | $request.ContentType = "application/x-www-form-urlencoded"
42 | $request.Method = "POST"
43 | $request.ContentLength = $buffer.Length;
44 |
45 | $stream = $request.GetRequestStream()
46 | Try { $stream.Write($buffer, 0, $buffer.Length) }
47 | Finally{ $stream.Dispose() }
48 |
49 | $response = $request.GetResponse()
50 |
51 | $successCookie = $response.Cookies | Where Name -eq 'reddit_session'
52 |
53 | if( $successCookie -eq $null )
54 | {
55 | Write-Error -Message "Authentication Failed" `
56 | -Category PermissionDenied `
57 | -RecommendedAction "Check username and password"
58 | }
59 | else
60 | {
61 | Write-Host "Successfully Authenticated user ""$userName"""
62 | $script:currentRedditSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
63 | $script:currentRedditSession.Cookies.Add($successCookie)
64 | }
65 |
66 | return $script:currentRedditSession
67 | }
68 |
69 |
70 | <#
71 | .SYNOPSIS
72 | Logs out Reddit session
73 |
74 | .DESCRIPTION
75 | Logs out reddit session by forgetting cookie
76 |
77 | #>
78 | function Disconnect-RedditSession
79 | {
80 | [CmdletBinding()]
81 | Param ()
82 |
83 | $script:currentRedditSession = $null
84 |
85 | }
86 |
87 |
88 | <#
89 | .SYNOPSIS
90 | Gets a list of Reddit links
91 |
92 | .DESCRIPTION
93 | Uses the Reddit API to get Reddit links from given subreddit(s)
94 |
95 | .PARAMETER Name
96 | Name of the Subreddit to fetch from. Can be an array.
97 |
98 | #>
99 | function Get-RedditLink
100 | {
101 | [CmdletBinding()]
102 | Param (
103 | [Parameter(Position=1, Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
104 | [Alias("r","Subreddit")]
105 | [string[]]
106 | $Name = 'frontpage'
107 | )
108 |
109 | # Construct the Uri. Multiple subreddits can be joined with plusses
110 | $uri = 'http://www.reddit.com/r/{0}.json' -f [string]::Join('+', $Name)
111 |
112 | # Run the RestMethod in the current user context
113 | $response = (Invoke-RestMethod $uri -WebSession $script:currentRedditSession)
114 |
115 | # This is the listing. Contains before/after for pagination, and links
116 | $listing = $response | Where kind -eq 'Listing' | Select -Expand data
117 |
118 | # Links have type "t3" in Reddit API
119 | $links = $listing.children | Where kind -eq 't3' | select -expand data
120 |
121 | # Return the links with a custom type of [PowerReddit.Link]. We do this so
122 | # that they can be extended by psxml files, etc.
123 | $links | %{ $_.PSObject.TypeNames.Insert(0,'PowerReddit.Link'); $_ }
124 |
125 | }
126 |
127 |
128 | <#
129 | .SYNOPSIS
130 | Gets comments of a Reddit link
131 |
132 | .DESCRIPTION
133 | Uses the Reddit API to get comments made on a given link
134 |
135 | .PARAMETER id
136 | Internal id of the Reddit link
137 |
138 | #>
139 | function Get-RedditComment
140 | {
141 | [CmdletBinding()]
142 | Param (
143 | [Parameter(
144 | Position = 1,
145 | Mandatory = $true,
146 | ValueFromPipelineByPropertyName = $true
147 | )]
148 | [Alias("Link")]
149 | [string]
150 | $id
151 | )
152 |
153 | Process
154 | {
155 | $uri = 'http://www.reddit.com/comments/{0}.json' -f $id
156 |
157 | $listings = (Invoke-RestMethod $uri) | Where kind -eq 'Listing'
158 |
159 | # Comments have a type 't1' in Reddit API
160 | $comments = $listings | %{ $_.data.children } | Where kind -eq 't1' | Select -Expand data
161 |
162 | $comments | %{ $_.PSObject.TypeNames.Insert(0,'PowerReddit.Comment'); $_ }
163 | }
164 | }
165 |
166 |
167 | <#
168 | .SYNOPSIS
169 | Gets information about the currently logged in user
170 |
171 | .PARAMETER redditSession
172 | An optional session to use (like that returned from Connect-RedditSession)
173 |
174 | #>
175 | function Get-RedditUserInfo
176 | {
177 | [CmdletBinding()]
178 | Param (
179 | [Parameter(
180 | Position = 1,
181 | Mandatory = $false,
182 | ValueFromPipelineByPropertyName = $true
183 | )]
184 | [Alias("Link")]
185 | [Microsoft.PowerShell.Commands.WebRequestSession]
186 | $redditSession
187 | )
188 |
189 | if ($redditSession -ne $null)
190 | {
191 | $thisSession = $redditSession
192 | }
193 | elseif ($script:currentRedditSession -ne $null)
194 | {
195 | $thisSession = $script:currentRedditSession
196 | }
197 | else
198 | {
199 | Write-Error -Message "No active session" `
200 | -Category PermissionDenied `
201 | -RecommendedAction "Log in or provide a session object"
202 | return
203 | }
204 |
205 | $uri = 'http://www.reddit.com/api/me.json'
206 | $response = (Invoke-RestMethod $uri -WebSession $thisSession)
207 |
208 | $user = $response | Select -Expand data
209 | $user | %{ $_.PSObject.TypeNames.Insert(0,'PowerReddit.User'); $_ }
210 | }
211 |
212 |
213 | <#
214 | Export public functions
215 | #>
216 | Export-ModuleMember -function `
217 | Get-RedditLink,
218 | Get-RedditComment,
219 | Connect-RedditSession,
220 | Disconnect-RedditSession,
221 | Get-RedditUserInfo
222 |
--------------------------------------------------------------------------------
/Private/Get-DecryptedValue.ps1:
--------------------------------------------------------------------------------
1 | Function Get-DecryptedValue{
2 | param($inputObj,$name)
3 |
4 | $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($inputObj)
5 | $result = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr)
6 | [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr)
7 | New-Variable -Scope Global -Name $name -Value $result -PassThru -Force
8 |
9 | }
--------------------------------------------------------------------------------
/Private/Show-oAuthWindow.ps1:
--------------------------------------------------------------------------------
1 | #region mini window, made by (Insert credits here)
2 | Function Show-OAuthWindow {
3 | param($url)
4 | Add-Type -AssemblyName System.Windows.Forms
5 |
6 | $form = New-Object -TypeName System.Windows.Forms.Form -Property @{Width=820;Height=920}
7 | $web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{Width=800;Height=900;Url=($url -f ($Scope -join "%20")) }
8 | $DocComp = {
9 | $Global:uri = $web.Url.AbsoluteUri
10 | if ($Global:Uri -match "error=[^&]*|code=[^&]*") {$form.Close() }
11 | }
12 |
13 | $web.ScrollBarsEnabled = $false
14 | $web.ScriptErrorsSuppressed = $true
15 | $web.Add_DocumentCompleted($DocComp)
16 | $form.Controls.Add($web)
17 | $form.Add_Shown({$form.Activate()})
18 | $form.ShowDialog() | Out-Null
19 | }
20 | #endregion
21 |
22 | #login to get an access code
--------------------------------------------------------------------------------
/Public/Connect-RedditAccount.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .Synopsis
3 | Use this cmdlet to connect to your Reddit account from PowerShell
4 | .DESCRIPTION
5 | Use this cmdlet to connect to your Reddit account from PowerShell.You'll first need to register for an Register for a Reddit API account here, https://www.reddit.com/prefs/apps, and choose a Script based Application.
6 |
7 | Make note of your ClientSecret, ClientID and RedirectURI (which can be anything). This cmdlet displays a login window to allow a user to provision access to their account by means of oAuth.
8 |
9 | The permissions requested are: identity, history, mysubreddits, read, report, save, submit
10 | .EXAMPLE
11 | Connect-RedditAccount -ClientID $ClientID -ClientSecret $ClientSecret -RedirectURI $RedirectURI
12 | .EXAMPLE
13 | Another example of how to use this cmdlet
14 | .INPUTS
15 | Inputs to this cmdlet (if any)
16 | .OUTPUTS
17 | Output from this cmdlet (if any)
18 | .NOTES
19 | You'll first need to register for an Register for a Reddit API account here, https://www.reddit.com/prefs/apps, and choose a Script based Application. Make note of your ClientSecret, ClientID and RedirectURI (which can be anything).
20 | .COMPONENT
21 | The component this cmdlet belongs to
22 | .ROLE
23 | The role this cmdlet belongs to
24 | .FUNCTIONALITY
25 | The functionality that best describes this cmdlet
26 | .LINK
27 | https://www.reddit.com/dev/api
28 | For Reference for the API
29 | https://github.com/1RedOne/PSReddit/
30 | The project homepage on GitHub
31 |
32 | #>
33 | Function Connect-RedditAccount {
34 | [CmdletBinding()]
35 | param(
36 | $ClientSecret,
37 | $ClientID,
38 | $redirectURI,
39 | [Switch]$force)
40 |
41 | $configDir = "$Env:AppData\WindowsPowerShell\Modules\PSReddit\0.1\Config.ps1xml"
42 | $refreshTokenPath = "$Env:AppData\WindowsPowerShell\Modules\PSReddit\0.1\Config.Refresh.ps1xml"
43 | #look for a stored password
44 |
45 |
46 | if (-not (Test-Path $configDir) -or $force){
47 | if ($force){Write-verbose "`$force detected"}
48 | #create the file to store our Access Token
49 | Write-Verbose "cached Access Code not found, or the user instructed us to refresh"
50 |
51 | if (-not (Test-Path $refreshTokenPath)){New-item -Force -Path $refreshTokenPath -ItemType file }
52 | New-item -Force -Path "$configDir" -ItemType File
53 |
54 | $guid = [guid]::NewGuid()
55 | $URL = "https://www.reddit.com/api/v1/authorize?client_id=$clientID&response_type=code&state=$GUID&redirect_uri=$redirectURI&duration=permanent&scope=identity,history,mysubreddits,read,report,privatemessages,save,submit"
56 |
57 | #Display an oAuth login prompt for the user to user authorize our application, returns uri
58 | Show-OAuthWindow -url $URL
59 |
60 | #attempt to parse $uri to retrieve our AuthCode
61 | $regex = '(?<=code=)(.*)'
62 |
63 | try {$Reddit_authCode = ($uri | Select-string -pattern $regex).Matches[0].Value}
64 | catch {Write-Warning "did not receive an authCode, check ClientID and RedirectURi"
65 | return}
66 |
67 | $global:Reddit_authCode = $Reddit_authCode
68 | Write-Verbose "Received an authCode, $Reddit_authCode"
69 |
70 | write-debug "Pause here to test value of `$uri"
71 | Write-Verbose "Exchanging authCode for Access Token"
72 |
73 | try {
74 | #reddit uses basic auth, which means in PowerShell that we can provide our creds using a credential object
75 | $secpasswd = ConvertTo-SecureString $ClientSecret -AsPlainText -Force
76 | $credential = New-Object System.Management.Automation.PSCredential ($ClientID, $secpasswd)
77 |
78 | #retrieve Access Token
79 | $result = Invoke-RestMethod https://ssl.reddit.com/api/v1/access_token -Method Post -Body @{client_id=$clientId; state=$guid ; redirect_uri=$redirectURI; grant_type="authorization_code"; code=$Reddit_authCode} -ContentType "application/x-www-form-urlencoded" -ErrorAction STOP -Credential $credential
80 | }
81 | catch {
82 | Write-Warning "Something didn't work, this is normally caused by an internet flub, try again in a few minutes"
83 | Write-debug "Test the -body params for the Rest command"
84 | }
85 |
86 | Write-Debug 'go through the results of $result, looking for our token'
87 | if ($result.access_token){
88 | Write-Output "Updated Authorization Token"
89 | $global:PSReddit_accessToken = $result.access_token}
90 |
91 | Write-Verbose "Storing token in $configDir"
92 | #store the token
93 | $password = ConvertTo-SecureString $result.access_token -AsPlainText -Force
94 | $password | ConvertFrom-SecureString | Export-Clixml $configDir -Force
95 |
96 | Write-verbose "Storing refresh token in $refreshTokenPath"
97 | $refresh = ConvertTo-SecureString $result.refresh_token -AsPlainText -Force
98 | $refresh | ConvertFrom-SecureString | Export-Clixml $refreshTokenPath -Force
99 |
100 | }
101 | else{
102 | #if the user did not specify -Force, or if the file path for a stored token already exists
103 | Write-Verbose "We're looking for a stored token in $configDir"
104 | try {
105 | $password = Import-Clixml -Path $configDir -ErrorAction STOP | ConvertTo-SecureString
106 | $refreshToken = Import-Clixml -Path $refreshTokenPath -ErrorAction STOP | ConvertTo-SecureString
107 | }
108 | catch {
109 | Write-Warning "Corrupt Password file found, rerun with -Force to fix this"
110 | BREAK
111 | }
112 |
113 | Get-DecryptedValue -inputObj $password -name PSReddit_accessToken
114 | Get-DecryptedValue -inputObj $refreshToken -name PSReddit_refreshToken
115 |
116 | 'Found cached Cred'
117 | continue
118 | }
119 |
120 | }
--------------------------------------------------------------------------------
/Public/Get-RedditAccount.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Gets information about the currently logged in user
4 | .Description
5 | After you've connected using Connect-RedditAccount, you can use this cmdlet to get information about the currently logged in user
6 | .PARAMETER redditSession
7 | An optional session to use (like that returned from Connect-RedditSession)
8 | .Example
9 | Get-RedditAccount
10 |
11 | name : 1RedOne
12 | hide_from_robots : False
13 | gold_creddits : 0
14 | link_karma : 2674
15 | comment_karma : 19080
16 | over_18 : True
17 | is_gold : False
18 | is_mod : False
19 | gold_expiration :
20 | has_verified_email : True
21 | inbox_count : 2
22 | Created Date : 1/20/2010 6:44:21 PM
23 | .LINK
24 | https://github.com/1RedOne/PSReddit
25 | #>
26 | function Get-RedditAccount
27 | {
28 | [CmdletBinding()]
29 | Param (
30 | [Parameter(
31 | Position = 1,
32 | Mandatory = $false,
33 | ValueFromPipelineByPropertyName = $true
34 | )]
35 | [Alias("Link")]
36 | $accessToken=$Global:PSReddit_accessToken
37 | )
38 |
39 |
40 | $defaultDisplaySet = 'ID','name','Created Date','comment_karma','link_karma','gold_credits'
41 |
42 | #Create the default property display set
43 | $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet(‘DefaultDisplayPropertySet’,[string[]]$defaultDisplaySet)
44 | $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)
45 |
46 | $uri = 'https://oAuth.reddit.com/api/v1/me'
47 | try {$response = (Invoke-RestMethod $uri -Headers @{"Authorization" = "bearer $accessToken"}) }
48 | catch{write-warning "Authentication failed, we should do something here"}
49 |
50 | $origin = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0
51 | $created = $origin.AddSeconds($response.created)
52 |
53 | $response | select -ExcludeProperty created* -Property *,@{Name="Created Date";exp={$created}}
54 |
55 | $response.PSObject.TypeNames.Insert(0,'PSReddit.User')
56 | $response | Add-Member MemberSet PSStandardMembers $PSStandardMembers
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/Public/Get-RedditComment.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .Synopsis
3 | Gets the comments of a Reddit link, or several.
4 | .DESCRIPTION
5 | Uses the Reddit API to get comments made on a given link, collection of posts or the id.
6 | .EXAMPLE
7 | Get-RedditComment -id "3i9psm"
8 | .EXAMPLE
9 | "https://www.reddit.com/r/redditdev/comments/3i9psm/how_can_i_find_the_id_of_the_original_post_in_a/" | Get-RedditComment
10 | .EXAMPLE
11 | Get-RedditPost -Name PowerShell | Select-Object -First 1 | Get-RedditComment
12 | #>
13 | function Get-RedditComment
14 | {
15 | [CmdletBinding()]
16 | Param (
17 | [Parameter(
18 | Position = 1,
19 | Mandatory = $true,
20 | ValueFromPipeline = $true,
21 | ValueFromPipelineByPropertyName = $true
22 | )]
23 | [Alias("Link", "Name")]
24 | [string]
25 | $id
26 | )
27 |
28 | Process
29 | {
30 | ## Depending on how we passed the id to the function, we need to
31 | ## strip some characters.
32 | switch ($id)
33 | {
34 | {($id -like "t3_*")}
35 | {
36 | $id = $id -replace "t3_", ""
37 | break
38 | }
39 | {($id -like "http*")}
40 | {
41 | $id = $id.Split("/")[6]
42 | break
43 | }
44 | }
45 |
46 | $uri = 'http://www.reddit.com/comments/{0}.json' -f $id
47 |
48 | Write-Verbose "Sending request to $uri"
49 | $listings = (Invoke-RestMethod $uri) | Where kind -eq 'Listing'
50 |
51 | # Comments have a type 't1' in Reddit API
52 | $comments = $listings | ForEach-Object { $_.data.children } | Where-Object kind -eq 't1' | Select-Object -Expand data
53 | $comments | ForEach-Object { $_.PSObject.TypeNames.Insert(0,'PowerReddit.Comment'); $_ }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Public/Get-RedditPost.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .Synopsis
3 | Retrieve a listing of the top 50 posts by popularity in a given subreddit. Supports -Subreddit to specify a particular subreddit
4 | .DESCRIPTION
5 | Currently the objects are a bit boned, and you can't get into too much detail, so that's no good. Trust me when I say it will get better.
6 | .EXAMPLE
7 | Get-RedditPost
8 | ups : 4819
9 | title : You know what.. Fuck you!
10 | url : http://i.imgur.com/ln1PIuI.gifv
11 | name : t3_3lfds5
12 | permalink : /r/Unexpected/comments/3lfds5/you_know_what_fuck_you/
13 | Created Date : 3 hours ago
14 |
15 | ups : 5215
16 | title : It must have been a rough divorce
17 | url : http://imgur.com/fXdbGtd.jpeg
18 | name : t3_3lfbd9
19 | permalink : /r/funny/comments/3lfbd9/it_must_have_been_a_rough_divorce/
20 | Created Date : 2 hours ago
21 | .EXAMPLE
22 | Get-RedditPost -Name PowerShell | select -First 5
23 |
24 |
25 | ups : 4
26 | title : List All printers that were /ga from PrintUI
27 | url : http://www.reddit.com/r/PowerShell/comments/3lgj6a/list_all_printers_that_were_ga_from_printui/
28 | name : t3_3lgj6a
29 | created : 1442627254.0
30 | permalink : /r/PowerShell/comments/3lgj6a/list_all_printers_that_were_ga_from_printui/
31 |
32 | ups : 10
33 | title : Combine directories.
34 | url : http://www.reddit.com/r/PowerShell/comments/3lf9ny/combine_directories/
35 | name : t3_3lf9ny
36 | created : 1442607409.0
37 | permalink : /r/PowerShell/comments/3lf9ny/combine_directories/
38 | .EXAMPLE
39 | Get-RedditPost -Name PowerShell | select -First 1 | Get-RedditPostComments
40 |
41 | This will eventually work
42 | #>
43 | Function Get-RedditPost {
44 | [CmdletBinding()]
45 | Param (
46 | [Parameter(Position=1, Mandatory=$false, ValueFromPipelineByPropertyName=$true)]
47 | [Alias("r","Subreddit")]
48 | [string[]]
49 | $Name = 'all',
50 | [Parameter(
51 | Position = 0,
52 | Mandatory = $false,
53 | ValueFromPipelineByPropertyName = $true
54 | )]
55 | [Alias("Link")]
56 | $accessToken=$Global:PSReddit_accessToken
57 | )
58 | #needs to be updated to reflect properties on line 36, also need to add new type to .ps1xml file for this
59 | $defaultDisplaySet = 'ID','name','Created Date','comment_karma','link_karma','gold_credits'
60 | # Construct the Uri. Multiple subreddits can be joined with plusses
61 | #$uri = 'http://www.reddit.com/r/{0}.json' -f [string]::Join('+', $Name)
62 |
63 | $uri = "https://oAuth.reddit.com/r/$Name/hot" ;
64 | try {$response = (Invoke-RestMethod $uri -Headers @{"Authorization" = "bearer $accessToken"} -ErrorAction STOP) }
65 | catch{write-warning "Authentication failed, we should do something here"}
66 |
67 | $response.data.children.data | Select ups,Title,URL,name,created,permalink
68 |
69 | #Figure out the age of a post
70 | write-debug "figure out select logic for age of post"
71 |
72 | $origin = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0
73 | $now = get-date
74 | $created = $origin.AddSeconds($response.created)
75 |
76 | $response.data.children.data | select -ExcludeProperty created* -Property ups,Title,URL,name,created,permalink,@{Name="Created Date";exp={
77 | "$($origin.AddSeconds($_.created) - $now | select -expandProperty Hours) hours ago"
78 | }
79 | }
80 |
81 |
82 | <#
83 | Write-debug "test out response"
84 | # This is the listing. Contains before/after for pagination, and links
85 | $listing = $response | Where kind -eq 'Listing' | Select -Expand data
86 |
87 | # Links have type "t3" in Reddit API
88 | $links = $listing.children | Where kind -eq 't3' | select -expand data
89 |
90 | # Return the links with a custom type of [PowerReddit.Link]. We do this so
91 | # that they can be extended by psxml files, etc.
92 | $links | %{ $_.PSObject.TypeNames.Insert(0,'PowerReddit.Link'); $_ }
93 |
94 | #>
95 | }
--------------------------------------------------------------------------------
/Public/New-RedditPost.ps1:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <#
6 | POST /api/submitsubmit
7 |
8 |
9 |
10 | Submit a link to a subreddit.
11 |
12 | Submit will create a link or self-post in the subreddit sr with the title title. If kind is "link", then url is expected to be a valid URL to link to. Otherwise, text, if present, will be the body of the self-post.
13 |
14 | If a link with the same URL has already been submitted to the specified subreddit an error will be returned unless resubmit is true. extension is used for determining which view-type (e.g. json, compact etc.) to use for the redirect that is generated if the resubmit error occurs.
15 |
16 |
17 | api_type
18 |
19 | the string json
20 |
21 |
22 | captcha
23 |
24 | the user's response to the CAPTCHA challenge
25 |
26 |
27 | extension
28 |
29 | extension used for redirects
30 |
31 |
32 | iden
33 |
34 | the identifier of the CAPTCHA challenge
35 |
36 |
37 | kind
38 |
39 | one of (link, self)
40 |
41 |
42 | resubmit
43 |
44 | boolean value
45 |
46 |
47 | sendreplies
48 |
49 | boolean value
50 |
51 |
52 | sr
53 |
54 | name of a subreddit
55 |
56 |
57 | text
58 |
59 | raw markdown text
60 |
61 |
62 | title
63 |
64 | title of the submission. up to 300 characters long
65 |
66 |
67 | uh / X-Modhash header
68 |
69 | a modhash
70 |
71 |
72 | url
73 |
74 | a valid URL
75 |
76 |
77 | #>
--------------------------------------------------------------------------------
/Public/Refresh-RedditToken.ps1:
--------------------------------------------------------------------------------
1 | Function Refresh-RedditToken{param($settings)
2 |
3 |
4 | $body = @{
5 | client_id = $settings.client_id
6 | grant_type = 'refresh_token'
7 | refresh_token = $settings.refresh_token
8 | redirect_uri = $settings.redirect_uri
9 | duration= $settings.duration
10 | scope= $settings.scope # 'identity','history','mysubreddits','read','report','privatemessages','save','submit'
11 |
12 | }
13 | $tempPW = ConvertTo-SecureString $settings.secret -AsPlainText -Force
14 | $credential = New-Object System.Management.Automation.PSCredential ($settings.client_id, $tempPW)
15 |
16 | Invoke-RestMethod https://www.reddit.com/api/v1/access_token -Body $body -Method Post -Credential $credential #-ContentType "application/x-www-form-urlencoded"
17 |
18 |
19 | }
--------------------------------------------------------------------------------
/Public/Send-RedditMessage.ps1:
--------------------------------------------------------------------------------
1 | Function Send-RedditMessage {param(
2 | $AccessToken,
3 | $Recipient,
4 | $subject,
5 | $post,
6 | $userAgent = 'AzureFunction-SubredditBot:0.0.2 (by /u/1RedOne)'
7 | )
8 |
9 | $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
10 | $headers.Add("User-Agent", 'AzureFunction-SubredditBot:0.0.2 (by /u/1RedOne)')
11 | $headers.Add("Authorization", "bearer $AccessToken")
12 |
13 | $bodyMarkdown = "
14 | Hi Stephen,
15 |
16 | A new post was submitted on [/r/FoxDeploy](http://www.reddit.com/r/FoxDeploy), you should check it out.
17 |
18 |
19 | Post Title: $($post.data.title)
20 |
21 | Post link here: [Click here for the link]($($post.data.url))
22 |
23 | ----------
24 |
25 |
26 | This alert was generated at $time."
27 |
28 | $body = @{
29 | api_type = 'json'
30 | to = $Recipient #@'1RedOne'
31 | subject = $subject
32 | text=$bodyMarkdown
33 | }
34 |
35 |
36 | $Request = Invoke-RestMethod -Headers $headers -Uri https://oauth.reddit.com/api/compose -Method Post -Body $body -ContentType 'application/x-www-form-urlencoded'
37 |
38 | If ($Request.json.errors.Count -eq 0){
39 | Write-Host -ForegroundColor Green 'Message sent'
40 | }
41 | else{
42 | Write-Warning 'Error'
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | PSReddit
2 | ===========
3 | This is a set of tools for browsing Reddit using the Powershell command line.
4 |
5 | Installation
6 | ------------
7 | * Copy the "PSReddit" folder into your module path. Note: You can find an
8 | appropriate directory by running `$ENV:PSModulePath.Split(';')`.
9 | * Run `Import-Module PSReddit` from your PowerShell command prompt.
10 |
11 | Usage
12 | -----
13 |
14 | Register for a Reddit API account here, [Reddit Application Preferences](https://www.reddit.com/prefs/apps), and choose a Script based Application. Make note of your ClientSecret, ClientID and RedirectURI (which can be anything).
15 | 
16 |
17 | ###Connecting your Account###
18 | Connect-RedditAccount -ClientID $clientID -redirectURI $redirectURI -force -ClientSecret $ClientSecret
19 | #oAuth Window will be displayed
20 |
21 | 
22 |
23 | Credentials persist in secure storage and are automatically imported when you use a cmdlet in this module.
24 |
25 | Once connected, you can connect to any of the endpoints [listed in the Reddit API Documentation here.](https://www.reddit.com/dev/api)
26 |
27 | Get-RedditAccount
28 |
29 | name : 1RedOne
30 | hide_from_robots : False
31 | gold_creddits : 0
32 | link_karma : 2674
33 | comment_karma : 19080
34 | over_18 : True
35 | is_gold : False
36 | is_mod : False
37 | gold_expiration :
38 | has_verified_email : True
39 | inbox_count : 2
40 | Created Date : 1/20/2010 6:44:21 PM
41 |
42 | ... gets you information about your account including karma and account creation date
43 |
44 | ####Links####
45 |
46 | **Most of these are out of date with the new Rest method, and will be revamped**
47 |
48 | Get-RedditPost
49 |
50 | ... gets you a nicely formatted table of the current front page links.
51 |
52 | Get-RedditLink -r Powershell
53 |
54 | ... does the same but for the subreddits listed.
55 |
56 | Get-RedditLink -r Powershell | Where is_self | Format-List title, selftext | Out-Host -Paging
57 |
58 | ... will let you read the front-page self posts from the Powershell subreddit,
59 | in a nicely paginated format.
60 |
61 | $top = Get-RedditLink | Sort -Descending score
62 | $top[0].OpenUrl()
63 |
64 | ... will open the link with the top score on the front page in your default
65 | browser
66 |
67 | ###Comments - coming soon!###
68 |
69 | Get-RedditLink | Get-RedditComment
70 |
71 | ... gets you all the top-level comments of all the posts on the front page
72 |
73 | $top[0] | Get-RedditComment
74 |
75 | ... gets you the comments on just that top post
76 |
77 | ##Authentication##
78 |
79 | <<<<<<< HEAD
80 | Connect-RedditAccount
81 | Get-RedditAccount
82 | Disconnect-RedditAccount - coming soon
83 |
84 | =======
85 | Authentication is handled using oAuth via two private function cmdlets, Show-oAuthWindow being the most important of the two. If you've got another project and you're here because you need some reference for handling oAuth using PowerShell, this will be the cmdlet you want. It's found in the Module\Private folder.
86 | Connect-RedditAccount
87 |
88 | >>>>>>> origin/master
89 | ... logs you in, gets information about the logged in user, then logs out.
90 |
91 | ###To come###
92 |
93 | * Making Posts
94 | * imgur uploads
95 | * Your suggestions?
96 | * Multiple Account Support
97 |
--------------------------------------------------------------------------------
/img/API.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1RedOne/PSReddit/5d887c04525409d3ff069ca66e29dea39cba9a55/img/API.png
--------------------------------------------------------------------------------
/img/Approve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1RedOne/PSReddit/5d887c04525409d3ff069ca66e29dea39cba9a55/img/Approve.png
--------------------------------------------------------------------------------
/license:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------