Exemplo n.º 1
0
    public void Import_from_UserVoice()
    {
        string        oauthKey       = Environment.GetEnvironmentVariable("USERVOICE_KEY"); //required to get emails
        const int     resultsPerPage = 20;
        var           i           = 0;
        List <object> suggestions = null;

        var client = new JsonServiceClient("http://localhost:16325")
        {
            BearerToken = Environment.GetEnvironmentVariable("TECHSTACKS_DEVELOPMENT_TOKEN")
        };

        do
        {
            var url      = $"https://servicestack.uservoice.com/api/v1/forums/176786/suggestions.json?per_page={resultsPerPage}&page={++i}&oauth_consumer_key={oauthKey}";
            var json     = url.GetJsonFromUrl(req => req.AddBearerToken(oauthKey));
            var response = (Dictionary <string, object>)JSON.parse(json);
            suggestions = (List <object>)response["suggestions"];

            var userVoiceUsers  = new Dictionary <string, UserVoiceUser>(StringComparer.OrdinalIgnoreCase);
            var techstacksUsers = new Dictionary <string, UserRef>(StringComparer.OrdinalIgnoreCase);

            UserVoiceUser toUser(object oUser)
            {
                if (!(oUser is Dictionary <string, object> user))
                {
                    return(null);
                }

                if (!user.TryGetValue("email", out var oEmail))
                {
                    "EMAIL NOT FOUND:".Print();
                    user.PrintDump();
                    return(null);
                }

                var email = (string)oEmail;

                if (!userVoiceUsers.ContainsKey("user"))
                {
                    return(new UserVoiceUser {
                        Id = (int)user["id"],
                        Name = (string)user["name"],
                        Email = email,
                        AvatarUrl = (string)user["avatar_url"],
                        CreatedAt = user["created_at"].ToString().ConvertTo <DateTime>(),
                        UpdatedAt = user["updated_at"].ToString().ConvertTo <DateTime>(),
                    });
                }

                return(null);
            }

            foreach (var oSuggestion in suggestions)
            {
                var request = new ImportUserVoiceSuggestion {
                    OrganizationId = 1,
                };

                try
                {
                    if (oSuggestion is Dictionary <string, object> suggestion)
                    {
                        request.Url   = (string)suggestion["url"];
                        request.Id    = (int)suggestion["id"];
                        request.State = (string)suggestion["state"];
                        request.Title = (string)suggestion["title"];

                        //Can be null and just have title
                        request.Text = suggestion["text"] as string;
                        if (request.Text != null)
                        {
                            request.Text = JsonTypeSerializer.Unescape(request.Text);
                        }

                        request.FormattedText = suggestion["formatted_text"] as string;
                        if (request.FormattedText != null)
                        {
                            request.FormattedText = JsonTypeSerializer.Unescape(request.FormattedText);
                        }

                        request.VoteCount = (int)suggestion["vote_count"];
                        request.CreatedAt = suggestion["created_at"].ToString().ConvertTo <DateTime>();
                        request.UpdatedAt = suggestion["updated_at"].ToString().ConvertTo <DateTime>();

                        if (suggestion.TryGetValue("category", out var category))
                        {
                            request.Category = category as string;
                        }

                        if (suggestion.TryGetValue("topic", out var oTopic) &&
                            oTopic is Dictionary <string, object> topic)
                        {
                            request.TopicId = (int)topic["id"];
                        }

                        if (suggestion.TryGetValue("creator", out var creator))
                        {
                            request.Creator = toUser(creator);
                        }

                        if (suggestion.TryGetValue("closed_at", out var oClosedAt) &&
                            oClosedAt is string closeAt)
                        {
                            request.ClosedAt = oClosedAt.ConvertTo <DateTime>();
                        }

                        if (suggestion.TryGetValue("status_changed_by", out var statusUser))
                        {
                            request.StatusChangedBy = toUser(statusUser);
                        }

                        if (suggestion.TryGetValue("status", out var oStatus) && oStatus is Dictionary <string, object> status)
                        {
                            var statusKey = (string)status["key"];
                            if (statusKey != "published")
                            {
                                request.StatusKey      = statusKey;
                                request.StatusHexColor = (string)status["hex_color"];
                            }
                        }

                        if (suggestion.TryGetValue("response", out var statusResponse) &&
                            statusResponse is Dictionary <string, object> oStatusResponse)
                        {
                            request.Response = new UserVoiceComment {
                                Text          = (string)oStatusResponse["text"],
                                FormattedText = (string)oStatusResponse["formatted_text"],
                                CreatedAt     = oStatusResponse["created_at"].ToString().ConvertTo <DateTime>(),
                            };
                            if (request.Response.Text != null)
                            {
                                request.Response.Text = JsonTypeSerializer.Unescape(request.Response.Text);
                            }

                            if (request.Response.FormattedText != null)
                            {
                                request.Response.FormattedText = JsonTypeSerializer.Unescape(request.Response.FormattedText);
                            }

                            if (oStatusResponse.TryGetValue("creator", out var responseCreator))
                            {
                                request.Response.Creator = toUser(responseCreator);
                            }
                        }

                        $"Importing Suggestion {request.Id}: {request.Title}".Print();

                        var newPost = client.Post(request);

                        $"Imported Post {newPost.PostId}: {newPost.PostSlug}".Print();
                    }
                }
                catch (Exception ex)
                {
                    $"Could not import suggestion: {ex.Message}\n{ex.StackTrace}".Print();
                    oSuggestion.PrintDump();
                }
            }
        } while (suggestions.Count >= resultsPerPage);
    }
Exemplo n.º 2
0
        public async Task <ImportUserVoiceSuggestionResponse> Any(ImportUserVoiceSuggestion request)
        {
            var user = GetUser();

            AssertOrganizationModerator(Db, request.OrganizationId, user, out var org, out var orgMember);

            var creator = await GetOrCreateUser(request.Creator);

            var existingPost = await Db.SingleAsync <Post>(x =>
                                                           (request.Url != null && x.Url == request.Url) ||
                                                           (x.RefSource == UserVoiceSource && x.RefId == request.Id));

            if (existingPost != null)
            {
                throw HttpError.Conflict($"Post already imported: /posts/{existingPost.Id}/{existingPost.Slug}");
            }

            var categoryId = await GetOrCreateCategory(request.OrganizationId, request.Category);

            var now    = DateTime.Now;
            var hidden = request.StatusKey == "declined" || request.StatusKey == "completed"
                ? now
                : (DateTime?)null;

            var statusBy = (await GetOrCreateUser(request.StatusChangedBy))?.UserName
                           ?? user.UserName;

            var labels = new List <string>();

            if (request.State != null && request.State != "closed")
            {
                labels.Add(request.State.GenerateSlug());
            }

            if (request.StatusKey != null)
            {
                labels.Add(request.StatusKey);

                var orgLabelExists = await Db.ExistsAsync <OrganizationLabel>(x =>
                                                                              x.OrganizationId == request.OrganizationId && x.Slug == request.StatusKey);

                if (!orgLabelExists)
                {
                    await Db.InsertAsync(new OrganizationLabel {
                        OrganizationId = request.OrganizationId,
                        Slug           = request.StatusKey,
                        Description    = $"UserVoice Suggestion",
                        Color          = request.StatusHexColor,
                    });
                }
            }

            Post newPost = null;

            using (var trans = Db.OpenTransaction())
            {
                newPost = new Post
                {
                    OrganizationId = request.OrganizationId,
                    UserId         = creator.Id,
                    Type           = PostType.Request,
                    Url            = request.Url,
                    Title          = request.Title,
                    Slug           = request.Slug ?? request.Title.GenerateSlug(),
                    RefSource      = "uservoice",
                    RefId          = request.Id,
                    RefUrn         = $"urn:uservoice:suggestion:{request.TopicId}:{request.Id}",
                    Created        = request.CreatedAt,
                    CreatedBy      = creator.UserName,
                    Modified       = request.UpdatedAt,
                    ModifiedBy     = creator.UserName,
                    CategoryId     = categoryId,
                    PointsModifier = request.VoteCount,
                    Hidden         = hidden,
                    HiddenBy       = statusBy,
                    Content        = request.Text,
                    ContentHtml    = request.FormattedText,
                    Labels         = labels.Count > 0 ? labels.ToArray() : null,
                };

                if (request.State == "closed")
                {
                    newPost.Status     = request.State;
                    newPost.StatusBy   = statusBy;
                    newPost.StatusDate = request.StatusChangedBy?.UpdatedAt;
                }

                newPost.Id = await Db.InsertAsync(newPost, selectIdentity : true);

                if (request.Response != null)
                {
                    var commentUser = await GetOrCreateUser(request.Response.Creator);

                    var newComment = new PostComment {
                        PostId      = newPost.Id,
                        Content     = request.Response.Text,
                        ContentHtml = request.Response.FormattedText,
                        Created     = request.Response.CreatedAt,
                        CreatedBy   = commentUser.UserName,
                        Modified    = request.Response.CreatedAt,
                        RefSource   = "uservoice",
                        RefId       = request.Id,
                        RefUrn      = $"urn:uservoice:response:{request.TopicId}:{request.Id}",
                    };

                    newComment.Id = await Db.InsertAsync(newComment, selectIdentity : true);

                    await Db.UpdateOnlyAsync(() => new Post { PinCommentId = newComment.Id },
                                             where : x => x.Id == newPost.Id && x.OrganizationId == request.OrganizationId);
                }

                trans.Commit();
            }

            return(new ImportUserVoiceSuggestionResponse {
                PostId = newPost.Id,
                PostSlug = newPost.Slug
            });
        }