{"action":"created","comment":{"url":"https://api.github.com/repos/ubtue/ub_tools/pulls/comments/55187909","id":55187909,"diff_hunk":"@@ -0,0 +1,221 @@\n+/** \\file    add_author_synonyms.cc\n+ *  \\brief   Adds author synonyms to each record.\n+ *  \\author  Oliver Obenland\n+ */\n+\n+/*\n+    Copyright (C) 2016, Library of the University of Tübingen\n+\n+    This program is free software: you can redistribute it and/or modify\n+    it under the terms of the GNU Affero General Public License as\n+    published by the Free Software Foundation, either version 3 of the\n+    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 Affero General Public License for more details.\n+\n+    You should have received a copy of the GNU Affero General Public License\n+    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n+*/\n+\n+#include <iostream>\n+#include <vector>\n+#include <cstdlib>\n+#include \"Compiler.h\"\n+#include \"MarcUtil.h\"\n+#include \"MediaTypeUtil.h\"\n+#include \"StringUtil.h\"\n+#include \"Subfields.h\"\n+#include \"util.h\"\n+\n+\n+static unsigned modified_count(0);\n+static unsigned record_count(0);\n+\n+\n+void Usage() {\n+    std::cerr << \"Usage: \" << ::progname << \" master_marc_input norm_data_marc_input marc_output\\n\";\n+    std::exit(EXIT_FAILURE);\n+}\n+\n+\n+void RemoveCommasDuplicatesAndEmptyEntries(std::vector<std::string> * const vector) {\n+    std::vector<std::string> cleaned_up_vector;\n+    std::set<std::string> uniqe_entries;\n+\n+    for (auto &entry : *vector) {\n+        StringUtil::RemoveChars(\",\", &entry);\n+\n+        if (entry.empty())\n+            continue;\n+\n+        const bool is_new_entry(uniqe_entries.emplace(entry).second);\n+        if (is_new_entry)\n+            cleaned_up_vector.emplace_back(std::move(entry));\n+    }\n+    vector->swap(cleaned_up_vector);\n+}\n+\n+\n+std::string ExtractNameFromSubfields(const std::string &field_contents, const std::string &subfield_codes) {\n+    const Subfields subfields(field_contents);\n+    std::vector<std::string> subfield_values;\n+    if (subfields.extractSubfields(subfield_codes, &subfield_values) == 0)\n+        return \"\";\n+\n+    std::sort(subfield_values.begin(), subfield_values.end());\n+    return StringUtil::Join(subfield_values, ' ');\n+}\n+\n+\n+void ExtractSynonyms(File * const marc_input, std::map<std::string, std::string> &author_to_synonyms_map,\n+                     const std::string &field_list)\n+{\n+    std::set<std::string> synonyms;\n+    std::vector<std::string> tags_and_subfield_codes;\n+    if (unlikely(StringUtil::Split(field_list, ':', &tags_and_subfield_codes) < 2))\n+        Error(\"in ExtractSynonymsAndWriteSynonymMap: need at least two fields!\");\n+    unsigned count(0);\n+    while (const MarcUtil::Record record = MarcUtil::Record::XmlFactory(marc_input)) {\n+        ++count;\n+\n+        const int primary_name_field_index(record.getFieldIndex(tags_and_subfield_codes[0].substr(0, 3)));\n+        if (primary_name_field_index == -1)\n+            continue;\n+\n+        const std::vector<std::string> &fields(record.getFields());\n+        const std::string primary_name(ExtractNameFromSubfields(fields[primary_name_field_index], tags_and_subfield_codes[0].substr(3)));\n+        if (unlikely(primary_name.empty()))\n+            continue;\n+\n+        std::vector<std::string> alternatives;\n+        alternatives.emplace_back(primary_name);\n+        if (author_to_synonyms_map.find(primary_name) != author_to_synonyms_map.end())\n+            continue;\n+\n+        const std::vector<DirectoryEntry> &dir_entries(record.getDirEntries());\n+\n+        for (unsigned i(1); i < tags_and_subfield_codes.size(); ++i) {\n+            const std::string tag(tags_and_subfield_codes[i].substr(0, 3));\n+            const std::string secondary_field_subfield_codes(tags_and_subfield_codes[i].substr(3));\n+            int secondary_name_field_index(record.getFieldIndex(tag));\n+            while (secondary_name_field_index != -1 and static_cast<size_t>(secondary_name_field_index) < dir_entries.size()\n+                   and dir_entries[secondary_name_field_index].getTag() == tag)\n+            {\n+                const std::string secondary_name(ExtractNameFromSubfields(fields[secondary_name_field_index],\n+                                                                          secondary_field_subfield_codes));\n+                if (not secondary_name.empty())\n+                    alternatives.emplace_back(secondary_name);\n+                ++secondary_name_field_index;\n+            }\n+        }\n+\n+        RemoveCommasDuplicatesAndEmptyEntries(&alternatives);\n+        if (alternatives.size() <= 1)\n+            continue;\n+\n+        alternatives.erase(alternatives.begin());\n+        author_to_synonyms_map.emplace(primary_name, StringUtil::Join(alternatives, ','));\n+    }\n+\n+    std::cout << \"Found synonys for \" << author_to_synonyms_map.size() << \" authors while processing \" << count\n+              << \" norm data records.\\n\";\n+}\n+\n+\n+void ProcessRecord(MarcUtil::Record * const record, const std::map<std::string, std::string> &author_to_synonyms_map,\n+                   const std::string &primary_author_field)\n+{\n+    const std::vector<DirectoryEntry> &dir_entries(record->getDirEntries());\n+    if (dir_entries.at(0).getTag() != \"001\")\n+        Error(\"First field of record is not \\\"001\\\"!\");\n+\n+    const int primary_name_field_index(record->getFieldIndex(primary_author_field.substr(0, 3)));\n+    if (primary_name_field_index == -1)\n+        return;\n+\n+    const std::vector<std::string> &fields(record->getFields());\n+    const std::string primary_name(ExtractNameFromSubfields(fields[primary_name_field_index], primary_author_field.substr(3)));\n+    if (unlikely(primary_name.empty()))\n+        return;\n+\n+    const auto synonyms_iterator = author_to_synonyms_map.find(primary_name);\n+    if (synonyms_iterator == author_to_synonyms_map.end())\n+        return;\n+\n+    const std::string synonyms = synonyms_iterator->second;\n+    Subfields subfields(/* indicator1 = */' ', /* indicator2 = */' ');\n+    subfields.addSubfield('a', synonyms);\n+\n+    if (not record->insertField(\"101\", subfields.toString())) {\n+        Warning(\"Not enough room to add a 101 field! (Control number: \" + fields[0] + \")\");\n+        return;\n+    }\n+    ++modified_count;\n+}\n+\n+\n+void AddAuthorSynonyms(File * const marc_input, File * marc_output, const std::map<std::string, std::string> &author_to_synonyms_map,\n+                       const std::string &primary_author_field)\n+{\n+    XmlWriter xml_writer(marc_output);\n+    xml_writer.openTag(\"collection\", { std::make_pair(\"xmlns\", \"http://www.loc.gov/MARC21/slim\") });\n+\n+    while (MarcUtil::Record record = MarcUtil::Record::XmlFactory(marc_input)) {\n+        ProcessRecord(&record, author_to_synonyms_map, primary_author_field);\n+        record.write(&xml_writer);\n+        ++record_count;\n+    }\n+\n+    xml_writer.closeTag();\n+\n+    std::cerr << \"Modified \" << modified_count << \" of \" << record_count << \" record(s).\\n\";\n+}\n+\n+\n+std::unique_ptr<File> OpenInputFile(const std::string &filename) {\n+    std::string mode(\"r\");\n+    mode += MediaTypeUtil::GetFileMediaType(filename) == \"application/lz4\" ? \"u\" : \"m\";\n+    std::unique_ptr<File> file(new File(filename, mode));\n+    if (file == nullptr)\n+        Error(\"can't open \\\"\" + filename + \"\\\" for reading!\");\n+\n+    return file;\n+}\n+\n+\n+int main(int argc, char **argv) {\n+    progname = argv[0];\n+\n+    if (argc != 4)\n+        Usage();\n+\n+    const std::string marc_input_filename(argv[1]);\n+    std::unique_ptr<File> marc_input(OpenInputFile(marc_input_filename));\n+\n+    const std::string norm_data_marc_input_filename(argv[2]);\n+    std::unique_ptr<File> norm_data_marc_input(OpenInputFile(norm_data_marc_input_filename));\n+\n+    const std::string marc_output_filename(argv[3]);\n+    if (unlikely(marc_input_filename == marc_output_filename))\n+        Error(\"Master input file name equals output file name!\");\n+    if (unlikely(norm_data_marc_input_filename == marc_output_filename))\n+        Error(\"Auxiallary input file name equals output file name!\");","path":"cpp/add_author_synonyms.cc","position":205,"original_position":205,"commit_id":"6f051d8f5d1048d52ccdd3910436acf50934d948","original_commit_id":"6f051d8f5d1048d52ccdd3910436acf50934d948","user":{"login":"ruschein","id":991243,"avatar_url":"https://avatars.githubusercontent.com/u/991243?v=3","gravatar_id":"","url":"https://api.github.com/users/ruschein","html_url":"https://github.com/ruschein","followers_url":"https://api.github.com/users/ruschein/followers","following_url":"https://api.github.com/users/ruschein/following{/other_user}","gists_url":"https://api.github.com/users/ruschein/gists{/gist_id}","starred_url":"https://api.github.com/users/ruschein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ruschein/subscriptions","organizations_url":"https://api.github.com/users/ruschein/orgs","repos_url":"https://api.github.com/users/ruschein/repos","events_url":"https://api.github.com/users/ruschein/events{/privacy}","received_events_url":"https://api.github.com/users/ruschein/received_events","type":"User","site_admin":false},"body":"Auxillary","created_at":"2016-03-07T10:53:49Z","updated_at":"2016-03-07T10:53:49Z","html_url":"https://github.com/ubtue/ub_tools/pull/313#discussion_r55187909","pull_request_url":"https://api.github.com/repos/ubtue/ub_tools/pulls/313","_links":{"self":{"href":"https://api.github.com/repos/ubtue/ub_tools/pulls/comments/55187909"},"html":{"href":"https://github.com/ubtue/ub_tools/pull/313#discussion_r55187909"},"pull_request":{"href":"https://api.github.com/repos/ubtue/ub_tools/pulls/313"}}},"pull_request":{"url":"https://api.github.com/repos/ubtue/ub_tools/pulls/313","id":61733890,"html_url":"https://github.com/ubtue/ub_tools/pull/313","diff_url":"https://github.com/ubtue/ub_tools/pull/313.diff","patch_url":"https://github.com/ubtue/ub_tools/pull/313.patch","issue_url":"https://api.github.com/repos/ubtue/ub_tools/issues/313","number":313,"state":"open","locked":false,"title":"Add author synonyms tool","user":{"login":"oobenland","id":1352796,"avatar_url":"https://avatars.githubusercontent.com/u/1352796?v=3","gravatar_id":"","url":"https://api.github.com/users/oobenland","html_url":"https://github.com/oobenland","followers_url":"https://api.github.com/users/oobenland/followers","following_url":"https://api.github.com/users/oobenland/following{/other_user}","gists_url":"https://api.github.com/users/oobenland/gists{/gist_id}","starred_url":"https://api.github.com/users/oobenland/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oobenland/subscriptions","organizations_url":"https://api.github.com/users/oobenland/orgs","repos_url":"https://api.github.com/users/oobenland/repos","events_url":"https://api.github.com/users/oobenland/events{/privacy}","received_events_url":"https://api.github.com/users/oobenland/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-03-04T16:17:50Z","updated_at":"2016-03-07T10:53:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"73d355e16350b936f56e5a401a81b97e9d9a4b85","assignee":{"login":"ruschein","id":991243,"avatar_url":"https://avatars.githubusercontent.com/u/991243?v=3","gravatar_id":"","url":"https://api.github.com/users/ruschein","html_url":"https://github.com/ruschein","followers_url":"https://api.github.com/users/ruschein/followers","following_url":"https://api.github.com/users/ruschein/following{/other_user}","gists_url":"https://api.github.com/users/ruschein/gists{/gist_id}","starred_url":"https://api.github.com/users/ruschein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ruschein/subscriptions","organizations_url":"https://api.github.com/users/ruschein/orgs","repos_url":"https://api.github.com/users/ruschein/repos","events_url":"https://api.github.com/users/ruschein/events{/privacy}","received_events_url":"https://api.github.com/users/ruschein/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/ubtue/ub_tools/pulls/313/commits","review_comments_url":"https://api.github.com/repos/ubtue/ub_tools/pulls/313/comments","review_comment_url":"https://api.github.com/repos/ubtue/ub_tools/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ubtue/ub_tools/issues/313/comments","statuses_url":"https://api.github.com/repos/ubtue/ub_tools/statuses/6f051d8f5d1048d52ccdd3910436acf50934d948","head":{"label":"ubtue:obenland","ref":"obenland","sha":"6f051d8f5d1048d52ccdd3910436acf50934d948","user":{"login":"ubtue","id":12495698,"avatar_url":"https://avatars.githubusercontent.com/u/12495698?v=3","gravatar_id":"","url":"https://api.github.com/users/ubtue","html_url":"https://github.com/ubtue","followers_url":"https://api.github.com/users/ubtue/followers","following_url":"https://api.github.com/users/ubtue/following{/other_user}","gists_url":"https://api.github.com/users/ubtue/gists{/gist_id}","starred_url":"https://api.github.com/users/ubtue/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ubtue/subscriptions","organizations_url":"https://api.github.com/users/ubtue/orgs","repos_url":"https://api.github.com/users/ubtue/repos","events_url":"https://api.github.com/users/ubtue/events{/privacy}","received_events_url":"https://api.github.com/users/ubtue/received_events","type":"Organization","site_admin":false},"repo":{"id":35827831,"name":"ub_tools","full_name":"ubtue/ub_tools","owner":{"login":"ubtue","id":12495698,"avatar_url":"https://avatars.githubusercontent.com/u/12495698?v=3","gravatar_id":"","url":"https://api.github.com/users/ubtue","html_url":"https://github.com/ubtue","followers_url":"https://api.github.com/users/ubtue/followers","following_url":"https://api.github.com/users/ubtue/following{/other_user}","gists_url":"https://api.github.com/users/ubtue/gists{/gist_id}","starred_url":"https://api.github.com/users/ubtue/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ubtue/subscriptions","organizations_url":"https://api.github.com/users/ubtue/orgs","repos_url":"https://api.github.com/users/ubtue/repos","events_url":"https://api.github.com/users/ubtue/events{/privacy}","received_events_url":"https://api.github.com/users/ubtue/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ubtue/ub_tools","description":"Various C++ utility programs typically relating to MARC 21 manipulation.","fork":false,"url":"https://api.github.com/repos/ubtue/ub_tools","forks_url":"https://api.github.com/repos/ubtue/ub_tools/forks","keys_url":"https://api.github.com/repos/ubtue/ub_tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ubtue/ub_tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ubtue/ub_tools/teams","hooks_url":"https://api.github.com/repos/ubtue/ub_tools/hooks","issue_events_url":"https://api.github.com/repos/ubtue/ub_tools/issues/events{/number}","events_url":"https://api.github.com/repos/ubtue/ub_tools/events","assignees_url":"https://api.github.com/repos/ubtue/ub_tools/assignees{/user}","branches_url":"https://api.github.com/repos/ubtue/ub_tools/branches{/branch}","tags_url":"https://api.github.com/repos/ubtue/ub_tools/tags","blobs_url":"https://api.github.com/repos/ubtue/ub_tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ubtue/ub_tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ubtue/ub_tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/ubtue/ub_tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ubtue/ub_tools/statuses/{sha}","languages_url":"https://api.github.com/repos/ubtue/ub_tools/languages","stargazers_url":"https://api.github.com/repos/ubtue/ub_tools/stargazers","contributors_url":"https://api.github.com/repos/ubtue/ub_tools/contributors","subscribers_url":"https://api.github.com/repos/ubtue/ub_tools/subscribers","subscription_url":"https://api.github.com/repos/ubtue/ub_tools/subscription","commits_url":"https://api.github.com/repos/ubtue/ub_tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/ubtue/ub_tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/ubtue/ub_tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/ubtue/ub_tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/ubtue/ub_tools/contents/{+path}","compare_url":"https://api.github.com/repos/ubtue/ub_tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ubtue/ub_tools/merges","archive_url":"https://api.github.com/repos/ubtue/ub_tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ubtue/ub_tools/downloads","issues_url":"https://api.github.com/repos/ubtue/ub_tools/issues{/number}","pulls_url":"https://api.github.com/repos/ubtue/ub_tools/pulls{/number}","milestones_url":"https://api.github.com/repos/ubtue/ub_tools/milestones{/number}","notifications_url":"https://api.github.com/repos/ubtue/ub_tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ubtue/ub_tools/labels{/name}","releases_url":"https://api.github.com/repos/ubtue/ub_tools/releases{/id}","deployments_url":"https://api.github.com/repos/ubtue/ub_tools/deployments","created_at":"2015-05-18T16:02:47Z","updated_at":"2016-01-11T08:51:29Z","pushed_at":"2016-03-07T10:53:39Z","git_url":"git://github.com/ubtue/ub_tools.git","ssh_url":"git@github.com:ubtue/ub_tools.git","clone_url":"https://github.com/ubtue/ub_tools.git","svn_url":"https://github.com/ubtue/ub_tools","homepage":null,"size":14730,"stargazers_count":2,"watchers_count":2,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":2,"default_branch":"master"}},"base":{"label":"ubtue:master","ref":"master","sha":"95f6c62d8f5230e64331e26ca0c4d0c5ded45386","user":{"login":"ubtue","id":12495698,"avatar_url":"https://avatars.githubusercontent.com/u/12495698?v=3","gravatar_id":"","url":"https://api.github.com/users/ubtue","html_url":"https://github.com/ubtue","followers_url":"https://api.github.com/users/ubtue/followers","following_url":"https://api.github.com/users/ubtue/following{/other_user}","gists_url":"https://api.github.com/users/ubtue/gists{/gist_id}","starred_url":"https://api.github.com/users/ubtue/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ubtue/subscriptions","organizations_url":"https://api.github.com/users/ubtue/orgs","repos_url":"https://api.github.com/users/ubtue/repos","events_url":"https://api.github.com/users/ubtue/events{/privacy}","received_events_url":"https://api.github.com/users/ubtue/received_events","type":"Organization","site_admin":false},"repo":{"id":35827831,"name":"ub_tools","full_name":"ubtue/ub_tools","owner":{"login":"ubtue","id":12495698,"avatar_url":"https://avatars.githubusercontent.com/u/12495698?v=3","gravatar_id":"","url":"https://api.github.com/users/ubtue","html_url":"https://github.com/ubtue","followers_url":"https://api.github.com/users/ubtue/followers","following_url":"https://api.github.com/users/ubtue/following{/other_user}","gists_url":"https://api.github.com/users/ubtue/gists{/gist_id}","starred_url":"https://api.github.com/users/ubtue/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ubtue/subscriptions","organizations_url":"https://api.github.com/users/ubtue/orgs","repos_url":"https://api.github.com/users/ubtue/repos","events_url":"https://api.github.com/users/ubtue/events{/privacy}","received_events_url":"https://api.github.com/users/ubtue/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ubtue/ub_tools","description":"Various C++ utility programs typically relating to MARC 21 manipulation.","fork":false,"url":"https://api.github.com/repos/ubtue/ub_tools","forks_url":"https://api.github.com/repos/ubtue/ub_tools/forks","keys_url":"https://api.github.com/repos/ubtue/ub_tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ubtue/ub_tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ubtue/ub_tools/teams","hooks_url":"https://api.github.com/repos/ubtue/ub_tools/hooks","issue_events_url":"https://api.github.com/repos/ubtue/ub_tools/issues/events{/number}","events_url":"https://api.github.com/repos/ubtue/ub_tools/events","assignees_url":"https://api.github.com/repos/ubtue/ub_tools/assignees{/user}","branches_url":"https://api.github.com/repos/ubtue/ub_tools/branches{/branch}","tags_url":"https://api.github.com/repos/ubtue/ub_tools/tags","blobs_url":"https://api.github.com/repos/ubtue/ub_tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ubtue/ub_tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ubtue/ub_tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/ubtue/ub_tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ubtue/ub_tools/statuses/{sha}","languages_url":"https://api.github.com/repos/ubtue/ub_tools/languages","stargazers_url":"https://api.github.com/repos/ubtue/ub_tools/stargazers","contributors_url":"https://api.github.com/repos/ubtue/ub_tools/contributors","subscribers_url":"https://api.github.com/repos/ubtue/ub_tools/subscribers","subscription_url":"https://api.github.com/repos/ubtue/ub_tools/subscription","commits_url":"https://api.github.com/repos/ubtue/ub_tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/ubtue/ub_tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/ubtue/ub_tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/ubtue/ub_tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/ubtue/ub_tools/contents/{+path}","compare_url":"https://api.github.com/repos/ubtue/ub_tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ubtue/ub_tools/merges","archive_url":"https://api.github.com/repos/ubtue/ub_tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ubtue/ub_tools/downloads","issues_url":"https://api.github.com/repos/ubtue/ub_tools/issues{/number}","pulls_url":"https://api.github.com/repos/ubtue/ub_tools/pulls{/number}","milestones_url":"https://api.github.com/repos/ubtue/ub_tools/milestones{/number}","notifications_url":"https://api.github.com/repos/ubtue/ub_tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ubtue/ub_tools/labels{/name}","releases_url":"https://api.github.com/repos/ubtue/ub_tools/releases{/id}","deployments_url":"https://api.github.com/repos/ubtue/ub_tools/deployments","created_at":"2015-05-18T16:02:47Z","updated_at":"2016-01-11T08:51:29Z","pushed_at":"2016-03-07T10:53:39Z","git_url":"git://github.com/ubtue/ub_tools.git","ssh_url":"git@github.com:ubtue/ub_tools.git","clone_url":"https://github.com/ubtue/ub_tools.git","svn_url":"https://github.com/ubtue/ub_tools","homepage":null,"size":14730,"stargazers_count":2,"watchers_count":2,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ubtue/ub_tools/pulls/313"},"html":{"href":"https://github.com/ubtue/ub_tools/pull/313"},"issue":{"href":"https://api.github.com/repos/ubtue/ub_tools/issues/313"},"comments":{"href":"https://api.github.com/repos/ubtue/ub_tools/issues/313/comments"},"review_comments":{"href":"https://api.github.com/repos/ubtue/ub_tools/pulls/313/comments"},"review_comment":{"href":"https://api.github.com/repos/ubtue/ub_tools/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ubtue/ub_tools/pulls/313/commits"},"statuses":{"href":"https://api.github.com/repos/ubtue/ub_tools/statuses/6f051d8f5d1048d52ccdd3910436acf50934d948"}}}}