Beispiel #1
0
        public SetModel(JsonValue json, IJsonContext context)
        {
            var dict = JsonDictionary.FromValue(json);

            SetID                  = dict.Get <long>("id", context);
            Uri                    = new Uri(dict.Get <string>("url", context));
            Title                  = dict.Get <string>("title", context);
            Author                 = dict.Get <string>("created_by", context);
            Description            = dict.Get <string>("description", context, null);
            TermCount              = dict.Get <int>("term_count", context);
            Created                = new DateTime(1970, 1, 1).AddSeconds(dict.Get <double>("created_date", context));
            Modified               = new DateTime(1970, 1, 1).AddSeconds(dict.Get <double>("modified_date", context));
            Subjects               = context.FromJson <List <string> >(dict["subjects"]);
            Visibility             = SetPermissions.ParseVisibility(dict.Get <string>("visibility", context));
            EditPermissions        = SetPermissions.ParseEditPermissions(dict.Get <string>("editable", context));
            HasAccess              = dict.Get <bool>("has_access", context);
            HasDiscussion          = dict.Get <bool>("has_discussion", context, false);
            TermLanguageCode       = dict.Get <string>("lang_terms", context, null);
            DefinitionLanguageCode = dict.Get <string>("lang_definitions", context, null);

            if (dict.Items.ContainsKey("terms"))
            {
                Terms = context.FromJson <List <TermModel> >(dict["terms"]);
            }
        }
        public PracticeItem(JsonValue json, IJsonContext ctx)
        {
            var dict = JsonDictionary.FromValue(json);

            term       = ctx.FromJson <string>(dict["term"]);
            definition = ctx.FromJson <string>(dict["definition"]);
        }
Beispiel #3
0
        public async Task <List <SetModel> > SearchSets(string query, CancellationToken cancel, IProgress <ProgressChangedEventArgs> progress = null)
        {
            var ep   = EndPoint("search/sets?q={0}&per_page=50", Uri.EscapeDataString(query));
            var json = await Fetch(ep, RequestType.Get, false, cancel, progress);

            return(JsonDictionary.FromValue(json).Get <List <SetModel> >("sets", new JsonContext()));
        }
        public RoundInfo(JsonValue json, IJsonContext ctx)
        {
            var dict = JsonDictionary.FromValue(json);

            RoundNumber = ctx.FromJson <int>(dict["roundNumber"]);
            Score       = ctx.FromJson <int>(dict["score"]);
            ItemCount   = ctx.FromJson <int>(dict["itemCount"]);
        }
Beispiel #5
0
        public Credentials(JsonValue json, IJsonContext context) : this()
        {
            var dict = JsonDictionary.FromValue(json);

            UserName = dict.Get <string>("UserName", context);
            ValidTo  = dict.Get <long>("ValidTo", context).DateTimeFromUnixTime();
            ApiToken = dict.Get <string>("ApiToken", context);
        }
        public PracticeViewModel(JsonValue json, IJsonContext ctx)
        {
            var dict = JsonDictionary.FromValue(json);

            items         = ctx.FromJson <List <PracticeItem> >(dict["items"]);
            nextItems     = ctx.FromJson <List <PracticeItem> >(dict["nextItems"]);
            failed        = ctx.FromJson <bool>(dict["failed"]);
            currentItem   = ctx.FromJson <PracticeItem>(dict["currentItem"]);
            currentIndex  = ctx.FromJson <int>(dict["currentIndex"]);
            itemCount     = ctx.FromJson <int>(dict["itemCount"]);
            score         = ctx.FromJson <int>(dict["score"]);
            round         = ctx.FromJson <int>(dict["round"]);
            lastRoundInfo = ctx.FromJson <RoundInfo>(dict["lastRoundInfo"]);
            allRounds     = new ObservableCollection <RoundInfo>(ctx.FromJson <List <RoundInfo> >(dict["allRounds"]));
            maxItemCount  = ctx.FromJson <int>(dict["maxItemCount"]);
            title         = ctx.FromJson <string>(dict["title"]);
        }
Beispiel #7
0
        public UserModel(JsonValue json, IJsonContext context)
        {
            var dict = JsonDictionary.FromValue(json);

            bool wasRelaxed = context.RelaxedNumericConversion;

            context.RelaxedNumericConversion = true;

            UserName    = dict.Get <string>("username", context);
            AccountType = dict.Get <string>("account_type", context, "free");
            SignUpDate  = new DateTime(1970, 1, 1).AddSeconds(dict.Get <double>("sign_up_date", context));

            if (dict.Items.ContainsKey("profile_image"))
            {
                ProfileImage = new Uri(dict.Get <string>("profile_image", context), UriKind.Absolute);
            }

            Sets          = dict.Get <List <SetModel> >("sets", context);
            FavouriteSets = dict.Get <List <SetModel> >("favorite_sets", context);
            Groups        = dict.Get <List <GroupModel> >("groups", context);

            if (dict.Items.ContainsKey("statistics"))
            {
                var stats = dict.GetSubDictionary("statistics");
                foreach (var k in stats.Items)
                {
                    switch (k.Key)
                    {
                    case "study_session_count": StudySessionCount = context.FromJson <int>(k.Value); break;

                    case "message_count": MessageCount = context.FromJson <int>(k.Value); break;

                    case "total_answer_count": TotalAnswerCount = context.FromJson <int>(k.Value); break;

                    case "public_sets_created": PublicSetsCreated = context.FromJson <int>(k.Value); break;

                    case "public_terms_entered": PublicTermsEntered = context.FromJson <int>(k.Value); break;
                    }
                }
            }

            context.RelaxedNumericConversion = wasRelaxed;
        }
Beispiel #8
0
        public async Task <Credentials> Authenticate(string code, CancellationToken cancel, IProgress <ProgressChangedEventArgs> progress = null)
        {
            var fields = new Dictionary <string, string>();

            fields["grant_type"]   = "authorization_code";
            fields["code"]         = code;
            fields["redirect_uri"] = "flashcards://complete-oauth";

            var basicAuth = new KeyValuePair <string, string>(clientID, secretKey);

            var json = await Fetch(new Uri("/oauth/token", UriKind.Relative), RequestType.Post, false, cancel, progress, fields, basicAuth);

            var dict = JsonDictionary.FromValue(json);
            var ctx  = new JsonContext();

            // TODO Should probably check token_type and scope properties to check we have the right type of token!
            return(new Credentials(
                       ctx.FromJson <string>(dict["user_id"]),
                       DateTime.UtcNow.AddSeconds(ctx.FromJson <double>(dict["expires_in"])),
                       ctx.FromJson <string>(dict["access_token"])));
        }
Beispiel #9
0
        public TermModel(JsonValue json, IJsonContext context)
        {
            if (json == null)
            {
                throw new ArgumentNullException("json");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            var dict = JsonDictionary.FromValue(json);

            TermID     = context.FromJson <long>(dict["id"]);
            Term       = context.FromJson <string>(dict["term"]);
            Definition = context.FromJson <string>(dict["definition"]);
            if (dict.Items.ContainsKey("image") && dict.Items["image"] is JsonDictionary)
            {
                var imageDict = dict.GetSubDictionary("image");
                ImageWidth  = imageDict.Get <int>("width", context);
                ImageHeight = imageDict.Get <int>("height", context);
            }
        }
Beispiel #10
0
        protected async Task <JsonValue> Fetch(
            Uri endPoint,
            RequestType requestType,
            bool needsToken,
            CancellationToken cancel,
            IProgress <ProgressChangedEventArgs> progress = null,
            IDictionary <string, string> postData         = null,
            KeyValuePair <string, string>?overrideAuth    = null)
        {
            if (endPoint == null)
            {
                throw new ArgumentNullException("endPoint");
            }

            var wc = new WebClient();

            if (needsToken && !Credentials.HasValue)
            {
                throw new InvalidOperationException("Cannot access this part of the Quizlet service without logging in.");
            }

            wc.Headers["User-Agent"] = "FlashcardsWP8/0.1 (" + Environment.OSVersion + "; .NET " + Environment.Version + ")";

            // Overriding is used for basic authentication for OAuth process.
            bool useClientID = false;

            if (overrideAuth != null)
            {
                wc.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(overrideAuth.Value.Key + ":" + overrideAuth.Value.Value));
            }
            else if (Credentials != null)
            {
                wc.Headers["Authorization"] = "Bearer " + Credentials.Value.ApiToken;
            }
            else
            {
                useClientID = true;
            }

            try {
                string result;
                if (requestType == RequestType.Get)
                {
                    var uri = new Uri(ServiceUri, endPoint);
                    uri    = new Uri(uri + (uri.Query == "" ? "?" : "&") + "client_id=" + clientID);
                    result = await wc.DownloadStringAsTask(uri, cancel, progress);
                }
                else
                {
                    var sb = new StringBuilder();
                    wc.Headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
                    wc.Encoding = Encoding.UTF8;
                    if (postData != null)
                    {
                        if (useClientID)
                        {
                            postData["client_id"] = clientID;
                        }
                        foreach (var kvp in postData)
                        {
                            if (sb.Length > 0)
                            {
                                sb.Append('&');
                            }
                            sb.Append(kvp.Key).Append('=').Append(Uri.EscapeDataString(kvp.Value));
                        }
                    }

                    result = await wc.UploadStringAsTask(new Uri(ServiceUri, endPoint), requestType.ToString().ToUpperInvariant(), sb.ToString(), cancel, progress);
                }

                JsonValue json = null;

                // In case of HTTP status 204 (no content). This is produced, for example, as the result of
                // a DELETE call to an endpoint.
                if (!string.IsNullOrWhiteSpace(result))
                {
                    json = JsonValue.Parse(new StringReader(result));
                }

                return(json);
            } catch (WebException e) {
                // The Quizlet API returns a JSON document explaining the error if there is one,
                // so try to use that if possible.

                try {
                    if (e.Response != null)
                    {
                        var response = (e.Response as HttpWebResponse).GetResponseStream();
                        using (var reader = new StreamReader(response)) {
                            var dict      = JsonDictionary.FromValue(JsonValue.Parse(reader));
                            var ctx       = new JsonContext();
                            var errorCode = ctx.FromJson <string>(dict["error"]);
                            var errorText = ctx.FromJson <string>(dict["error_description"]);

                            if (errorCode != null && errorText != null)
                            {
                                switch (errorCode)
                                {
                                case "invalid_access": throw new AccessDeniedException(errorText);

                                case "item_not_found": throw new ItemNotFoundException(errorText);

                                case "item_deleted": throw new ItemDeletedException(errorText);

                                default: throw new QuizletException(errorText);
                                }
                            }
                        }
                    }

                    throw new QuizletException(string.Format("Unable to contact the Quizlet server ({0}).", e.Message), e);
                } catch (FormatException) {
                    // Not JSON or invalid - just wrap the original exception
                    throw new QuizletException(e.Message, e);
                } catch (KeyNotFoundException) {
                    throw new QuizletException(e.Message, e);
                }
            }
        }