예제 #1
0
        public async Task <IActionResult> RandomAsset()
        {
            Console.WriteLine($"/pollinator/atom/randomAsset{Request.QueryString}");

            string functionString = Request.Query["asset.function"];

            SporeServerAsset[] assets = null;

            // make sure we can parse the function string
            if (Int64.TryParse(functionString, out Int64 function))
            {
                // we only support modeltypes for now,
                // TODO: support archetypes/herdtypes
                if (Enum.IsDefined(typeof(SporeModelType), function))
                {
                    var user = await _userManager.GetUserAsync(User);

                    assets = await _assetManager.GetRandomAssetsAsync(user.Id, (SporeModelType)function);
                }
                else
                {
                    Console.WriteLine($"unsupported randomAsset function: {function}");
                }
            }

            return(AtomFeedBuilder.CreateFromTemplate(
                       new RandomAssetTemplate(assets)
                       ).ToContentResult());
        }
예제 #2
0
        public UserTemplate(SporeServerUser author, SporeServerAsset[] assets)
        {
            // <feed />
            //
            var document = AtomFeedBuilder.CreateDocument("feed");

            // <id />
            AtomFeedBuilder.AddCustomElement(document, "id", $"tag:spore.com,2006:user/{author.Id}");
            // <title />
            AtomFeedBuilder.AddCustomElement(document, "title", $"{author.UserName}");
            // <updated />
            // TODO
            AtomFeedBuilder.AddCustomElement(document, "updated", $"{XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)}");
            // <author />
            AtomFeedBuilder.AddAuthorElement(document, $"{author.UserName}", $"{author.Id}");
            // <subcount />
            // TODO?
            AtomFeedBuilder.AddCustomElement(document, "subcount", "0");
            // <link />
            AtomFeedBuilder.AddLinkElement(document, "self", $"https://pollinator.spore.com/pollinator/atom/user/{author.Id}", null, null);

            // add assets to feed
            SporeAtomFeedHelper.AddAssetsToFeed(document, assets);

            // save xml
            _xml = document.OuterXml;
        }
예제 #3
0
        public AggregatorTemplate(SporeServerAggregator aggregator, int subscriberCount)
        {
            // <feed />
            //
            var document = AtomFeedBuilder.CreateDocument("feed");

            // <id />
            AtomFeedBuilder.AddCustomElement(document, "id", $"tag:spore.com,2006:aggregator/{aggregator.AggregatorId}");
            // <title />
            AtomFeedBuilder.AddCustomElement(document, "title", $"{aggregator.Name}");
            // <updated />
            AtomFeedBuilder.AddCustomElement(document, "updated", $"{XmlConvert.ToString(aggregator.Timestamp, XmlDateTimeSerializationMode.Utc)}");
            // <subtitle />
            AtomFeedBuilder.AddCustomElement(document, "subtitle", $"{aggregator.Description}");
            // <author />
            AtomFeedBuilder.AddAuthorElement(document, $"{aggregator.Author.UserName}", $"{aggregator.Author.Id}");
            // <subcount />
            AtomFeedBuilder.AddCustomElement(document, "subcount", $"{subscriberCount}");
            // <link />
            AtomFeedBuilder.AddLinkElement(document, "self", $"https://www.spore.com/pollinator/atom/aggregator/{aggregator.AggregatorId}", null, null);

            // add assets to feed
            SporeAtomFeedHelper.AddAssetsToFeed(document, aggregator.Assets.ToArray());

            // save xml
            _xml = document.OuterXml;
        }
예제 #4
0
        public async Task <IActionResult> DownloadQueue()
        {
            Console.WriteLine($"/pollinator/atom/downloadQueue{Request.QueryString}");

            var user = await _userManager.GetUserAsync(User);

            return(AtomFeedBuilder.CreateFromTemplate(
                       new DownloadQueueTemplate(user, null)
                       ).ToContentResult());
        }
        public void ClientCanReadWrittenFeed(
            AtomEventsInMemory sut,
            AtomFeedBuilder<XmlAttributedTestEventY> feedBuilder,
            XmlContentSerializer serializer)
        {
            var expected = feedBuilder.Build();

            using (var w = sut.CreateFeedWriterFor(expected))
                expected.WriteTo(w, serializer);
            using (var r = sut.CreateFeedReaderFor(expected.Locate()))
            {
                var actual = AtomFeed.ReadFrom(r, serializer);

                Assert.Equal(expected, actual, new AtomFeedComparer());
            }
        }
예제 #6
0
        public async Task <IActionResult> Aggregator(Int64 id)
        {
            Console.WriteLine($"/pollinator/atom/aggregator/{id}{Request.QueryString}");

            var aggregator = await _aggregatorManager.FindByIdAsync(id);

            // make sure the aggregator exists
            if (aggregator == null)
            {
                return(NotFound());
            }

            var subscriberCount = await _aggregatorSubscriptionManager.GetSubscriberCountAsync(aggregator);

            return(AtomFeedBuilder.CreateFromTemplate(
                       new AggregatorTemplate(aggregator, subscriberCount)
                       ).ToContentResult());
        }
예제 #7
0
        public async Task <IActionResult> Asset(Int64?id)
        {
            Console.WriteLine($"/pollinator/atom/asset/{id}{Request.QueryString}");

            var assets = new List <SporeServerAsset>();

            if (id != null)
            {
                // parameter is asset id
                var asset = await _assetManager.FindByIdAsync((Int64)id, true);

                if (asset != null)
                {
                    assets.Add(asset);
                }
            }
            else
            {
                // loop over all id queries
                foreach (var idQuery in Request.Query["id"])
                {
                    // make sure we can parse the id
                    // and that the asset exists
                    if (Int64.TryParse(idQuery, out Int64 assetId))
                    {
                        var asset = await _assetManager.FindByIdAsync(assetId, true);

                        if (asset != null)
                        {
                            assets.Add(asset);
                        }
                    }
                }
            }

            Console.WriteLine(AtomFeedBuilder.CreateFromTemplate(
                                  new AssetTemplate(assets.ToArray())
                                  ).ToContentResult().Content);

            return(AtomFeedBuilder.CreateFromTemplate(
                       new AssetTemplate(assets.ToArray())
                       ).ToContentResult());
        }
예제 #8
0
        public RandomAssetTemplate(SporeServerAsset[] assets)
        {
            // <feed />
            //
            var document = AtomFeedBuilder.CreateDocument("feed");

            // <id />
            AtomFeedBuilder.AddCustomElement(document, "id", "tag:spore.com,2006:randomAsset");
            // <title />
            AtomFeedBuilder.AddCustomElement(document, "title", "randomAsset");
            // <updated />
            AtomFeedBuilder.AddCustomElement(document, "updated", $"{XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)}");
            // <link />
            AtomFeedBuilder.AddLinkElement(document, "self", "https://pollinator.spore.com/pollinator/atom/randomAsset", null, null);

            // add assets to feed
            SporeAtomFeedHelper.AddAssetsToFeed(document, assets);

            // save xml
            _xml = document.OuterXml;
        }
예제 #9
0
        public async Task <IActionResult> AtomUser(Int64 userId)
        {
            Console.WriteLine($"/pollinator/atom/user/{userId}{Request.QueryString}");

            var user = await _userManager.FindByIdAsync(userId.ToString());

            // make sure the user exists
            if (user == null)
            {
                return(NotFound());
            }

            var assets = await _assetManager.FindAllByUserIdAsync(userId);

            Console.WriteLine(AtomFeedBuilder.CreateFromTemplate(
                                  new UserTemplate(user, assets)
                                  ).ToContentResult().Content);

            return(AtomFeedBuilder.CreateFromTemplate(
                       new UserTemplate(user, assets)
                       ).ToContentResult());
        }
예제 #10
0
        public async Task <IActionResult> HandShake()
        {
            var user = await _userManager.GetUserAsync(User);

            var asset = await _assetManager.FindByIdAsync(user.NextAssetId);

            var aggregators = await _aggregatorManager.FindByAuthorAsync(user);

            var userSubscriptions = await _userSubscriptionManager.FindAllByAuthorAsync(user);

            var aggregatorSubscriptions = await _aggregatorSubscriptionManager.FindAllByAuthorAsync(user);

            var aggregatorSubscriptionCounts = new List <Int32>();

            // retrieve subscription count for each aggregator
            foreach (var aggregator in aggregators)
            {
                var aggregatorSubscriptionCount = await _aggregatorSubscriptionManager.GetSubscriberCountAsync(aggregator);

                aggregatorSubscriptionCounts.Add(aggregatorSubscriptionCount);
            }

            // reserve new asset when
            //      * user has no reserved asset
            //      * user has a used asset
            if (user.NextAssetId == 0 ||
                (asset != null && asset.Used))
            {
                // when reserving a new asset fails, error out
                if (!await _assetManager.ReserveAsync(user))
                {
                    return(StatusCode(500));
                }
            }

            return(AtomFeedBuilder.CreateFromTemplate(
                       new HandshakeTemplate(user, aggregators, aggregatorSubscriptionCounts.ToArray(), userSubscriptions, aggregatorSubscriptions)
                       ).ToContentResult());
        }
예제 #11
0
        public void SutCanRoundTripToString(
            XmlContentSerializer serializer,
            AtomFeedBuilder<XmlAttributedTestEventY> builder)
        {
            var expected = builder.Build();
            var xml = expected.ToXmlString(serializer);

            AtomFeed actual = AtomFeed.Parse(xml, serializer);

            Assert.Equal(expected, actual, new AtomFeedComparer());
        }
예제 #12
0
        /// <summary>
        ///     Creates an ATOM feed entry for the given asset
        /// </summary>
        /// <param name="document"></param>
        /// <param name="asset"></param>
        public static void AddAssetFeedEntry(XmlDocument document, SporeServerAsset asset)
        {
            // <entry />
            //
            var entryFeed = AtomFeedBuilder.AddFeedEntry(document,
                                                         id: $"tag:spore.com,2006:asset/{asset.AssetId}",
                                                         title: $"{asset.Name}",
                                                         updated: asset.Timestamp,
                                                         subtitle: null,
                                                         authorName: $"{asset.Author.UserName}",
                                                         authorUri: $"{asset.Author.Id}",
                                                         subCount: null,
                                                         link: null);

            // <locale />
            // TODO
            AtomFeedBuilder.AddCustomElement(document, entryFeed, "locale", "en_US");
            // <modeltype />
            AtomFeedBuilder.AddCustomElement(document, entryFeed, "modeltype", $"0x{((Int64)asset.ModelType):x2}");

            // <sp:stats />
            // TODO
            if (asset.Type == SporeAssetType.Adventure)
            {
                var statsElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "sp:stats");

                // <sp:stat name="playcount" />
                var statElement = AtomFeedBuilder.AddCustomElement(document, statsElement, "sp:stat", "0");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "name", "playcount");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "type", "int");
                // <sp:stat name="difficulty" />
                statElement = AtomFeedBuilder.AddCustomElement(document, statsElement, "sp:stat", "0");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "name", "difficulty");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "type", "int");
                // <sp:stat name="rating" />
                statElement = AtomFeedBuilder.AddCustomElement(document, statsElement, "sp:stat", $"{asset.Rating}");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "name", "rating");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "type", "float");
                // <sp:stat name="pointvalue" />
                statElement = AtomFeedBuilder.AddCustomElement(document, statsElement, "sp:stat", "0");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "name", "pointvalue");
                AtomFeedBuilder.AddCustomAttribute(document, statElement, "type", "int");
            }

            // <sp:images />
            //
            if (asset.Type == SporeAssetType.Adventure)
            {
                var imagesElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "sp:images", null);

                // <sp:image_1 />
                if (asset.ImageFileUrl != null)
                {
                    AtomFeedBuilder.AddLinkElement(document, imagesElement,
                                                   name: "sp:image_1",
                                                   rel: null,
                                                   url: $"https://static.spore.com/{asset.ImageFileUrl}",
                                                   type: "image/png",
                                                   length: null);
                }
                // <sp:image_2 />
                if (asset.ImageFile2Url != null)
                {
                    AtomFeedBuilder.AddLinkElement(document, imagesElement,
                                                   name: "sp:image_2",
                                                   rel: null,
                                                   url: $"https://static.spore.com/{asset.ImageFile2Url}",
                                                   type: "image/png",
                                                   length: null);
                }
                // <sp:image_3 />
                if (asset.ImageFile3Url != null)
                {
                    AtomFeedBuilder.AddLinkElement(document, imagesElement,
                                                   name: "sp:image_3",
                                                   rel: null,
                                                   url: $"https://static.spore.com/{asset.ImageFile3Url}",
                                                   type: "image/png",
                                                   length: null);
                }
                // <sp:image_4 />
                if (asset.ImageFile4Url != null)
                {
                    AtomFeedBuilder.AddLinkElement(document, imagesElement,
                                                   name: "sp:image_4",
                                                   rel: null,
                                                   url: $"https://static.spore.com/{asset.ImageFile4Url}",
                                                   type: "image/png",
                                                   length: null);
                }
            }

            // <sp:ownership />
            //
            var ownershipElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "sp:ownership");
            // <sp:original />
            var originalElement = AtomFeedBuilder.AddCustomElement(document, ownershipElement, "sp:original", $"{asset.OriginalAssetId}");

            AtomFeedBuilder.AddCustomAttribute(document, originalElement, "name", "id");
            AtomFeedBuilder.AddCustomAttribute(document, originalElement, "type", "int");
            // <sp:parent />
            var parentElement = AtomFeedBuilder.AddCustomElement(document, ownershipElement, "sp:parent", $"{asset.ParentAssetId}");

            AtomFeedBuilder.AddCustomAttribute(document, parentElement, "name", "id");
            AtomFeedBuilder.AddCustomAttribute(document, parentElement, "type", "int");

            // <content />
            //
            var contentElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "content");

            AtomFeedBuilder.AddCustomAttribute(document, contentElement, "type", "html");
            // <img />
            var imgElement = AtomFeedBuilder.AddCustomElement(document, contentElement, "img");

            AtomFeedBuilder.AddCustomAttribute(document, imgElement, "src", $"https://static.spore.com/{asset.ThumbFileUrl}");

            // <link />
            //
            AtomFeedBuilder.AddLinkElement(document, entryFeed,
                                           rel: "enclosure",
                                           url: $"https://static.spore.com/{asset.ThumbFileUrl}",
                                           type: "image/png",
                                           length: $"{asset.Size}");

            // <link />
            //
            AtomFeedBuilder.AddLinkElement(document, entryFeed,
                                           rel: "enclosure",
                                           url: $"https://static.spore.com/{asset.ModelFileUrl}",
                                           type: $"application/x-{asset.Type.ToString().ToLower()}+xml",
                                           length: null);

            // <summary />
            //
            AtomFeedBuilder.AddCustomElement(document, entryFeed, "summary", $"{asset.Description}");

            // <category />
            //
            if (asset.Tags != null)
            {
                for (int i = 0; i < asset.Tags.Count; i++)
                {
                    // <category scheme="tag" term="tag1" />
                    // <category scheme="tag" term=" tag2" />
                    var tag             = asset.Tags.ElementAt(i);
                    var categoryElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "category");
                    AtomFeedBuilder.AddCustomAttribute(document, categoryElement, "scheme", "tag");
                    AtomFeedBuilder.AddCustomAttribute(document, categoryElement, "term", $"{(i == 0 ? "" : " ")}{tag.Tag}");
                }
            }
            if (asset.Traits != null)
            {
                foreach (var trait in asset.Traits)
                {
                    // <category scheme="consequence" term="0x2b35f523" />
                    var categoryElement = AtomFeedBuilder.AddCustomElement(document, entryFeed, "category");
                    AtomFeedBuilder.AddCustomAttribute(document, categoryElement, "scheme", "consequence");
                    AtomFeedBuilder.AddCustomAttribute(document, categoryElement, "term", $"0x{(Int64)trait.TraitType:x}");
                }
            }
        }
예제 #13
0
        public HandshakeTemplate(SporeServerUser user, SporeServerAggregator[] aggregators, Int32[] aggregatorSubscriptionCounts, SporeServerUserSubscription[] userSubscriptions, SporeServerAggregatorSubscription[] aggregatorSubscriptions)
        {
            // <handshake />
            //
            var document = AtomFeedBuilder.CreateDocument("handshake");

            // <user-id />
            AtomFeedBuilder.AddCustomElement(document, "user-id", $"{user.Id}");
            // <screen-name />
            AtomFeedBuilder.AddCustomElement(document, "screen-name", $"{user.UserName}");
            // <next-id />
            AtomFeedBuilder.AddCustomElement(document, "next-id", $"{user.NextAssetId}");
            // <refresh-rate />
            AtomFeedBuilder.AddCustomElement(document, "refresh-rate", "120");

            // <maxis-feeds />
            //
            AtomFeedBuilder.AddCustomElement(document, "maxis-feeds");

            /* We can remove this because
             * the official server returns an empty feed at the url anyways
             * maybe allow custom sporecasts here in the future?
             * AtomFeedBuilder.AddFeedEntry(document, maxisFeeds,
             *  id: "tag:spore.com,2006:maxis/adventures/en_US",
             *  title: "Maxis Adventures",
             *  updated: DateTime.Now,
             *  subtitle: "Free creations from Maxis.",
             *  authorName: null,
             *  authorUri: null,
             *  subCount: 0,
             *  link: "https://pollinator.spore.com/pollinator/atom/maxis/adventures/en_US");
             */

            // <my-feeds />
            //
            var myFeeds = AtomFeedBuilder.AddCustomElement(document, "my-feeds");

            for (int i = 0; i < aggregators.Length; i++)
            {
                var aggregator = aggregators[i];
                var aggregatorSubscriptionCount = aggregatorSubscriptionCounts[i];
                AtomFeedBuilder.AddFeedEntry(document, myFeeds,
                                             id: $"tag:spore.com,2006:aggregator/{aggregator.AggregatorId}",
                                             title: $"{aggregator.Name}",
                                             updated: DateTime.Now,
                                             subtitle: null,
                                             authorName: $"{aggregator.Author.UserName}",
                                             authorUri: $"{aggregator.AuthorId}",
                                             subCount: aggregatorSubscriptionCount,
                                             link: $"https://pollinator.spore.com/pollinator/atom/aggregator/{aggregator.AggregatorId}");
            }
            AtomFeedBuilder.AddFeedEntry(document, myFeeds,
                                         id: $"tag:spore.com,2006:user/{user.Id}",
                                         title: $"{user.UserName}",
                                         updated: DateTime.Now,
                                         subtitle: null,
                                         authorName: $"{user.UserName}",
                                         authorUri: $"{user.Id}",
                                         subCount: 0,
                                         link: $"https://pollinator.spore.com/pollinator/atom/user/{user.Id}");

            // <subscriptions />
            //
            var subscriptionsFeed = AtomFeedBuilder.AddCustomElement(document, "subscriptions");

            foreach (var subscription in userSubscriptions)
            {
                AtomFeedBuilder.AddFeedEntry(document, subscriptionsFeed,
                                             id: $"tag:spore.com,2006:user/{subscription.UserId}",
                                             title: $"{subscription.User.UserName}",
                                             updated: DateTime.Now,
                                             subtitle: null,
                                             authorName: $"{subscription.User.UserName}",
                                             authorUri: $"{subscription.UserId}",
                                             subCount: 0,
                                             link: $"https://pollinator.spore.com/pollinator/atom/user/{subscription.UserId}");
            }
            foreach (var subscription in aggregatorSubscriptions)
            {
                AtomFeedBuilder.AddFeedEntry(document, subscriptionsFeed,
                                             id: $"tag:spore.com,2006:aggregator/{subscription.AggregatorId}",
                                             title: $"{subscription.Aggregator.Name}",
                                             updated: subscription.Aggregator.Timestamp,
                                             subtitle: $"{subscription.Aggregator.Description}",
                                             authorName: $"{subscription.Aggregator.Author.UserName}",
                                             authorUri: $"{subscription.Aggregator.AuthorId}",
                                             subCount: 0,
                                             link: $"https://pollinator.spore.com/pollinator/atom/aggregator/{subscription.AggregatorId}");
            }

            // <invisible-feeds />
            //
            var invisibleFeed = AtomFeedBuilder.AddCustomElement(document, "invisible-feeds");

            AtomFeedBuilder.AddFeedEntry(document, invisibleFeed,
                                         id: "tag:spore.com,2006:downloadQueue",
                                         title: $"{user.UserName}",
                                         updated: DateTime.Now,
                                         subtitle: null,
                                         authorName: $"{user.UserName}",
                                         authorUri: $"{user.Id}",
                                         subCount: 0,
                                         link: "https://pollinator.spore.com/pollinator/atom/downloadQueue");

            // save xml
            _xml = document.OuterXml;
        }