Source

Linq2vk / src / VkontakteAPI / Linq2vk / Api.fs

namespace Linq2vk

open System
open System.Text

module Api =

    let BaseUrl = "http://api.vk.com/api.php"
    let SupportedFormat = "JSON"
    let SupportedVersion = "3.0"

    type Handle = {
        AppId : int64;
        Uid : int64;
        Secret : string;
        Sid : string;
        Expire : DateTime;
    }

    module AuxKeys =

        [<Literal>]
        let ApiId = "api_id"
        [<Literal>]
        let Format = "format"
        [<Literal>]
        let Sig = "sig"
        [<Literal>]
        let Sid = "sid"
        [<Literal>]
        let Version = "v"

        let All = [ApiId; Format; Sig; Sid; Version]


    [<AutoOpen>]
    module HelperFunctions =

        let createSignature handle query =
            let sortedQuery = Query.sort query
            sortedQuery
                |> Query.joinWith (fun (k, v) -> sprintf "%s=%s" k v)
                |> (fun args -> sprintf "%d%s%s" (handle.Uid) args (handle.Secret))
//                |> (fun s -> do Console.WriteLine(s)
//                             s)
                |> DataTools.md5

        let cleanQuery =
            let autogeneratedKeys =
                Set.ofList AuxKeys.All
            let shouldRemain k =
                not <| Set.contains k autogeneratedKeys
            Query.filterKeys shouldRemain

    let create appid uid secret sid expire = {
        AppId = appid;
        Uid = uid;
        Secret = secret;
        Sid = sid;
        Expire = DataTools.fromUnixtime expire
    }

    // Query should only contain the significant data related to an API method call
    // api_id, format, sid, sig and v attributes are added automatically
    // see HelperFunctions.cleanQuery for details
    let createQueryString handle query =
        let cleanQ = cleanQuery query
        let signature = createSignature handle cleanQ
        let auxArgs = [
            (AuxKeys.ApiId, string handle.AppId);
            (AuxKeys.Format, SupportedFormat);
            (AuxKeys.Sid, handle.Sid);
            (AuxKeys.Version, SupportedVersion);
            (AuxKeys.Sig, signature);
        ]
        let resultQ = cleanQ |> Query.addMany auxArgs
        Query.toQueryString resultQ