Added retrieving API token from a local property or environment variable.

This commit is contained in:
Erik C. Thauvin 2017-11-08 01:03:22 -08:00
parent 87357f5127
commit e857d3d3aa
5 changed files with 139 additions and 39 deletions

View file

@ -17,7 +17,7 @@ poster.addPin("http://www.example.com/foo", "This is a test")
poster.deletePin("http:///www.example.com/bar")
```
[View Example](https://github.com/ethauvin/pinboard-poster/blob/master/src/main/kotlin/net/thauvin/erik/pinboard/PinboardPoster.kt#L203)
[View Example](https://github.com/ethauvin/pinboard-poster/blob/master/src/main/kotlin/net/thauvin/erik/pinboard/PinboardPoster.kt#L219)
### Java
```java
@ -116,6 +116,46 @@ logger.setLevel(Level.FINE);
or using a logging properties file.
## API Authentication Token
The token can also be located in a [properties file](https://en.wikipedia.org/wiki/.properties) or environment variable.
### Local Property
For example, using the default `PINBOARD_API_TOKEN` key value from a `local.properties` file:
```ini
# local.properties
PINBOARD_API_TOKEN=user\:TOKEN
```
```kotlin
val poster = PinboardPoster(Paths.get("local.properties"))
```
To specify your own key:
```ini
# my.properties
my.api.key=user\:TOKEN
```
```kotlin
val poster = PinboardPoster(Paths.get("my.properties"), "my.api.key")
```
### Environment Variable
If no arguments are passed to the constructor, the `PINBOARD_API_TOKEN` environment variable will be used, if any.
```sh
export PINBOARD_API_TOKEN="user:TOKEN"
```
```kotlin
val poster = PinboardPoster()
```
## API End Point
The API end point is automatically configured to `https://api.pinboard.in/v1/`. Since Pinboard uses the `del.ico.us` API, the library could potentially be used with another compatible service. To configure the API end point, use:

View file

@ -11,9 +11,6 @@ import org.apache.maven.model.Developer
import org.apache.maven.model.License
import org.apache.maven.model.Model
import org.apache.maven.model.Scm
import java.io.File
import java.io.FileInputStream
import java.util.*
val bs = buildScript {
plugins("net.thauvin.erik:kobalt-versioneye:", "net.thauvin.erik:kobalt-maven-local:")
@ -26,12 +23,6 @@ val p = project {
artifactId = name
version = "0.9.2"
val localProperties = Properties().apply {
val f = "local.properties"
if (File(f).exists()) FileInputStream(f).use { fis -> load(fis) }
}
val apiToken = localProperties.getProperty("pinboard-api-token", "")
pom = Model().apply {
description = project.description
url = "https://github.com/ethauvin/pinboard-poster"
@ -67,13 +58,13 @@ val p = project {
application {
mainClass = "net.thauvin.erik.pinboard.PinboardPosterKt"
args(apiToken)
ignoreErrorStream = true
}
application {
taskName = "runJava"
mainClass = "net.thauvin.erik.pinboard.JavaExample"
args(apiToken)
ignoreErrorStream = true
}
install {

View file

@ -31,15 +31,52 @@
*/
package net.thauvin.erik.pinboard;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class JavaExample {
public static void main(String[] args) {
final String url = "http://www.example.com/pinboard";
final PinboardPoster poster = new PinboardPoster(args[0]);
final Path properties = Paths.get("local.properties");
final PinboardPoster poster;
if (args.length == 1) {
// API Token is an argument
poster = new PinboardPoster(args[0]);
} else if (Files.exists(properties)) {
// API Token is in local.properties (PINBOARD_API_TOKEN)
final Properties p = new Properties();
try (final InputStream stream = Files.newInputStream(properties)) {
p.load(stream);
} catch (IOException ignore) {
;
}
poster = new PinboardPoster(p);
} else {
// API Token is an environment variable (PINBOARD_API_TOKEN) or empty
poster = new PinboardPoster();
}
// Set logging levels
final ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(Level.FINE);
final Logger logger = poster.getLogger();
logger.addHandler(consoleHandler);
logger.setLevel(Level.FINE);
// Add Pin
if (poster.addPin(url, "Testing", "Extended test", "test kotlin")) {
System.out.println("Added: " + url);
}
// Delete Pin
if (poster.deletePin(url)) {
System.out.println("Deleted: " + url);
}

View file

@ -31,12 +31,16 @@
*/
package net.thauvin.erik.pinboard
import net.thauvin.erik.pinboard.Constants.ENV_API_TOKEN
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import org.xml.sax.InputSource
import java.io.StringReader
import java.net.URL
import java.nio.file.Files
import java.nio.file.Paths
import java.util.*
import java.util.logging.ConsoleHandler
import java.util.logging.Level
import java.util.logging.Logger
@ -46,9 +50,21 @@ object Constants {
const val API_ENDPOINT = "https://api.pinboard.in/v1/"
const val AUTH_TOKEN = "auth_token"
const val DONE = "done"
const val ENV_API_TOKEN = "PINBOARD_API_TOKEN"
}
open class PinboardPoster(var apiToken: String) {
open class PinboardPoster() {
constructor(apiToken: String) : this() {
this.apiToken = apiToken
}
@JvmOverloads
constructor(properties: Properties, key: String = ENV_API_TOKEN) : this() {
this.apiToken = properties.getProperty(key, "")
}
var apiToken: String = if (System.getenv(ENV_API_TOKEN).isNullOrBlank()) "" else System.getenv(ENV_API_TOKEN)
var apiEndPoint: String = Constants.API_ENDPOINT
val logger: Logger by lazy { Logger.getLogger(PinboardPoster::class.java.simpleName) }
@ -201,23 +217,37 @@ open class PinboardPoster(var apiToken: String) {
}
fun main(args: Array<String>) {
if (args.size == 1) {
val url = "http://www.example.com/pinboard"
val poster = PinboardPoster(args[0])
val properties = Paths.get("local.properties")
val poster = when {
args.size == 1 ->
// API Token is an argument
PinboardPoster(args[0])
Files.exists(properties) ->
// API Token is in a local.properties (PINBOARD_API_TOKEN)
PinboardPoster(
Properties().apply {
Files.newInputStream(properties).use { fis -> load(fis) }
}.getProperty(ENV_API_TOKEN, "")
)
else ->
// API Token is an environment variable (PINBOARD_API_TOKEN) or empty;
PinboardPoster()
}
// Set logging levels
with(poster.logger) {
addHandler(ConsoleHandler().apply { level = Level.FINE })
level = Level.FINE
}
// Add Pin
if (poster.addPin(url, "Testing", "Extended test", "test kotlin")) {
println("Added: $url")
}
// Delete Pin
if (poster.deletePin(url)) {
println("Deleted: $url")
}
} else {
println("Please specify a valid API token. (eg. user:TOKEN)")
}
}

View file

@ -41,16 +41,10 @@ class PinboardPosterTest {
private val url = "http://www.foo.com/"
private val desc = "This is a test."
private val localProps = Paths.get("local.properties")
private val apiToken = if (Files.exists(localProps)) {
val p = Properties().apply { Files.newInputStream(localProps).use { fis -> load(fis) } }
p.getProperty("pinboard-api-token", "")
} else {
System.getenv("PINBOARD_API_TOKEN")
}
@Test
fun testAddPin() {
val poster = PinboardPoster("")
var poster = PinboardPoster("")
Assert.assertFalse(poster.addPin(url, desc), "apiToken: <blank>")
@ -60,13 +54,13 @@ class PinboardPosterTest {
//poster.apiToken = "foo:TESTING"
//Assert.assertFalse(poster.addPin(url, desc), "apiToken: ${poster.apiToken}")
poster.apiToken = apiToken
Assert.assertTrue(poster.addPin(url, desc), "apiToken: $apiToken")
poster = pinboardPosterInstance()
Assert.assertTrue(poster.addPin(url, desc), "apiToken: ${Constants.ENV_API_TOKEN}")
}
@Test
fun testDeletePin() {
val poster = PinboardPoster(apiToken)
val poster = pinboardPosterInstance()
poster.apiEndPoint = ""
Assert.assertFalse(poster.deletePin(url), "apiEndPoint: <blank>")
@ -76,4 +70,12 @@ class PinboardPosterTest {
Assert.assertFalse(poster.deletePin("foo.com"), "url: foo.com")
}
private fun pinboardPosterInstance(): PinboardPoster {
return if (Files.exists(localProps)) {
PinboardPoster(Properties().apply { Files.newInputStream(localProps).use { fis -> load(fis) } })
} else {
PinboardPoster()
}
}
}