{"id":21328446,"url":"https://github.com/mrcook/pgrdf","last_synced_at":"2025-10-11T08:42:33.659Z","repository":{"id":67278566,"uuid":"358979315","full_name":"mrcook/pgrdf","owner":"mrcook","description":"Library (golang) for reading/writing Project Gutenberg RDF XML catalog metadata","archived":false,"fork":false,"pushed_at":"2023-11-03T21:37:08.000Z","size":217,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-16T00:17:10.199Z","etag":null,"topics":["gutenberg-ebooks","gutenberg-metadata","project-gutenberg","rdf","xml"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrcook.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-17T20:48:30.000Z","updated_at":"2024-08-16T08:50:20.000Z","dependencies_parsed_at":"2024-06-20T09:26:44.492Z","dependency_job_id":"d3c572fa-b68a-4f20-82ef-6f33d4c5f742","html_url":"https://github.com/mrcook/pgrdf","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/mrcook/pgrdf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrcook%2Fpgrdf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrcook%2Fpgrdf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrcook%2Fpgrdf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrcook%2Fpgrdf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrcook","download_url":"https://codeload.github.com/mrcook/pgrdf/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrcook%2Fpgrdf/sbom","scorecard":{"id":663691,"data":{"date":"2025-08-11","repo":{"name":"github.com/mrcook/pgrdf","commit":"1a835ead7c4bb319902366e5f7dccb6c5b5e4607"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T17:07:45.437Z","repository_id":67278566,"created_at":"2025-08-21T17:07:45.437Z","updated_at":"2025-08-21T17:07:45.437Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279006638,"owners_count":26084149,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gutenberg-ebooks","gutenberg-metadata","project-gutenberg","rdf","xml"],"created_at":"2024-11-21T21:29:00.491Z","updated_at":"2025-10-11T08:42:33.621Z","avatar_url":"https://github.com/mrcook.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pgrdf - a Project Gutenberg RDF library\n\nA library written in the Go language for reading and writing Project Gutenberg\nRDF documents using a simpler set of intermediary data types, which can also be\nmarshaled to JSON for a more compact representation of the metadata.\n\nHelper functions are provided for reading RDF files directly from their `tar`\narchive. See the usage section below for more information.\n\nThe `Ebook` struct is used as an intermediary representation of the metadata,\nwhich provides a much easier set of data types than needing to handle RDF\ndirectly, and can also be marshaled to JSON.\n\nThe following is a (truncated) JSON example:\n\n```json\n{\n  \"id\": 1400,\n  \"released\": \"1998-07-01\",\n  \"titles\": [\"Great Expectations\"],\n  \"creators\": [{\n    \"id\": 37,\n    \"name\": \"Dickens, Charles\",\n    \"aliases\": [\n      \"Dickens, Charles John Huffam\",\n      \"Boz\"\n    ],\n    \"born_year\": 1812,\n    \"died_year\": 1870,\n    \"webpages\": [\"https://en.wikipedia.org/wiki/Charles_Dickens\"]\n  }]\n}\n```\n\nAnd here's the corresponding RDF snippet for [Great Expectations](https://gutenberg.org/ebooks/1400.rdf):\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003crdf:RDF xml:base=\"http://www.gutenberg.org/\"\n         xmlns:dcam=\"http://purl.org/dc/dcam/\"\n         xmlns:dcterms=\"http://purl.org/dc/terms/\"\n         xmlns:pgterms=\"http://www.gutenberg.org/2009/pgterms/\"\n         xmlns:cc=\"http://web.resource.org/cc/\"\n         xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n         xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\"\u003e\n    \u003cpgterms:ebook rdf:about=\"ebooks/1400\"\u003e\n        \u003cdcterms:title\u003eGreat Expectations\u003c/dcterms:title\u003e\n        \u003cdcterms:creator\u003e\n            \u003cpgterms:agent rdf:about=\"2009/agents/37\"\u003e\n                \u003cpgterms:name\u003eDickens, Charles\u003c/pgterms:name\u003e\n                \u003cpgterms:alias\u003eDickens, Charles John Huffam\u003c/pgterms:alias\u003e\n                \u003cpgterms:alias\u003eBoz\u003c/pgterms:alias\u003e\n                \u003cpgterms:webpage rdf:resource=\"https://en.wikipedia.org/wiki/Charles_Dickens\"/\u003e\n                \u003cpgterms:birthdate rdf:datatype=\"http://www.w3.org/2001/XMLSchema#integer\"\u003e1812\u003c/pgterms:birthdate\u003e\n                \u003cpgterms:deathdate rdf:datatype=\"http://www.w3.org/2001/XMLSchema#integer\"\u003e1870\u003c/pgterms:deathdate\u003e\n            \u003c/pgterms:agent\u003e\n        \u003c/dcterms:creator\u003e\n        \u003cdcterms:issued rdf:datatype=\"http://www.w3.org/2001/XMLSchema#date\"\u003e1998-07-01\u003c/dcterms:issued\u003e\n        \u003c!-- ... --\u003e\n    \u003c/pgterms:ebook\u003e\n\u003c/rdf:RDF\u003e\n```\n\n\n## Usage\n\nA basic example might be:\n\n```go\npackage main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/mrcook/pgrdf\"\n)\n\nfunc main() {\n\trdfFile, _ := os.Open(\"/path/to/pg1400.rdf\")\n\tebook, _ := pgrdf.ReadRDF(rdfFile)\n\n\tebook.Titles = append(ebook.Titles, \"In Three Volumes\")\n\n\tw := bytes.NewBuffer([]byte{}) // create an io.Writer\n\t_ = ebook.WriteRDF(w)          // write the RDF data\n\n\tdata, _ := json.Marshal(ebook) // marshal to JSON\n\tfmt.Println(string(data))\n}\n```\n\nIt is possible to read an RDF directly from the official Project Gutenberg\noffline catalog archive: http://www.gutenberg.org/cache/epub/feeds/.\n\nThere are currently two archives available:\n\n    rdf-files.tar.bz2\n    rdf-files.tar.zip\n\nReading from a `bz2` is considerably slower than just the plain `tar` archive,\nso it is recommended to first extract the tarball from the `bz2` archive.\nExample on Linux:\n\n    $ bzip2 -dk rdf-files.tar.bz2\n\nIf this is not possible/desirable then the `.tar.bz2` must first be wrapped in a\n`bzip2` reader:\n\n    rdf, err := archive.FromTarArchive(bzip2.NewReader(archiveFile), id)\n\nWhen an archive is fully extracted to a local directory, the `FromDirectory`\nfunction can be used:\n\n    rdf, err := archive.FromDirectory(\"/rdf_files_dir\", 1400)\n\nIt is important to note that the directory structure must be exactly as\nextracted from the archive:\n\n    rdf_files_dir/\n    ├─ cache/\n    │  └─ epub/\n    │     ├─ 1/\n    │     │  └─ pg1.rdf\n    │     ├─ 2/\n    │     ...\n\n\n## LICENSE\n\nCopyright (c) 2018-2023 Michael R. Cook. All rights reserved.\n\nThis work is licensed under the terms of the MIT license.\nFor a copy, see \u003chttps://opensource.org/licenses/MIT\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrcook%2Fpgrdf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrcook%2Fpgrdf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrcook%2Fpgrdf/lists"}