Skip to content

Commit

Permalink
fix discussion create failed
Browse files Browse the repository at this point in the history
  • Loading branch information
jiacai2050 committed Jul 16, 2023
1 parent 09cf3e6 commit 3a0330b
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 34 deletions.
7 changes: 4 additions & 3 deletions core/omg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1512,9 +1512,10 @@ omg_error omg_toggle_pull(omg_context ctx, const char *full_name,
return omg_request(ctx, PATCH_METHOD, url, request, NULL);
}

omg_error omg_create_discusstion(omg_context ctx, const char *repo_id,
const char *category_id, const char *title,
const char *body, omg_discussion *out) {
omg_error omg_create_discusstion_not_used(omg_context ctx, const char *repo_id,
const char *category_id,
const char *title, const char *body,
omg_discussion *out) {

char mutation[4096];
sprintf(
Expand Down
162 changes: 138 additions & 24 deletions core/omg.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@ const std = @import("std");
const c = @cImport({
@cInclude("omg.h");
});
const mem = std.mem;
const fmt = std.fmt;

const allocator = std.heap.c_allocator;
const ResponseBuffer = std.ArrayList(u8);
const Buffer = std.ArrayList(u8);
const GRAPHQL_API = "https://api.github.com/graphql";

// Copy from https://ziglang.org/learn/samples/#using-curl-from-zig
fn writeToArrayListCallback(data: *anyopaque, size: c_uint, nmemb: c_uint, user_data: *anyopaque) callconv(.C) c_uint {
var buffer: *ResponseBuffer = @alignCast(@ptrCast(user_data));
var buffer: *Buffer = @alignCast(@ptrCast(user_data));
var typed_data: [*]u8 = @ptrCast(data);
buffer.appendSlice(typed_data[0 .. nmemb * size]) catch return 0;
return nmemb * size;
}

fn request(ctx: ?*c.struct_omg_context, url: [:0]const u8, method: [:0]const u8, payload: ?[:0]const u8) !ResponseBuffer {
fn request(ctx: ?*c.struct_omg_context, url: [:0]const u8, method: [:0]const u8, payload: ?[:0]const u8) !Buffer {
const handle: ?*c.CURL = c.omg__curl_handler(ctx);
if (c.curl_easy_setopt(handle, c.CURLOPT_URL, url.ptr) != c.CURLE_OK)
return error.CouldNotSetURL;
Expand All @@ -27,7 +29,7 @@ fn request(ctx: ?*c.struct_omg_context, url: [:0]const u8, method: [:0]const u8,
return error.CouldNotSetPayload;
}
}
var response_buffer = ResponseBuffer.init(allocator);
var response_buffer = Buffer.init(allocator);

// _ = c.curl_easy_setopt(handle, c.CURLOPT_VERBOSE, @as(c_long, 10));

Expand All @@ -43,30 +45,40 @@ fn request(ctx: ?*c.struct_omg_context, url: [:0]const u8, method: [:0]const u8,
return response_buffer;
}

fn query_inner(ctx: ?*c.struct_omg_context, owner: []const u8, name: []const u8, diag: *c.omg_error) !c.omg_repo_discussion_category {
var q = try std.fmt.allocPrintZ(allocator,
\\ query {{
\\ repository(name: "{s}", owner: "{s}") {{
fn query_inner(
ctx: ?*c.struct_omg_context,
owner: [:0]const u8,
name: [:0]const u8,
diag: *c.omg_error,
) !c.omg_repo_discussion_category {
const q =
\\ query ($owner:String!, $name:String!) {
\\ repository(owner: $owner, name: $name) {
\\ id
\\ url
\\ discussionCategories(first:100) {{
\\ edges {{
\\ node {{
\\ discussionCategories(first:100) {
\\ edges {
\\ node {
\\ id
\\ name
\\ slug
\\ }}
\\ }}
\\ }}
\\ }}
\\ }}
, .{ name, owner });
defer allocator.free(q);
\\ }
\\ }
\\ }
\\ }
\\ }
;

var payload = std.ArrayList(u8).init(allocator);
defer payload.deinit();

try std.json.stringify(.{ .query = q }, .{}, payload.writer());
try std.json.stringify(.{
.query = q,
.variables = .{
.owner = owner,
.name = name,
},
}, .{}, payload.writer());
try payload.append(0);

const resp = try request(
Expand All @@ -75,6 +87,7 @@ fn query_inner(ctx: ?*c.struct_omg_context, owner: []const u8, name: []const u8,
"POST",
payload.items[0 .. payload.items.len - 1 :0],
);
defer resp.deinit();

const CategoryList = struct {
data: struct {
Expand Down Expand Up @@ -109,21 +122,21 @@ fn query_inner(ctx: ?*c.struct_omg_context, owner: []const u8, name: []const u8,
}, std.io.getStdOut().writer());

if (json.value.errors) |e| {
const msg = try std.fmt.allocPrintZ(allocator, "{s}", .{e[0].message});
const msg = try fmt.allocPrintZ(allocator, "{s}", .{e[0].message});
defer allocator.free(msg);

diag.* = c.new_error(c.OMG_CODE_GITHUB, msg);
return error.GitHubError;
}

if (json.value.data.repository) |repo| {
const repo_id = try std.fmt.allocPrintZ(allocator, "{s}", .{repo.id});
const repo_id = try fmt.allocPrintZ(allocator, "{s}", .{repo.id});
const len = repo.discussionCategories.edges.len;
var list = try allocator.alloc(c.omg_discussion_category, len);
for (repo.discussionCategories.edges, 0..) |edge, idx| {
list[idx] = c.omg_discussion_category{
.id = try std.fmt.allocPrintZ(allocator, "{s}", .{edge.node.id}),
.name = try std.fmt.allocPrintZ(allocator, "{s}", .{edge.node.name}),
.id = try fmt.allocPrintZ(allocator, "{s}", .{edge.node.id}),
.name = try fmt.allocPrintZ(allocator, "{s}", .{edge.node.name}),
};
}

Expand All @@ -144,7 +157,7 @@ export fn omg_query_repo_discussion_category(
out: *c.omg_repo_discussion_category,
) c.omg_error {
var diag = c.omg_error{ .code = c.OMG_CODE_OK, .message = .{} };
const r = query_inner(ctx, std.mem.span(owner), std.mem.span(name), &diag) catch |e| {
const r = query_inner(ctx, mem.span(owner), mem.span(name), &diag) catch |e| {
if (c.is_ok(diag)) {
return c.new_error(c.OMG_CODE_INTERNAL, @errorName(e));
}
Expand All @@ -155,3 +168,104 @@ export fn omg_query_repo_discussion_category(
out.* = r;
return c.omg_error{ .code = c.OMG_CODE_OK, .message = .{} };
}

fn create_inner(
ctx: c.omg_context,
repo_id: [:0]const u8,
category_id: [:0]const u8,
title: [:0]const u8,
body: [:0]const u8,
diag: *c.omg_error,
) !c.omg_discussion {
const mutation =
\\ mutation($repo_id:ID!, $cat_id:ID!, $title:String!, $body:String!) {
\\ createDiscussion(
\\ input: {repositoryId: $repo_id, categoryId: $cat_id, title: $title, body: $body }
\\ ) {
\\ discussion {
\\ id
\\ title
\\ body
\\ createdAt
\\ url
\\ }
\\ }
\\ }
;
var payload = Buffer.init(allocator);
defer payload.deinit();

try std.json.stringify(.{
.query = mutation,
.variables = .{
.repo_id = repo_id,
.cat_id = category_id,
.title = title,
.body = body,
},
}, .{}, payload.writer());
try payload.append(0);

const resp = try request(
ctx,
GRAPHQL_API,
"POST",
payload.items[0 .. payload.items.len - 1 :0],
);
defer resp.deinit();

const CreateResult = struct {
data: struct {
createDiscussion: ?struct {
discussion: struct {
id: []const u8,
url: []const u8,
},
} = null,
},
errors: ?[]struct {
message: []const u8,
} = null,
};

// std.debug.print("raw:{s}\n", .{resp.items});
const json = try std.json.parseFromSlice(CreateResult, allocator, resp.items, .{
.ignore_unknown_fields = true,
});
defer json.deinit();

if (json.value.errors) |e| {
const msg = try fmt.allocPrintZ(allocator, "{s}", .{e[0].message});
defer allocator.free(msg);

diag.* = c.new_error(c.OMG_CODE_GITHUB, msg);
return error.GitHubError;
}

const dis = json.value.data.createDiscussion.?.discussion;
return c.omg_discussion{
.id = try fmt.allocPrintZ(allocator, "{s}", .{dis.id}),
.url = try fmt.allocPrintZ(allocator, "{s}", .{dis.url}),
};
}

export fn omg_create_discusstion(
ctx: c.omg_context,
repo_id: [*c]const u8,
category_id: [*c]const u8,
title: [*c]const u8,
body: [*c]const u8,
out: *c.omg_discussion,
) c.omg_error {
var diag = c.omg_error{ .code = c.OMG_CODE_OK, .message = .{} };
const r = create_inner(ctx, mem.span(repo_id), mem.span(category_id), mem.span(title), mem.span(body), &diag) catch |e| {
if (c.is_ok(diag)) {
return c.new_error(c.OMG_CODE_INTERNAL, @errorName(e));
}

return diag;
};

out.* = r;
return diag;
}
6 changes: 3 additions & 3 deletions emacs/omg-discussion.el
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@
;;;###autoload
(defun omg-discussion-create ()
(interactive)
(let* ((meta (concat "#+TITLE:"
"\n#+REPO-ID:"
(let* ((meta (concat "#+TITLE: "
"\n#+REPO-ID: "
omg-discussion-repo-id
"\n#+CATEGORY-ID:"
"\n#+CATEGORY-ID: "
omg-discussion-category-id
"\n")))
(with-current-buffer (get-buffer-create (format omg-discussion--buf-basename
Expand Down
6 changes: 3 additions & 3 deletions tests/discussion.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub fn main() !void {
const ctx = try util.init_ctx();

// https://github.com/xigua2023/test-github-api/discussions
// try create(ctx);
try create(ctx);
try query(ctx);
}

Expand All @@ -32,7 +32,7 @@ fn create(ctx: c.omg_context) !void {
const category_id = "DIC_kwDOJ8Azuc4CX6mT";
var buf = std.mem.zeroes([40]u8);
const title = try std.fmt.bufPrintZ(&buf, "Awesome Title-{d}", .{time.milliTimestamp()});
const body = "## test from omg\n Succeed!";
const body = "## Test from omg\n Succeed!";
var out = c.omg_discussion{ .url = null, .id = null };
try util.check_error(c.omg_create_discusstion(ctx, repo_id, category_id, title, body, &out));
defer {
Expand All @@ -43,5 +43,5 @@ fn create(ctx: c.omg_context) !void {
const url = std.mem.span(out.url);
try testing.expect(std.mem.indexOf(u8, url, "xigua") != null);
try testing.expect(out.id != null);
// std.debug.print("{s}-{s}\n", .{ out.url, out.id });
std.debug.print("Success: {s}-{s}\n", .{ out.url, out.id });
}
2 changes: 1 addition & 1 deletion tests/util.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn init_ctx() !c.omg_context {

pub fn check_error(err: c.omg_error) !void {
if (!c.is_ok(err)) {
std.log.err("omg_error code:{d}, msg:{s}", .{ err.code, err.message });
std.log.err("check error failed, code:{d}, msg:{s}", .{ err.code, err.message });
return error.TestUnexpectedError;
}
}

0 comments on commit 3a0330b

Please sign in to comment.