Source

Linq2vk / src / VkontakteAPI / Linq2vk / Api.fs

namespace Linq2vk

open System
open System.Text

module Net =
    
    module Query =

        type Query =
            Query of (string * string) list

        let init () =
            Query []

        let fromSeq src =
            Query <| Seq.toList src

        let add (k:string) (v:'a) (Query q) =
            Query <| (k, v.ToString()) :: q

        let joinWith f (Query q) =
            let loop (sb:StringBuilder) (s:string) =
                sb.Append(s)
            let builder =
                q |> Seq.map f
                    |> Seq.fold loop (StringBuilder())
            builder.ToString()

        let toQueryString =
            joinWith (fun (k, v) -> sprintf "%s=%s&" k v)

        let sort (Query q) =
            Query <| List.sort q


    let createSignature (uid:int64) (secret:string) (query:Query.Query) =
        let sortedQuery = Query.sort query
        sortedQuery
            |> Query.joinWith (fun (k, v) -> sprintf "%s=%s" k v)
            |> (fun args -> sprintf "%d%s%s" uid args secret)
            |> DataTools.md5

    module Tests =

        let signatureTest () =
            let query = Query.init()
                        |> Query.add "fields" "photo,sex"
                        |> Query.add "format" "JSON"
                        |> Query.add "api_id" "1854119"
                        |> Query.add "method" "getProfiles"
                        |> Query.add "uids" "100172"
                        |> Query.add "v" "3.0"
            let actual = createSignature 100172L "655df68ded" query
            let expected = "4a5bf45c9fe5c66d3afa73d8520fe46a"
            actual = expected

module Login =

    let LoginUrlBase = "http://vk.com/login.php"

    let makeLoginUrl (appId:int64) (settings:int64) =
        let query = Net.Query.fromSeq [
            ("app", string appId);
            ("layout", "popup");
            ("type", "browser");
            ("settings", string settings)
        ]
        sprintf "%s?%s" LoginUrlBase (Net.Query.toQueryString query)


module Api =

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

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