{"action":"created","comment":{"url":"https://api.github.com/repos/Gnucash/gnucash/pulls/comments/61127443","id":61127443,"diff_hunk":"@@ -0,0 +1,942 @@\n+/********************************************************************\\\n+ * Account-Imap.cpp -- Account Import Mapping                       *\n+ * Copyright (C) 2007 David Hampton <hampton@employees.org>         *\n+ * Copyright (C) 2016 Robert Fewell                                 *\n+ *                                                                  *\n+ * This program is free software; you can redistribute it and/or    *\n+ * modify it under the terms of the GNU General Public License as   *\n+ * published by the Free Software Foundation; either version 2 of   *\n+ * the License, or (at your option) any later version.              *\n+ *                                                                  *\n+ * This program is distributed in the hope that it will be useful,  *\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *\n+ * GNU General Public License for more details.                     *\n+ *                                                                  *\n+ * You should have received a copy of the GNU General Public License*\n+ * along with this program; if not, contact:                        *\n+ *                                                                  *\n+ * Free Software Foundation           Voice:  +1-617-542-5942       *\n+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *\n+ * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *\n+ *                                                                  *\n+\\********************************************************************/\n+\n+extern \"C\"\n+{\n+#include <config.h>\n+#include \"AccountP.h\"\n+#include <qof.h>\n+#include <qofinstance-p.h>\n+#include \"gnc-features.h\"\n+}\n+\n+#include \"Account-Imap.h\"\n+#include <kvp_frame.hpp>\n+\n+#include <iostream>\n+#include <string>\n+#include <algorithm>\n+#include <unordered_map>\n+\n+static QofLogModule log_module = GNC_MOD_ACCOUNT;\n+\n+\n+/* ================================================================ */\n+/* The following functions are used by\n+ * src/import-export/import-backend.c to manipulate the contra-account\n+ * matching data. See src/import-export/import-backend.c for explanations.\n+ */\n+\n+GncImportMatchMap::GncImportMatchMap (Account *acc) :\n+    m_account {acc},\n+    m_book {gnc_account_get_book(acc)}\n+{\n+    /* Cache the book for easy lookups; store the account/book for\n+     * marking dirtiness */\n+}\n+\n+GncImportMatchMap::~GncImportMatchMap()\n+{\n+}\n+\n+Account *\n+GncImportMatchMap::get_account()\n+{\n+    return m_account;\n+}\n+\n+QofBook *\n+GncImportMatchMap::get_book()\n+{\n+    return m_book;\n+}\n+\n+Account *\n+GncImportMatchMap::find_account (const char* category, const char *key)\n+{\n+    KvpValue *value;\n+\n+    if (!key) return nullptr;\n+\n+    ENTER(\" \");\n+\n+    auto slots = qof_instance_get_slots(QOF_INSTANCE(m_account));\n+\n+    if (!category)\n+        value = slots->get_slot({IMAP_FRAME, key});\n+    else\n+        value = slots->get_slot({IMAP_FRAME, category, key});\n+\n+    if (value == nullptr || value->get_type() != KvpValue::Type::GUID)\n+    {\n+       LEAVE(\"No Guid\");\n+       return nullptr;\n+    }\n+    LEAVE(\"Guid found\");\n+\n+    return xaccAccountLookup(value->get<GncGUID*>(), m_book);\n+}\n+\n+void\n+GncImportMatchMap::add_account (const char *category, const char *key, Account *acc)\n+{\n+    if (!key || !acc || (strlen (key) == 0)) return;\n+\n+    ENTER(\" \");\n+\n+    auto acc_slots = qof_instance_get_slots(QOF_INSTANCE(m_account));\n+\n+    auto acc_val = new KvpValue(const_cast<GncGUID*>(xaccAccountGetGUID(acc)));\n+\n+    xaccAccountBeginEdit (m_account);\n+\n+    if (!category)\n+        acc_slots->set_path({IMAP_FRAME, key}, acc_val);\n+    else\n+        acc_slots->set_path({IMAP_FRAME, category, key}, acc_val);\n+\n+    qof_instance_set_dirty (QOF_INSTANCE (m_account));\n+    xaccAccountCommitEdit (m_account);\n+\n+    LEAVE(\" \");\n+}\n+\n+void\n+GncImportMatchMap::delete_account (const char *category, const char *key)\n+{\n+    std::string kvp_path;\n+    std::string delim = \"/\";\n+\n+    if (!key) return;\n+\n+    ENTER(\" \");\n+\n+    std::string str_key (key);\n+\n+    if (!category)\n+        kvp_path = IMAP_FRAME + delim + str_key;\n+    else\n+    {\n+        std::string str_category (category);\n+        kvp_path = IMAP_FRAME + delim + str_category + delim + str_key;\n+    }\n+    xaccAccountBeginEdit (m_account);\n+\n+    if (qof_instance_has_slot (QOF_INSTANCE (m_account), kvp_path.c_str()))\n+    {\n+        qof_instance_slot_delete (QOF_INSTANCE (m_account), kvp_path.c_str());\n+\n+        if (category)\n+        {\n+            std::string str_category (category);\n+            kvp_path = IMAP_FRAME + delim + str_category;\n+\n+            qof_instance_slot_delete_if_empty (QOF_INSTANCE (m_account), kvp_path.c_str());\n+        }\n+        qof_instance_slot_delete_if_empty (QOF_INSTANCE (m_account), IMAP_FRAME);\n+    }\n+    qof_instance_set_dirty (QOF_INSTANCE (m_account));\n+    xaccAccountCommitEdit (m_account);\n+\n+    LEAVE(\" \");\n+}\n+\n+\n+struct account_token_count\n+{\n+    std::string account_guid; // returned account guid\n+    int64_t token_count;      // occurances of a given token for this account_guid\n+};\n+\n+/** total_count and the token_count for a given account let us calculate the\n+ * probability of a given account with any single token\n+ */\n+struct token_accounts_info\n+{\n+    GList *accounts;           // array of struct account_token_count\n+    int64_t total_token_count; // the sum of token_count for a given token\n+};\n+\n+/** gpointer is a pointer to a struct token_accounts_info\n+ * \\note Can always assume that keys are unique, reduces code in this function\n+ */\n+static void\n+buildTokenInfo(const char *key, const GValue *value, gpointer data)\n+{\n+    struct token_accounts_info *tokenInfo = (struct token_accounts_info*)data;\n+    struct account_token_count* this_account;\n+\n+    //  PINFO(\"buildTokenInfo: account '%s', token_count: '%\" G_GINT64_FORMAT \"'\", (char*)key,\n+    //                  g_value_get_int64(value));\n+\n+    /* add the count to the total_token_count */\n+    tokenInfo->total_token_count += g_value_get_int64(value);\n+\n+    /* allocate a new structure for this account and it's token count */\n+    this_account = (struct account_token_count*)\n+                   new (struct account_token_count);\n+\n+    /* fill in the account guid and number of tokens found for this account */\n+    this_account->account_guid = ((char*)key);\n+    this_account->token_count = g_value_get_int64(value);\n+\n+    /* append onto the glist a pointer to the new account_token_count structure */\n+    tokenInfo->accounts = g_list_prepend(tokenInfo->accounts, this_account);\n+}\n+\n+/** intermediate values used to calculate the bayes probability of a given\n+    account where p(AB) = (a*b)/[a*b + (1-a)(1-b)], product is (a*b),\n+    product_difference is (1-a) * (1-b)\n+ */\n+class account_probability\n+{\n+    public:\n+    double m_product;             /* product of probabilities */\n+    double m_product_difference;  /* product of (1-probabilities) */\n+\n+    account_probability (double p, double pd)\n+    {\n+        m_product = p;\n+        m_product_difference = pd;\n+    }\n+};\n+\n+/** conversion factors for the unordered map of 100000x the percentage match value,\n+    ie. 10% would be  0.10 * 100000 = 10000\n+ */\n+static const double PROBABILITY_FACTOR = 100000.0;\n+static const double CONFIDENCE {0.90}; // 90%\n+static constexpr double threshold {CONFIDENCE * PROBABILITY_FACTOR};\n+\n+/** Look up an Account in the map */\n+Account *\n+GncImportMatchMap::find_account_bayes (GList* tokens)\n+{\n+    GList *current_token;                 /**< pointer to the current token from the input GList tokens */\n+\n+    struct token_accounts_info tokenInfo; /**< holds the accounts and total token count for a single token */\n+\n+    struct account_token_count *account_c; /**< an account name and the number of times a token has appeared for the account */\n+\n+    GList *current_account_token;         /**< pointer to the struct account_token_count */\n+\n+    std::unordered_map<std::string, account_probability>probability_hash;\n+    std::string selected_account_guid;\n+    int32_t max_probability = 0;\n+    std::string delim = \"/\";\n+\n+    ENTER(\" \");\n+\n+    /* find the probability for each account that contains any of the tokens\n+     * in the input tokens list\n+     */\n+    for (current_token = tokens; current_token; current_token = current_token->next)\n+    {\n+        std::string kvp_path = IMAP_FRAME_BAYES + delim + ((char*)current_token->data);\n+\n+        /* zero out the token_accounts_info structure */\n+        memset(&tokenInfo, 0, sizeof(struct token_accounts_info));\n+","path":"src/engine/Account-Imap.cpp","position":260,"original_position":260,"commit_id":"afb6650b3838e21584f098eb12f9951438f7a4d0","original_commit_id":"afb6650b3838e21584f098eb12f9951438f7a4d0","user":{"login":"jralls","id":58910,"avatar_url":"https://avatars.githubusercontent.com/u/58910?v=3","gravatar_id":"","url":"https://api.github.com/users/jralls","html_url":"https://github.com/jralls","followers_url":"https://api.github.com/users/jralls/followers","following_url":"https://api.github.com/users/jralls/following{/other_user}","gists_url":"https://api.github.com/users/jralls/gists{/gist_id}","starred_url":"https://api.github.com/users/jralls/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jralls/subscriptions","organizations_url":"https://api.github.com/users/jralls/orgs","repos_url":"https://api.github.com/users/jralls/repos","events_url":"https://api.github.com/users/jralls/events{/privacy}","received_events_url":"https://api.github.com/users/jralls/received_events","type":"User","site_admin":false},"body":"Don't use memset on a C++ class or struct!","created_at":"2016-04-26T17:23:57Z","updated_at":"2016-04-26T17:23:57Z","html_url":"https://github.com/Gnucash/gnucash/pull/75#discussion_r61127443","pull_request_url":"https://api.github.com/repos/Gnucash/gnucash/pulls/75","_links":{"self":{"href":"https://api.github.com/repos/Gnucash/gnucash/pulls/comments/61127443"},"html":{"href":"https://github.com/Gnucash/gnucash/pull/75#discussion_r61127443"},"pull_request":{"href":"https://api.github.com/repos/Gnucash/gnucash/pulls/75"}}},"pull_request":{"url":"https://api.github.com/repos/Gnucash/gnucash/pulls/75","id":64468478,"html_url":"https://github.com/Gnucash/gnucash/pull/75","diff_url":"https://github.com/Gnucash/gnucash/pull/75.diff","patch_url":"https://github.com/Gnucash/gnucash/pull/75.patch","issue_url":"https://api.github.com/repos/Gnucash/gnucash/issues/75","number":75,"state":"open","locked":false,"title":"Start to change the Account Imap functions to c++","user":{"login":"Bob-IT","id":15702727,"avatar_url":"https://avatars.githubusercontent.com/u/15702727?v=3","gravatar_id":"","url":"https://api.github.com/users/Bob-IT","html_url":"https://github.com/Bob-IT","followers_url":"https://api.github.com/users/Bob-IT/followers","following_url":"https://api.github.com/users/Bob-IT/following{/other_user}","gists_url":"https://api.github.com/users/Bob-IT/gists{/gist_id}","starred_url":"https://api.github.com/users/Bob-IT/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Bob-IT/subscriptions","organizations_url":"https://api.github.com/users/Bob-IT/orgs","repos_url":"https://api.github.com/users/Bob-IT/repos","events_url":"https://api.github.com/users/Bob-IT/events{/privacy}","received_events_url":"https://api.github.com/users/Bob-IT/received_events","type":"User","site_admin":false},"body":"I have started to change the account Imap functions to c++\r\nThis is my first attempt at writing c++ ('ish) so may not be that great but what I have done still works.\r\n\r\nAs you can see I have separated the Imap functions to a new file, Account-Imap.cpp and .h, not sure these are the correct names, and created a class based on old structure name. I have changed the non Bayesian functions to use this class and those tests still pass. The Bayesian ones are commented out to be changed next and then the ones I added for the Import Map editor.\r\n\r\nIs this OK and the right way to go  ?","created_at":"2016-03-29T13:51:39Z","updated_at":"2016-04-26T17:23:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0f2200a6bf8e725b5470bcc950534bb798bfc7a1","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Gnucash/gnucash/pulls/75/commits","review_comments_url":"https://api.github.com/repos/Gnucash/gnucash/pulls/75/comments","review_comment_url":"https://api.github.com/repos/Gnucash/gnucash/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Gnucash/gnucash/issues/75/comments","statuses_url":"https://api.github.com/repos/Gnucash/gnucash/statuses/afb6650b3838e21584f098eb12f9951438f7a4d0","head":{"label":"Bob-IT:imap-c++","ref":"imap-c++","sha":"afb6650b3838e21584f098eb12f9951438f7a4d0","user":{"login":"Bob-IT","id":15702727,"avatar_url":"https://avatars.githubusercontent.com/u/15702727?v=3","gravatar_id":"","url":"https://api.github.com/users/Bob-IT","html_url":"https://github.com/Bob-IT","followers_url":"https://api.github.com/users/Bob-IT/followers","following_url":"https://api.github.com/users/Bob-IT/following{/other_user}","gists_url":"https://api.github.com/users/Bob-IT/gists{/gist_id}","starred_url":"https://api.github.com/users/Bob-IT/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Bob-IT/subscriptions","organizations_url":"https://api.github.com/users/Bob-IT/orgs","repos_url":"https://api.github.com/users/Bob-IT/repos","events_url":"https://api.github.com/users/Bob-IT/events{/privacy}","received_events_url":"https://api.github.com/users/Bob-IT/received_events","type":"User","site_admin":false},"repo":{"id":45734777,"name":"gnucash","full_name":"Bob-IT/gnucash","owner":{"login":"Bob-IT","id":15702727,"avatar_url":"https://avatars.githubusercontent.com/u/15702727?v=3","gravatar_id":"","url":"https://api.github.com/users/Bob-IT","html_url":"https://github.com/Bob-IT","followers_url":"https://api.github.com/users/Bob-IT/followers","following_url":"https://api.github.com/users/Bob-IT/following{/other_user}","gists_url":"https://api.github.com/users/Bob-IT/gists{/gist_id}","starred_url":"https://api.github.com/users/Bob-IT/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Bob-IT/subscriptions","organizations_url":"https://api.github.com/users/Bob-IT/orgs","repos_url":"https://api.github.com/users/Bob-IT/repos","events_url":"https://api.github.com/users/Bob-IT/events{/privacy}","received_events_url":"https://api.github.com/users/Bob-IT/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Bob-IT/gnucash","description":"Public Mirror of code.gnucash.org/gnucash","fork":true,"url":"https://api.github.com/repos/Bob-IT/gnucash","forks_url":"https://api.github.com/repos/Bob-IT/gnucash/forks","keys_url":"https://api.github.com/repos/Bob-IT/gnucash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Bob-IT/gnucash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Bob-IT/gnucash/teams","hooks_url":"https://api.github.com/repos/Bob-IT/gnucash/hooks","issue_events_url":"https://api.github.com/repos/Bob-IT/gnucash/issues/events{/number}","events_url":"https://api.github.com/repos/Bob-IT/gnucash/events","assignees_url":"https://api.github.com/repos/Bob-IT/gnucash/assignees{/user}","branches_url":"https://api.github.com/repos/Bob-IT/gnucash/branches{/branch}","tags_url":"https://api.github.com/repos/Bob-IT/gnucash/tags","blobs_url":"https://api.github.com/repos/Bob-IT/gnucash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Bob-IT/gnucash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Bob-IT/gnucash/git/refs{/sha}","trees_url":"https://api.github.com/repos/Bob-IT/gnucash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Bob-IT/gnucash/statuses/{sha}","languages_url":"https://api.github.com/repos/Bob-IT/gnucash/languages","stargazers_url":"https://api.github.com/repos/Bob-IT/gnucash/stargazers","contributors_url":"https://api.github.com/repos/Bob-IT/gnucash/contributors","subscribers_url":"https://api.github.com/repos/Bob-IT/gnucash/subscribers","subscription_url":"https://api.github.com/repos/Bob-IT/gnucash/subscription","commits_url":"https://api.github.com/repos/Bob-IT/gnucash/commits{/sha}","git_commits_url":"https://api.github.com/repos/Bob-IT/gnucash/git/commits{/sha}","comments_url":"https://api.github.com/repos/Bob-IT/gnucash/comments{/number}","issue_comment_url":"https://api.github.com/repos/Bob-IT/gnucash/issues/comments{/number}","contents_url":"https://api.github.com/repos/Bob-IT/gnucash/contents/{+path}","compare_url":"https://api.github.com/repos/Bob-IT/gnucash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Bob-IT/gnucash/merges","archive_url":"https://api.github.com/repos/Bob-IT/gnucash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Bob-IT/gnucash/downloads","issues_url":"https://api.github.com/repos/Bob-IT/gnucash/issues{/number}","pulls_url":"https://api.github.com/repos/Bob-IT/gnucash/pulls{/number}","milestones_url":"https://api.github.com/repos/Bob-IT/gnucash/milestones{/number}","notifications_url":"https://api.github.com/repos/Bob-IT/gnucash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Bob-IT/gnucash/labels{/name}","releases_url":"https://api.github.com/repos/Bob-IT/gnucash/releases{/id}","deployments_url":"https://api.github.com/repos/Bob-IT/gnucash/deployments","created_at":"2015-11-07T12:04:14Z","updated_at":"2016-01-12T10:17:56Z","pushed_at":"2016-04-24T12:32:32Z","git_url":"git://github.com/Bob-IT/gnucash.git","ssh_url":"git@github.com:Bob-IT/gnucash.git","clone_url":"https://github.com/Bob-IT/gnucash.git","svn_url":"https://github.com/Bob-IT/gnucash","homepage":"www.gnucash.org","size":166065,"stargazers_count":0,"watchers_count":0,"language":"C","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Gnucash:master","ref":"master","sha":"ec768b160c63728c0fbc9a15d34e6795ff181293","user":{"login":"Gnucash","id":544952,"avatar_url":"https://avatars.githubusercontent.com/u/544952?v=3","gravatar_id":"","url":"https://api.github.com/users/Gnucash","html_url":"https://github.com/Gnucash","followers_url":"https://api.github.com/users/Gnucash/followers","following_url":"https://api.github.com/users/Gnucash/following{/other_user}","gists_url":"https://api.github.com/users/Gnucash/gists{/gist_id}","starred_url":"https://api.github.com/users/Gnucash/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gnucash/subscriptions","organizations_url":"https://api.github.com/users/Gnucash/orgs","repos_url":"https://api.github.com/users/Gnucash/repos","events_url":"https://api.github.com/users/Gnucash/events{/privacy}","received_events_url":"https://api.github.com/users/Gnucash/received_events","type":"Organization","site_admin":false},"repo":{"id":7966650,"name":"gnucash","full_name":"Gnucash/gnucash","owner":{"login":"Gnucash","id":544952,"avatar_url":"https://avatars.githubusercontent.com/u/544952?v=3","gravatar_id":"","url":"https://api.github.com/users/Gnucash","html_url":"https://github.com/Gnucash","followers_url":"https://api.github.com/users/Gnucash/followers","following_url":"https://api.github.com/users/Gnucash/following{/other_user}","gists_url":"https://api.github.com/users/Gnucash/gists{/gist_id}","starred_url":"https://api.github.com/users/Gnucash/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gnucash/subscriptions","organizations_url":"https://api.github.com/users/Gnucash/orgs","repos_url":"https://api.github.com/users/Gnucash/repos","events_url":"https://api.github.com/users/Gnucash/events{/privacy}","received_events_url":"https://api.github.com/users/Gnucash/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Gnucash/gnucash","description":"Public Mirror of code.gnucash.org/gnucash","fork":false,"url":"https://api.github.com/repos/Gnucash/gnucash","forks_url":"https://api.github.com/repos/Gnucash/gnucash/forks","keys_url":"https://api.github.com/repos/Gnucash/gnucash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Gnucash/gnucash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Gnucash/gnucash/teams","hooks_url":"https://api.github.com/repos/Gnucash/gnucash/hooks","issue_events_url":"https://api.github.com/repos/Gnucash/gnucash/issues/events{/number}","events_url":"https://api.github.com/repos/Gnucash/gnucash/events","assignees_url":"https://api.github.com/repos/Gnucash/gnucash/assignees{/user}","branches_url":"https://api.github.com/repos/Gnucash/gnucash/branches{/branch}","tags_url":"https://api.github.com/repos/Gnucash/gnucash/tags","blobs_url":"https://api.github.com/repos/Gnucash/gnucash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Gnucash/gnucash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Gnucash/gnucash/git/refs{/sha}","trees_url":"https://api.github.com/repos/Gnucash/gnucash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Gnucash/gnucash/statuses/{sha}","languages_url":"https://api.github.com/repos/Gnucash/gnucash/languages","stargazers_url":"https://api.github.com/repos/Gnucash/gnucash/stargazers","contributors_url":"https://api.github.com/repos/Gnucash/gnucash/contributors","subscribers_url":"https://api.github.com/repos/Gnucash/gnucash/subscribers","subscription_url":"https://api.github.com/repos/Gnucash/gnucash/subscription","commits_url":"https://api.github.com/repos/Gnucash/gnucash/commits{/sha}","git_commits_url":"https://api.github.com/repos/Gnucash/gnucash/git/commits{/sha}","comments_url":"https://api.github.com/repos/Gnucash/gnucash/comments{/number}","issue_comment_url":"https://api.github.com/repos/Gnucash/gnucash/issues/comments{/number}","contents_url":"https://api.github.com/repos/Gnucash/gnucash/contents/{+path}","compare_url":"https://api.github.com/repos/Gnucash/gnucash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Gnucash/gnucash/merges","archive_url":"https://api.github.com/repos/Gnucash/gnucash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Gnucash/gnucash/downloads","issues_url":"https://api.github.com/repos/Gnucash/gnucash/issues{/number}","pulls_url":"https://api.github.com/repos/Gnucash/gnucash/pulls{/number}","milestones_url":"https://api.github.com/repos/Gnucash/gnucash/milestones{/number}","notifications_url":"https://api.github.com/repos/Gnucash/gnucash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Gnucash/gnucash/labels{/name}","releases_url":"https://api.github.com/repos/Gnucash/gnucash/releases{/id}","deployments_url":"https://api.github.com/repos/Gnucash/gnucash/deployments","created_at":"2013-02-01T21:22:29Z","updated_at":"2016-04-25T17:11:12Z","pushed_at":"2016-04-25T17:27:25Z","git_url":"git://github.com/Gnucash/gnucash.git","ssh_url":"git@github.com:Gnucash/gnucash.git","clone_url":"https://github.com/Gnucash/gnucash.git","svn_url":"https://github.com/Gnucash/gnucash","homepage":"www.gnucash.org","size":185273,"stargazers_count":385,"watchers_count":385,"language":"C","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":198,"mirror_url":null,"open_issues_count":2,"forks":198,"open_issues":2,"watchers":385,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Gnucash/gnucash/pulls/75"},"html":{"href":"https://github.com/Gnucash/gnucash/pull/75"},"issue":{"href":"https://api.github.com/repos/Gnucash/gnucash/issues/75"},"comments":{"href":"https://api.github.com/repos/Gnucash/gnucash/issues/75/comments"},"review_comments":{"href":"https://api.github.com/repos/Gnucash/gnucash/pulls/75/comments"},"review_comment":{"href":"https://api.github.com/repos/Gnucash/gnucash/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Gnucash/gnucash/pulls/75/commits"},"statuses":{"href":"https://api.github.com/repos/Gnucash/gnucash/statuses/afb6650b3838e21584f098eb12f9951438f7a4d0"}}}}