GithubHelp home page GithubHelp logo

wurfl / wurfl-microservice-client-kotlin Goto Github PK

View Code? Open in Web Editor NEW
0.0 7.0 0.0 513 KB

WURFL Microservice client for kotlin language

License: Apache License 2.0

Kotlin 100.00%
wurfl wurfl-microservice kotlin ktor ktor-client

wurfl-microservice-client-kotlin's Introduction

wurfl-microservice-client-kotlin

Requisites

  • Gradle 7.2
  • Java 11 or above
  • Kotlin 1.6.10

Ktor client library - HTTP Client Engines

WURFL Microservice kotlin uses Ktor, a library that allows using different HTTP client implementations (aka "engines"). Initial implementation of WURFL Microservice client uses Apache engine, which, as of March 2022 has guaranteed the best performance for WURFL Microservice specific use case.

Download client from Maven Central

WURFL Microservice client for kotlin is distributed on Maven Central repository, so that you can add it to your project's favourite build system.

To add it as a Maven dependency you can do:

<dependency>
  <groupId>com.scientiamobile.wurflmicroservice</groupId>
  <artifactId>wurfl-microservice-kotlin</artifactId>
  <version>1.0.0</version>
</dependency>

If you are using Gradle as a build tool, you can add it to your project with this line (groovy DSL)

implementation 'com.scientiamobile.wurflmicroservice:wurfl-microservice-kotlin:1.0.0'

or (Kotlin DSL)

implementation("com.scientiamobile.wurflmicroservice:wurfl-microservice-kotlin:1.0.0")

Create a WURFL Microservice client, print some info and set up a cache

    // First we need to create a WM client instance, to connect to our WM server API at the specified host and port.
    val client = WmClient.create("http", "localhost", "8080", "")
    // We ask Wm server API for some Wm server info such as server API version and info about WURFL API and file used by WM server.
    val info = client.getInfo()
    println("Printing WM server information")
    println("WURFL API version:  ${info.wurflApiVersion}")
    println("WM server version:  ${info.wmVersion}")
    println("Wurfl file info: ${info.wurflInfo}")

    // By setting the cache size we are also activating the caching option in WM client. 
    // In order to not use cache, you just to need to omit setCacheSize call; anyway it is strongly recommended to use cache to 
    // increase client performance
    client.setCacheSize(10000)

Perform a lookup (AKA device detection)

The lookup methods allow using serverl types of input such as the User-Agent string:

    val ua = "Mozilla/5.0 (Linux; Android 7.1.1; ONEPLUS A5000 Build/NMF26X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36"
    val device = client.lookupUseragent(ua)

Anyway, passing all available headers to the lookup method will provide a more accurate detection.

val headers = HashMap<String, String>()
    headers["Accept-Encoding"] = "gzip, deflate"
    headers["Accept"] = "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1"
    headers["Accept-Language"] = "en"
    headers["Device-Stock-Ua"] = ua
    headers["Forwarded"] = "for=\"110.54.224.195:36350\""
    headers["Save-Data"] = "on"
    headers["Referer"] = "https://www.cram.com/flashcards/labor-and-delivery-questions-889210"
    headers["User-Agent"] = "Opera/9.80 (Android; Opera Mini/51.0.2254/184.121; U; en) Presto/2.12.423 Version/12.16"
    headers["X-Clacks-Overhead"] = "GNU ph"
    headers["X-Forwarded-For"] = "110.54.224.195, 82.145.210.235"
    headers["X-Operamini-Features"] = "advanced, camera, download, file_system, folding, httpping, pingback, routing, touch, viewport"
    headers["X-Operamini-Phone"] = "Android #"
    val device = client.lookupHeaders(headers)

If you are using WURFL Microservice client inside a Java server application compliant with the Java EE specs, you can use the lookupRequest methods passing a full HttpServletRequest instance to it. If you are using the popular Kotlin framework Ktor to develop a server application, you can pass Ktor's ApplicationRequest object to the lookupRequest overloaded method.

Full code sample

Here's a code example for a console application that uses the WURFL Microservice client (you can find it inside the wmclient-kotlin-example project).

import com.scientiamobile.wurfl.wmclient.kotlin.JSONModelMktName
import com.scientiamobile.wurfl.wmclient.kotlin.WmClient
import com.scientiamobile.wurfl.wmclient.kotlin.WmException


fun main() {

    try {
        // First we need to create a WM client instance, to connect to our WM server API at the specified host and port.
        val client = WmClient.create("http", "localhost", "8080", "")
        // We ask Wm server API for some Wm server info such as server API version and info about WURFL API and file used by WM server.
        val info = client.getInfo()
        println("Printing WM server information")
        println("WURFL API version:  ${info.wurflApiVersion}")
        println("WM server version:  ${info.wmVersion}")
        println("Wurfl file info: ${info.wurflInfo}")

        val ua = "Mozilla/5.0 (Linux; Android 7.1.1; ONEPLUS A5000 Build/NMF26X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36"

        // By setting the cache size we are also activating the caching option in WM client. In order to not use cache, you just to need to omit setCacheSize call
        client.setCacheSize(100000)

        // set the capabilities we want to receive from WM server
        client.setRequestedStaticCapabilities(arrayOf("brand_name", "model_name"))
        client.setRequestedVirtualCapabilities( arrayOf("is_smartphone", "form_factor"))

        println()
        println("Detecting device for user-agent: $ua")

        // Perform a device detection calling WM server API, using only the user agent
        // val device = client.lookupUseragent(ua)

        // Perform a device detection calling WM server API, using a full HTTP request header map (there's also a lookupRequest(req: ApplicationRequest)
        // and a lookupRequest(req: HttpServletRequest) that you can use when running a WM client inside a web application on an application server like tomcat/glassfish/jboss, etc.
        // or a web framework using an embedded server like Ktor
        val headers = HashMap<String, String>()
        headers["Accept-Encoding"] = "gzip, deflate"
        headers["Accept"] = "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1"
        headers["Accept-Language"] = "en"
        headers["Device-Stock-Ua"] = ua
        headers["Forwarded"] = "for=\"110.54.224.195:36350\""
        headers["Save-Data"] = "on"
        headers["Referer"] = "https://www.cram.com/flashcards/labor-and-delivery-questions-889210"
        headers["User-Agent"] = "Opera/9.80 (Android; Opera Mini/51.0.2254/184.121; U; en) Presto/2.12.423 Version/12.16"
        headers["X-Clacks-Overhead"] = "GNU ph"
        headers["X-Forwarded-For"] = "110.54.224.195, 82.145.210.235"
        headers["X-Operamini-Features"] = "advanced, camera, download, file_system, folding, httpping, pingback, routing, touch, viewport"
        headers["X-Operamini-Phone"] = "Android #"
        val device = client.lookupHeaders(headers)

        // Applicative error, ie: invalid input provided
        if (device.error.isNotEmpty()) {
            println("An error occurred:  $device.error")
        } else {
            // Let's get the device capabilities and print some of them
            val capabilities = device.capabilities
            println("Detected device WURFL ID: ${capabilities["wurfl_id"]}")
            println("Device brand & model: ${capabilities["brand_name"]} ${capabilities["model_name"]}")
            println("Detected device form factor: ${capabilities["form_factor"]}")
            if (capabilities["is_smartphone"] == "true") {
                println("This is a smartphone")
            }

            // Iterate over all the device capabilities and print them
            println("All received capabilities")
            capabilities.keys.forEach{ println("$it :  ${capabilities[it]}") }
        }

        // Get all the device manufacturers, and print the first twenty
        val limit = 20
        val deviceMakes = client.getAllDeviceMakes()
        println("------------ Print the first $limit Brand of ${deviceMakes.size} retrieved from server ------------")

        // Sort the device manufacturer names
        deviceMakes.sort()
        val firstItems = deviceMakes.copyOfRange(0, limit + 1)
        firstItems.forEach { println(it) }

        // Now call the WM server to get all device model and marketing names produced by Apple
        println("------------ Print all Model for the Apple Brand ------------")
        val devNames = client.getAllDevicesForMake("Apple")

        // Sort ModelMktName objects by their model name
        devNames.sortWith(ByModelNameComparer())
        devNames.forEach {
            println(" - ${it.modelName} ${it.marketingName}")
        }

        // Now call the WM server to get all operative system names
        println("------------ Print the list of OSes ------------")
        val oses = client.getAllOSes()
        // Sort and print all OS names
        oses.sort()
        oses.forEach { println(" - $it")  }

        // Let's call the WM server to get all version of the Android OS
        println("------------ Print all versions for the Android OS ------------")
        val osVersions = client.getAllVersionsForOS("Android")
        // Sort all Android version numbers and print them.
        osVersions.sort()
        osVersions.forEach { println(" - $it") }

        // Cleans all client resources. Any call on client API methods after this one will throw a WmException
        client.destroy()
    } catch (e: WmException) {
        // problems such as network errors  or internal server problems
        println("An error has occurred: " + e.message)
        e.printStackTrace()
    }
    println("------------ End of WM Java client example ------------")
}

// Comparator used to sort JSONModelMktName objects according to their model name property, for which is used the String natural ordering.
internal class ByModelNameComparer : Comparator<JSONModelMktName> {
    override fun compare(o1: JSONModelMktName, o2: JSONModelMktName): Int {
        return o1.modelName.compareTo(o2.modelName)
    }
}

You can also find a server-side usage sample of WURFL Microservice client inside thewmclient-kotlin-webserver-example project

wurfl-microservice-client-kotlin's People

Contributors

andreacastello avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.