Commits

Maxim Moiseev  committed 3901d9f

moved modules to separate files. implemented 'createQueryString'

  • Participants
  • Parent commits 1b8a84a

Comments (0)

Files changed (6)

File src/VkontakteAPI/Linq2vk/Api.fs

 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 =
 
+    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;
+        Expire : DateTime;
     }
 
-    let create uid secret sid expire = {
+    [<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))
+                |> DataTools.md5
+
+        let cleanQuery =
+            let autogeneratedKeys =
+                Set.ofList ["api_id"; "format"; "sig"; "sid"; "v"]
+            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
+        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 = [
+            ("app_id", string handle.AppId);
+            ("format", SupportedFormat);
+            ("sid", handle.Sid);
+            ("v", SupportedVersion);
+            ("sig", signature);
+        ]
+        let resultQ =
+            List.fold (fun q (k, v) -> Query.add k v q) cleanQ auxArgs
+        Query.toQueryString resultQ

File src/VkontakteAPI/Linq2vk/Linq2vk.fsproj

   </ItemGroup>
   <ItemGroup>
     <Compile Include="Data.fs" />
+    <Compile Include="Query.fs" />
+    <Compile Include="Login.fs" />
+    <Compile Include="Net.fs" />
     <Compile Include="Api.fs" />
+    <Compile Include="Tests.fs" />
   </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
   <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition=" Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />

File src/VkontakteAPI/Linq2vk/Login.fs

+namespace Linq2vk
+
+module Login =
+
+    let LoginUrlBase = "http://vk.com/login.php"
+
+    let makeLoginUrl (appId:int64) (settings:int64) =
+        let query = Query.fromSeq [
+            ("app", string appId);
+            ("layout", "popup");
+            ("type", "browser");
+            ("settings", string settings)
+        ]
+        sprintf "%s?%s" LoginUrlBase (Query.toQueryString query)
+
+

File src/VkontakteAPI/Linq2vk/Net.fs

+namespace Linq2vk
+
+
+//module Net =    

File src/VkontakteAPI/Linq2vk/Query.fs

+namespace Linq2vk
+
+open System.Text
+
+module Query =
+
+    type QueryImpl =
+        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 filterKeys p (Query q) =
+        Query <| List.filter (fun (k, _) -> p k) q
+
+    let toQueryString =
+        joinWith (fun (k, v) -> sprintf "%s=%s&" k v)
+
+    let sort (Query q) =
+        Query <| List.sort q

File src/VkontakteAPI/Linq2vk/Tests.fs

+namespace Linq2vk.Tests
+
+open Linq2vk
+
+//    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
+