public async Task<Listing> Filter(Listing listing)
        {
            if (listing != null && !_settings.AllowOver18)
            {
                List<Thing> _removalList = new List<Thing>();
                foreach (var item in listing.Data.Children)
                {
                    if (item.Data is Link && ((Link)item.Data).Over18)
                    {
                        if (!_settings.AllowOver18Items ||
                            (_initialFilter.ContainsKey(((Link)item.Data).Subreddit) && _initialFilter[((Link)item.Data).Subreddit]) ||
                            await _nsfwParentCache.GetOrCreate(((Link)item.Data).Subreddit, () => IsSubredditNSFW(((Link)item.Data).Subreddit)))
                        {
                            _removalList.Add(item);
                        }
                    }
                    else if (item.Data is Subreddit)
                    {
                        _nsfwParentCache.Add(((Subreddit)item.Data).DisplayName, Task.FromResult(((Subreddit)item.Data).Over18 ?? false));
                    }
                }

                if (_removalList.Count > 0)
                {
                    foreach (var thing in _removalList)
                    {
                        listing.Data.Children.Remove(thing);
                    }
                }
            }
            return listing;
        }
		public CommentsViewModel(ViewModelBase context, Listing comments, string url, DateTime? lastRefresh, bool isLimitedContext = false)
		{
			LastRefresh = lastRefresh;
			_context = context;
			Link = _context as LinkViewModel;
			_loadFullSentinel = new LoadFullCommentsViewModel(this);
			FlatComments = new ObservableCollection<ViewModelBase>();
			ProcessUrl(url);
			_loadFullTask = new Lazy<Task>(() => Task.FromResult(true));
			LoadDump(comments);
			_commentsContentStream = new Lazy<CommentsContentStreamViewModel>(() => new CommentsContentStreamViewModel(this));
		}
		private CommentShell DumpItem(string itemId, Listing result)
		{
			CommentShell currentShell;
			if (!_comments.TryGetValue(itemId, out currentShell))
			{
				MoreViewModel moreValues;
				if (_knownUnloaded.TryGetValue(itemId, out moreValues))
				{
					result.Data.Children.Add(new Thing { Kind = "more", Data = new More { Children = moreValues.Ids, ParentId = moreValues.ParentId, Count = moreValues.Count } });
				}
				return null;
			}
			else
			{
				var firstThing = new Thing { Kind = "t1", Data = currentShell.Comment.Thing };
				result.Data.Children.Add(firstThing);

				if (currentShell.FirstChild != null)
					((Comment)firstThing.Data).Replies = DumpListing(currentShell.FirstChild);
			}
			return currentShell;
		}
        private Listing DumpListing(string firstChild)
        {
            var result = new Listing { Kind = "listing", Data = new ListingData { Children = new List<Thing>() } };
			CommentShell currentShell;
			currentShell = DumpItem(firstChild, result);


			while (currentShell != null && currentShell.NextSibling != null)
            {
				currentShell = DumpItem(currentShell.NextSibling, result);
            }
            return result;
        }
		public void LoadDump(Listing comments)
		{
			List<ViewModelBase> flatChildren = new List<ViewModelBase>();
			var firstChild = comments.Data.Children.FirstOrDefault(thing => thing.Data is Comment);
			if (firstChild == null)
				return;
			_commentOriginStack.Add(CommentOriginType.New);
			MergeComments(null, comments.Data.Children, 0);
			InsertIntoFlatList(((Comment)firstChild.Data).Id, flatChildren);
			FlatComments = new ObservableCollection<ViewModelBase>(flatChildren);
		}
        //this needs to be called on anything that comes back from a load more because reddit mostly just gives us a non structured listing of comments
        private void FixupParentage(Listing listing)
        {
            Dictionary<string, Comment> nameMap = new Dictionary<string, Comment>();
            foreach (var item in listing.Data.Children)
            {
				if (item.Data is Comment)
					nameMap.Add(((Comment)item.Data).Name, ((Comment)item.Data));
            }

            foreach (var item in new List<Thing>(listing.Data.Children))
            {
				string parentId = null;
				if (item.Data is Comment)
					parentId = ((Comment)item.Data).ParentId;
				else if (item.Data is More)
					parentId = ((More)item.Data).ParentId;

				if (parentId != null && nameMap.ContainsKey(parentId))
                {
					var targetParent = nameMap[parentId];
                    if (targetParent.Replies == null)
                        targetParent.Replies = new Listing { Data = new ListingData { Children = new List<Thing>() } };

                    targetParent.Replies.Data.Children.Add(item);
                    listing.Data.Children.Remove(item);
                }
            }
        }
Exemple #7
0
        public async Task <Listing> GetCommentsOnPost(string subreddit, string permalink, int?limit)
        {
            var maxLimit     = _userState.IsGold ? 1500 : 500;
            var guardedLimit = Math.Min(maxLimit, limit ?? maxLimit);

            string targetUri = null;

            if (permalink.Contains("reddit.com"))
            {
                permalink = permalink.Substring(permalink.IndexOf("reddit.com") + "reddit.com".Length);
            }

            if (permalink.Contains(".json?"))
            {
                targetUri = "http://www.reddit.com" + permalink;
            }
            else if (permalink.Contains("?"))
            {
                var queryPos = permalink.IndexOf("?");
                targetUri = string.Format("http://www.reddit.com{0}.json{1}", permalink.Remove(queryPos), permalink.Substring(queryPos));
            }
            else
            {
                targetUri = limit == -1 ?
                            string.Format("http://www.reddit.com{0}.json", permalink) :
                            string.Format("http://www.reddit.com{0}.json?limit={1}", permalink, limit);
            }

            Listing listing = null;

            await ThrottleRequests();
            await EnsureRedditCookie();

            var comments = await _httpClient.GetStringAsync(targetUri);

            if (comments.StartsWith("["))
            {
                var listings = JsonConvert.DeserializeObject <Listing[]>(comments);
                listing = new Listing {
                    Data = new ListingData {
                        Children = new List <Thing>()
                    }
                };
                foreach (var combinableListing in listings)
                {
                    listing.Data.Children.AddRange(combinableListing.Data.Children);
                    listing.Kind        = combinableListing.Kind;
                    listing.Data.After  = combinableListing.Data.After;
                    listing.Data.Before = combinableListing.Data.Before;
                }
            }
            else
            {
                listing = JsonConvert.DeserializeObject <Listing>(comments);
            }

            var requestedLinkInfo = listing.Data.Children.FirstOrDefault(thing => thing.Data is Link);

            if (requestedLinkInfo != null)
            {
                if (!_linkToOpMap.ContainsKey(((Link)requestedLinkInfo.Data).Name))
                {
                    _linkToOpMap.Add(((Link)requestedLinkInfo.Data).Name, ((Link)requestedLinkInfo.Data).Author);
                }
            }
            return(listing);
        }
Exemple #8
0
        public async Task <Listing> GetMoreOnListing(More more, string contentId, string subreddit)
        {
            var targetUri = "http://www.reddit.com/api/morechildren.json";

            if (more.Children.Count == 0)
            {
                return new Listing
                       {
                           Kind = "Listing",
                           Data = new ListingData()
                       }
            }
            ;

            var viableChildren = more.Children.Take(20);
            var leftovers      = more.Children.Skip(20);

            var arguments = new Dictionary <string, string>
            {
                { "children", string.Join(",", viableChildren) },
                { "link_id", contentId.Contains("_") ? contentId : "t3_" + contentId },
                { "pv_hex", "" },
                { "api_type", "json" }
            };

            if (subreddit != null)
            {
                arguments.Add("r", subreddit);
            }
            getMoreCount++;
            await ThrottleRequests();
            await EnsureRedditCookie();

            var result = await _httpClient.PostAsync(targetUri, new FormUrlEncodedContent(arguments));

            var resultString = await result.Content.ReadAsStringAsync();

            var newListing = new Listing
            {
                Kind = "Listing",
                Data = new ListingData {
                    Children = JsonConvert.DeserializeObject <JsonThing>(resultString).Json.Data.Things
                }
            };

            if (leftovers.Count() > 0)
            {
                newListing.Data.Children.Add(new Thing {
                    Kind = "more", Data = new More {
                        Children = new List <string>(leftovers), ParentId = more.ParentId, Count = (more.Count - viableChildren.Count())
                    }
                });
            }
            if (getMoreCount != 0)
            {
                return(newListing);
            }
            else
            {
                return(newListing);
            }
        }