Skip to content

Commit

Permalink
Merge pull request #3 from tonicebrian/library-review
Browse files Browse the repository at this point in the history
Modifications for OpenCage's Library guidelines
  • Loading branch information
nmdguerreiro authored Jan 28, 2019
2 parents 9e63b7a + 943be9a commit af63fe8
Show file tree
Hide file tree
Showing 10 changed files with 420 additions and 254 deletions.
68 changes: 67 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
This is a client library for the [OpenCage Forward and Reverse geocoding APIs](https://opencagedata.com/api).
You will need to have an API key to be able to issue requests. You can register for free [here](https://opencagedata.com/users/sign_up).

Before using this library please have a look at [best practices for using the OpenCage API](https://opencagedata.com/api#bestpractices),
particularly OpenCage's advice for [how to format forward geocoding queries](https://github.com/OpenCageData/opencagedata-misc-docs/blob/master/query-formatting.md).

## Building

You'll need to install [sbt](https://www.scala-sbt.org/) first. Then you can just run:
Expand Down Expand Up @@ -47,6 +50,18 @@ To perform reverse geocoding, all you need to do is call the `reverseGeocode` me
}
```

## No results

Sometimes you query the OpenCage API and it cannot geocode your query, it was a valid query, but no results were found.
You can check if that's the case by checking status code of the response and emptiness of the results.

```scala
val response = Await.result(responseFuture, 5.seconds)
if (response.status.code == 200 & response.results.isEmpty) {
println("Ups, we can't geolocate your query")
}
```

Note that the client is non-blocking, so if you're handling responses in an async way, you won't need to await for the future.

## Closing the client
Expand Down Expand Up @@ -78,7 +93,58 @@ This is particularly useful for forward geocoding to help improve your results.

## Sample application

If you'd like to try the sample application included with this library, just run (e.g. forward geocoding the Brandenburg Gate):
Below you have a code snippet of a minimal application using OpenCage client. First create a minimal project scaffolding
by issuing `sbt new scala/scala-seed.g8`. Then place in `src/main/scala/example/` this file

```scala
package com.github.nmdguerreiro.opencage.geocoder

import scala.concurrent.Await
import scala.concurrent.duration._

/**
* A simple sample app to show how to use the client.
*/
object OpenCageClientForwardDemoApp {
def main(args: Array[String]): Unit = {
val parser = new scopt.OptionParser[Config]("OpenCageClientApp") {
head("OpenCageClientApp", "0.1")

opt[String]('q', "query").required().action( (q, c) =>
c.copy(query = q) ).text("the query you want issue")

opt[String]('k', "key").required().action( (k, c) =>
c.copy(key = k) ).text("your authentication key")
}

parser.parse(args, Config()) match {
case Some(config) =>

val client = new OpenCageClient(config.key)
val responseFuture = client.forwardGeocode(config.query)
val response = Await.result(responseFuture, 5.seconds)

println(response)

client.close()
case None => System.exit(1)
}
}
}

case class Config(query: String = "", key: String = "")
```

and don't forget to add `Scopt` and `OpenCage` dependencies with desired versions to the newly created `build.sbt`

```scala
libraryDependencies ++= Seq(
"com.github.scopt" %% "scopt" % "X.Y.Z",
"com.opengage" %% "scala-opencage-geocoder" % "X.Y.Z"
)
```

Then if you'd like to try the sample application included with this library, just run (e.g. forward geocoding the Brandenburg Gate):

```
sbt 'run -q "Brandenburg Gate" -k <your key>'
Expand Down
34 changes: 20 additions & 14 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@ name := "scala-opencage-geocoder"

version := "0.1"
scalaVersion := "2.12.4"
coverageEnabled := true

mainClass in (Compile, packageBin) := Some("com.github.nmdguerreiro.opencage.geocoder.OpenCageClientForwardDemoApp")
mainClass in (Compile, run) := Some("com.github.nmdguerreiro.opencage.geocoder.OpenCageClientForwardDemoApp")
mainClass in(Compile, packageBin) := Some("com.github.nmdguerreiro.opencage.geocoder.OpenCageClientForwardDemoApp")
mainClass in(Compile, run) := Some("com.github.nmdguerreiro.opencage.geocoder.OpenCageClientForwardDemoApp")

libraryDependencies += "com.softwaremill.sttp" %% "core" % "1.1.6"
libraryDependencies += "com.softwaremill.sttp" %% "async-http-client-backend-future" % "1.1.6"
libraryDependencies += "com.softwaremill.sttp" %% "circe" % "1.1.6"
libraryDependencies += "io.circe" %% "circe-core" % "0.9.1"
libraryDependencies += "io.circe" %% "circe-generic" % "0.9.1"
libraryDependencies += "io.circe" %% "circe-generic-extras" % "0.9.1"
libraryDependencies += "com.github.scopt" %% "scopt" % "3.7.0"
scalacOptions += "-feature"

libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test"
libraryDependencies += "com.github.tomakehurst" % "wiremock" % "2.15.0" % Test
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.7" % Test
libraryDependencies ++= {
val circeVersion = "0.11.0"
val sttpVersion = "1.2.3"
Seq(
"com.softwaremill.sttp" %% "core" % sttpVersion,
"com.softwaremill.sttp" %% "async-http-client-backend-future" % sttpVersion,
"com.softwaremill.sttp" %% "circe" % sttpVersion,
"io.circe" %% "circe-core" % circeVersion,
"io.circe" %% "circe-generic" % circeVersion,
"io.circe" %% "circe-generic-extras" % circeVersion,

addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
"org.scalatest" %% "scalatest" % "3.0.5" % Test,
"com.github.tomakehurst" % "wiremock" % "2.20.0" % Test,
"org.apache.commons" % "commons-lang3" % "3.7" % Test
)
}

addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version = 0.13.8
sbt.version = 1.2.8
2 changes: 2 additions & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
logLevel := Level.Warn
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1")
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0")

98 changes: 98 additions & 0 deletions scalastyle-config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<scalastyle>
<name>Scalastyle standard configuration</name>
<check level="warning" class="org.scalastyle.file.FileTabChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.file.FileLengthChecker" enabled="true">
<parameters>
<parameter name="maxFileLength"><![CDATA[800]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.SpacesAfterPlusChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.file.WhitespaceEndOfLineChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.SpacesBeforePlusChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.file.FileLineLengthChecker" enabled="true">
<parameters>
<parameter name="maxLineLength"><![CDATA[160]]></parameter>
<parameter name="tabSize"><![CDATA[4]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.ClassNamesChecker" enabled="true">
<parameters>
<parameter name="regex"><![CDATA[[A-Z][A-Za-z]*]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.ObjectNamesChecker" enabled="true">
<parameters>
<parameter name="regex"><![CDATA[[A-Z][A-Za-z]*]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.PackageObjectNamesChecker" enabled="true">
<parameters>
<parameter name="regex"><![CDATA[^[a-z][A-Za-z]*$]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.EqualsHashCodeChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.IllegalImportsChecker" enabled="true">
<parameters>
<parameter name="illegalImports"><![CDATA[sun._,java.awt._]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.ParameterNumberChecker" enabled="true">
<parameters>
<parameter name="maxParameters"><![CDATA[8]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.MagicNumberChecker" enabled="true">
<parameters>
<parameter name="ignore"><![CDATA[-1,0,1,2,3]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.NoWhitespaceBeforeLeftBracketChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.NoWhitespaceAfterLeftBracketChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.ReturnChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.NullChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.NoCloneChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.NoFinalizeChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.CovariantEqualsChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.StructuralTypeChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.file.RegexChecker" enabled="true">
<parameters>
<parameter name="regex"><![CDATA[println]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.NumberOfTypesChecker" enabled="true">
<parameters>
<parameter name="maxTypes"><![CDATA[30]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.CyclomaticComplexityChecker" enabled="true">
<parameters>
<parameter name="maximum"><![CDATA[10]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.UppercaseLChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.SimplifyBooleanExpressionChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.scalariform.IfBraceChecker" enabled="true">
<parameters>
<parameter name="singleLineAllowed"><![CDATA[true]]></parameter>
<parameter name="doubleLineAllowed"><![CDATA[false]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.MethodLengthChecker" enabled="true">
<parameters>
<parameter name="maxLength"><![CDATA[50]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.MethodNamesChecker" enabled="true">
<parameters>
<parameter name="regex"><![CDATA[^[a-z][A-Za-z0-9]*$]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.NumberOfMethodsInTypeChecker" enabled="true">
<parameters>
<parameter name="maxMethods"><![CDATA[30]]></parameter>
</parameters>
</check>
<check level="warning" class="org.scalastyle.scalariform.PublicMethodsHaveTypeChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.file.NewLineAtEofChecker" enabled="true"></check>
<check level="warning" class="org.scalastyle.file.NoNewLineAtEofChecker" enabled="false"></check>
</scalastyle>
Loading

0 comments on commit af63fe8

Please sign in to comment.