#mobile-devices #microservices #devices #client #wurfl #device-detection

wmclient

WURFL微服务(由ScientiaMobile,Inc.提供)是一种移动设备检测服务,可以快速准确地检测访问设备的500多种功能。它可以区分便携式移动设备、桌面设备、智能电视以及其他任何具有网络浏览器的设备。

2个版本

0.1.1 2021年10月27日
0.1.0 2021年10月19日

#7 in #device

Apache-2.0

49KB
707

WURFL微服务Rust客户端

WURFL微服务(由ScientiaMobile,Inc.提供)是一种移动设备检测服务,可以快速准确地检测访问设备的500多种功能。它可以区分便携式移动设备、桌面设备、智能电视以及其他任何具有网络浏览器的设备。

这是访问WURFL微服务的Rust客户端API。该API遵循开源协议,可以与其他开源或专有代码集成。为了运行,它需要一个正在运行的WURFL微服务产品实例的访问权限,例如

编译WURFL微服务客户端需要Rust 1.48或更高版本。

示例项目包含了一个控制台应用程序的客户端API使用示例

use std::collections::HashMap;
use wmclient::WmClient;

fn main() {
    // Let's create the WURFL microservice client by setting the connection data of out WURFL Microservice server
    let client_res = WmClient::new("http", "localhost", "8080", "");
    // Client is mutable because because some its internal can be modified depending on its interaction with the user or
    // the server.
    let mut client: WmClient;
    if client_res.is_ok(){
        client = client_res.unwrap();
        println!("-----------------------------------------------------------------------------------");
        println!("WURFL Microservice client created successfully. Rust client API version: {}", client.get_api_version());
        println!("-----------------------------------------------------------------------------------");
    } else {
        println!("Unable to create WURFL Microservice client: {}", client_res.err().unwrap().to_string());
        return;
    }
    // Let's add the caching layer to the client
    client.set_cache_size(10000);
    // Let's gather some server info.
    let info_res = client.get_info();
    if info_res.is_err(){
        println!("Unable to get server info. Exiting.");
        return;
    }
    let info = info_res.unwrap();
    println!("WURFL Microservice information:");
    println!("Server version: {}", info.wm_version);
    println!("WURFL API version: {}", info.wurfl_api_version);
    println!("WURFL file info: {}", info.wurfl_info);

    // set the capabilities we want to receive from WM server
    // Static capabilities
    let static_caps = vec! {"model_name brand_name"};
    client.set_requested_static_capabilities(Some(static_caps));
    // Virtual capabilities
    let virtual_caps = vec! {"is_smartphone form_factor"};
    client.set_requested_virtual_capabilities(Some(virtual_caps));

    // use this headers to perform a device detection.
    let mut headers = HashMap::new();
    headers.insert("Content-Type", "application/json");
    headers.insert("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.insert("Accept-Encoding", "gzip, deflate");
    headers.insert("Accept-Language", "en");
    headers.insert("Device-Stock-Ua", "Mozilla/5.0 (Linux; Android 8.1.0; SM-J610G Build/M1AJQ; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.100 Mobile Safari/537.36");
    headers.insert("Forwarded", "for=\"110.54.224.195:36350\"");
    headers.insert("Referer", "https://www.cram.com/flashcards/labor-and-delivery-questions-889210");
    headers.insert("User-Agent", "Opera/9.80 (Android; Opera Mini/51.0.2254/184.121; U; en) Presto/2.12.423 Version/12.16");
    headers.insert("X-Clacks-Overhead", "GNU ph");
    headers.insert("X-Forwarded-For", "110.54.224.195, 82.145.210.235");
    headers.insert("X-Operamini-Features", "advanced, camera, download, file_system, folding, httpping, pingback, routing, touch, viewport");
    headers.insert("X-Operamini-Phone", "Android #");
    headers.insert("X-Operamini-Phone-Ua", "Mozilla/5.0 (Linux; Android 8.1.0; SM-J610G Build/M1AJQ; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.100 Mobile Safari/537.36");

    let device_res = client.lookup_headers(headers);
    if device_res.is_err(){
        println!("Unable to detect device from the given HTTP headers: {}", device_res.err().unwrap().to_string());
        return;
    }
    // No error, let's get the device data
    let device = device_res.unwrap();
    let wurfl_id_opt = device.capabilities.get("wurfl_id");
    if wurfl_id_opt.is_some() {
        println!("-----------------------------------------------------------------------------------");
        println!("Sample device detection using sample headers");
        println!("WURFL device ID : {}", wurfl_id_opt.unwrap());
    }
    // If you are sure the capability you're querying exists and is in your required set, just unwrap the capability option
    println!("This device is a : {} {}", device.capabilities.get("brand_name").unwrap(), device.capabilities.get("model_name").unwrap());

    // check if device is a smartphone (a virtual capability)
    if device.capabilities.get("is_smartphone").unwrap() == "true" {
        println!("This is a smartphone")
    }
    println!("This device form_factor is: {}", device.capabilities.get("form_factor").unwrap());

    // Get all the device manufacturers, and print the first twenty
    let makes_res = client.get_all_device_makes();
    if makes_res.is_err() {
        let err_mk = makes_res.as_ref().err().unwrap();
        println!("Error getting device makes data {}", err_mk.to_string());
    }


    let mut device_makes = makes_res.unwrap();
    device_makes.sort();
    let limit = 20;
    println!("-----------------------------------------------------------------------------------");
    println!("Print the first {} brand_names of {} found", limit, device_makes.len());
    println!("-----------------------------------------------------------------------------------");

    for _i in 0..limit {
        println!("{}", device_makes.get(_i).unwrap());
    }

    // Now call the WM server to get all device model and marketing names produced by Apple
    let model_marketing_names_opt = client.get_all_devices_for_make("Apple".to_string());
    if model_marketing_names_opt.is_err(){
        let err_mmkt = model_marketing_names_opt.as_ref().err().unwrap();
        println!("Error getting device model and marketing data for Apple:  {}", err_mmkt.to_string());
    }

    let mut model_marketing_names = model_marketing_names_opt.unwrap();
    // Sort model_marketing_names structs by their model name, using natural ordering (thus Uppercase names come first, then lowercase)
    model_marketing_names.sort_by(|a,b| a.model_name.cmp(&b.model_name));
    println!("-----------------------------------------------------------------------------------");
    println!("Printing all model and marketing names for Apple brand");
    println!("-----------------------------------------------------------------------------------");
    for name in model_marketing_names{
        println!("- {} {}", name.model_name, name.marketing_name);
    }

    // Now call the WM server to get all operating system names
    println!("-----------------------------------------------------------------------------------");
    println!("Print the list of OSes");
    println!("-----------------------------------------------------------------------------------");
    let os_opt = client.get_all_oses();
    if os_opt.is_err(){
        let os_err = os_opt.as_ref().err().unwrap();
        println!("Unable to get the list of operating systems: {}", os_err.to_string());
    }
    let mut os_list = os_opt.unwrap();
    os_list.sort();
    for os in os_list {
        println!("- {}", os);
    }

    println!("-----------------------------------------------------------------------------------");
    println!("Print all version numbers for Android OS");
    println!("-----------------------------------------------------------------------------------");
    let android_ver_opt = client.get_all_versions_for_os("Android");
    if android_ver_opt.is_err(){
        let ver_err = android_ver_opt.as_ref().err().unwrap();
        println!("Unable to get versions for Android OS: {}", ver_err.to_string());
    }
    let android_versions = android_ver_opt.unwrap();
    for v in android_versions {
        println!("- {}", v);
    }
}

Crates.io发行说明

wmclient软件包通过crates.io发行,包含单元测试或示例。如果您需要运行测试,请克隆GitHub存储库,或者如果您需要特定版本的代码,请从GitHub发行页面下载zip文件。

依赖关系

~9–22MB
~379K SLoC