├── LICENSE ├── README.md ├── book_func.go ├── book_func_test.go ├── book_struct.go ├── openbd.go ├── openbd_test.go └── test ├── book_json.go ├── books_json.go ├── isbns.go └── pubdate_json.go /LICENSE: -------------------------------------------------------------------------------- 1 | the MIT License 2 | 3 | Copyright (c) 2017 seihmd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 17 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 20 | THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # openbd 2 | 3 | -- 4 | 5 | import "github.com/seihmd/openbd" 6 | 7 | Package openbd is API wrapper library for openBD: (openbd.jp)[https://openbd.jp/] 8 | 9 | ## Usage 10 | 11 | ```go 12 | o := openbd.New() 13 | 14 | // 一冊の情報を取得 15 | book, err := o.Get("477418392X") 16 | if err != nil { 17 | ... 18 | } 19 | book.GetISBN() // 477418392X 20 | 21 | // 複数冊の情報を取得 1000冊まで可 22 | isbns := []string{"9780061234002", "9780071123419"} 23 | books, err := o.GetBooks(isbns) 24 | if err != nil { 25 | ... 26 | } 27 | for _, book := range *books { 28 | if !book.IsValidData() { 29 | // fail to get data 30 | } 31 | } 32 | ``` 33 | 34 | #### type OpenBD 35 | 36 | ```go 37 | type OpenBD struct { 38 | Client *http.Client 39 | } 40 | ``` 41 | 42 | OpenBD has api request funcs 43 | 44 | #### func New 45 | 46 | ```go 47 | func New() OpenBD 48 | ``` 49 | New returns OpenBD 50 | 51 | #### func (*OpenBD) Get 52 | 53 | ```go 54 | func (o *OpenBD) Get(isbn string) (*Book, error) 55 | ``` 56 | Get requests single Book data 57 | 58 | #### func (*OpenBD) GetBooks 59 | 60 | ```go 61 | func (o *OpenBD) GetBooks(isbns []string) (*[]Book, error) 62 | ``` 63 | GetBooks requests multiple Book data 64 | 65 | 66 | #### type Book 67 | 68 | ```go 69 | type Book struct { 70 | Onix `json:"onix"` // JPRO-onix準拠項目 71 | Hanmoto `json:"hanmoto"` // 版元ドットコム独自項目 72 | Summary `json:"summary"` // 基本事項 73 | } 74 | ``` 75 | 76 | Book :struct to map whole response 77 | 78 | #### func (*Book) GetAuthor 79 | 80 | ```go 81 | func (b *Book) GetAuthor() string 82 | ``` 83 | GetAuthor returns Author 84 | 85 | #### func (*Book) GetCover 86 | 87 | ```go 88 | func (b *Book) GetCover() string 89 | ``` 90 | GetCover returns Cover 91 | 92 | #### func (*Book) GetDescription 93 | 94 | ```go 95 | func (b *Book) GetDescription() string 96 | ``` 97 | GetDescription returns Description 98 | 99 | #### func (*Book) GetISBN 100 | 101 | ```go 102 | func (b *Book) GetISBN() string 103 | ``` 104 | GetISBN returns ISBN 105 | 106 | #### func (*Book) GetImageLink 107 | 108 | ```go 109 | func (b *Book) GetImageLink() (l string) 110 | ``` 111 | GetImageLink returns ImageLink 112 | 113 | #### func (*Book) GetPages 114 | 115 | ```go 116 | func (b *Book) GetPages() (int, error) 117 | ``` 118 | GetPages returns Pages 119 | 120 | #### func (*Book) GetPubdate 121 | 122 | ```go 123 | func (b *Book) GetPubdate() (d time.Time, err error) 124 | ``` 125 | GetPubdate returns Pubdate 126 | 127 | #### func (*Book) GetPubdateStr 128 | 129 | ```go 130 | func (b *Book) GetPubdateStr() string 131 | ``` 132 | GetPubdateStr returns PubdateStr 133 | 134 | #### func (*Book) GetPublisher 135 | 136 | ```go 137 | func (b *Book) GetPublisher() string 138 | ``` 139 | GetPublisher returns Publisher 140 | 141 | #### func (*Book) GetSeries 142 | 143 | ```go 144 | func (b *Book) GetSeries() string 145 | ``` 146 | GetSeries returns Series 147 | 148 | #### func (*Book) GetTableOfContents 149 | 150 | ```go 151 | func (b *Book) GetTableOfContents() string 152 | ``` 153 | GetTableOfContents returns TableOfContents 154 | 155 | #### func (*Book) GetTitle 156 | 157 | ```go 158 | func (b *Book) GetTitle() string 159 | ``` 160 | GetTitle returns Title 161 | 162 | #### func (*Book) GetVolume 163 | 164 | ```go 165 | func (b *Book) GetVolume() string 166 | ``` 167 | GetVolume returns Volume 168 | 169 | #### func (*Book) IsValidData 170 | 171 | ```go 172 | func (b *Book) IsValidData() bool 173 | ``` 174 | IsValidData validates book has valid data 175 | 176 | #### type Hanmoto 177 | 178 | ```go 179 | type Hanmoto struct { 180 | Dateshuppan string // 出版年月日 181 | Datemodified string // 情報更新日時 182 | Datecreated string // 情報作成日時 183 | Lanove bool // ライトノベルフラグ 184 | Hasshohyo string // 書評データありフラグ 185 | Hastameshiyomi bool // ためしよみありフラグ 186 | Reviews []struct { 187 | Han string // 版数 188 | Appearance string // 掲載日 189 | PostUser string `json:"post_user"` // 入力者 190 | KubunID int `json:"kubun_id"` // 掲載元区分ID 191 | Source string // 掲載元 192 | Choyukan string // 朝刊/夕刊 193 | SourceID int `json:"source_id"` // 掲載元ID 194 | Reviewer string // 書評者 195 | Link string // リンク 196 | } 197 | // 版元ドットコム会員社独自項目 -> 198 | Genshomei string // 原書名 199 | Han string // 版"` // 新版、改訂などの版次(エディショ 200 | Datejuuhanyotei string // 重版予定日 201 | Datezeppan string // 絶版日 202 | Toji string // 製本"` // 上製="上製",並製="並 203 | Zaiko int // 在庫"` // 在庫あり=11/在庫僅少=21/重版中=/品切れ・重版未定=33/絶版=34 204 | Maegakinado string // まえがきなど 205 | Hanmotokarahitokoto string // 版元からひとこと 206 | Kaisetsu105W string // 内容紹介TRC(105字) 207 | Kanrensho string // 関連書 208 | KanrenLink string // 関連リンク htmlで記入 209 | Tsuiki string // サイト追記 210 | Genrecodetrc int // ジャンルコード 211 | Genrecodetrcjidou string // ジャンルコード(TRC児童書) 212 | Rubynoumu string // ルビの有無 213 | Ndccode string // NDCコード 214 | Kankoukeitai string // 刊行形態 215 | Sonotatokkijikou string // その他特記事項 216 | Jushoujouhou string // 受賞情報 217 | Furoku string // 付録 218 | Furokusonota string // 付録その他 219 | Dokushakakikomi string // 読者書き込み 220 | Dokushakakikomipagesuu int // 読者書き込みページ数 221 | Fuzokushiryounokangaikashidashi int // 付属資料館外貸出 可=1,不可=2,館内のみ=3 222 | Obinaiyou string // 帯内容 223 | Ruishokyougousho string // 類書・競合書 224 | Bessoushiryou string // 別送資料 225 | Zasshicode string // 雑誌コード 226 | Bikoujpo string // 備考(JPO) 227 | Bikoutrc string // 備考(TRC) 228 | Kanrenshoisbn string // 関連書ISBN 229 | Author []struct { 230 | Dokujikubun string // 独自著者区分 231 | Listseq int // リスト順 232 | } 233 | Jyuhan []struct { 234 | Date string // 重版日 235 | Ctime string // レコード作成日時 236 | Suri int // 刷り数 237 | Comment string // 重版コメント 238 | } 239 | } 240 | ``` 241 | 242 | Hanmoto :版元ドットコム独自項目 243 | 244 | #### type Onix 245 | 246 | ```go 247 | type Onix struct { 248 | RecordReference string // ISBNコード 249 | ProductIdentifier struct { 250 | IDValue string // ISBNコード 251 | ProductIDType string // ISBNコード 252 | } 253 | DescriptiveDetail struct { 254 | ProductComposition string // セット商品分売可否 255 | ProductFormDetail string // 判型 256 | Measure []struct { 257 | MeasureType string 258 | MeasureUnitCode string 259 | Measurement string 260 | } 261 | ProductPart []struct { 262 | NumberOfItemsOfThisForm json.Number 263 | ProductForm string 264 | ProductFormDescription string 265 | } 266 | Collection struct { 267 | TitleDetail struct { 268 | TitleType string 269 | TitleElement []struct { 270 | TitleElementLevel string 271 | TitleText struct { 272 | Content string `json:"content"` 273 | CollationKey string `json:"collationkey"` 274 | } 275 | } 276 | } 277 | CollectionType string 278 | } 279 | TitleDetail struct { 280 | TitleType string 281 | TitleElement struct { 282 | TitleElementLevel string 283 | TitleText struct { 284 | Content string 285 | Collationkey string 286 | } 287 | } 288 | } 289 | Contributor []struct { 290 | ContributorRole []string // 著者区分 291 | PersonName struct { 292 | Content string // 氏名 293 | Collationkey string // 照合キー 294 | } 295 | BiographicalNote string // 著者略歴 296 | SequenceNumber json.Number 297 | } 298 | Language []struct { 299 | LanguageCode string 300 | LanguageRole string 301 | CountryCode string 302 | } 303 | Extent []struct { 304 | ExtentValue json.Number 305 | ExtentUnit string 306 | ExtentType string 307 | } 308 | ProductForm string 309 | Subject []struct { 310 | SubjectSchemeIdentifier string 311 | SubjectCode string 312 | SubjectHeadingText string 313 | } 314 | Audience []struct { 315 | AudienceCodeType string 316 | AudienceCodeValue string 317 | } 318 | } 319 | Measure []struct { 320 | MeasureType string 321 | MeasureUnitCode string 322 | Measurement string 323 | } 324 | CollateralDetail struct { 325 | TextContent []struct { 326 | Text string 327 | TextType string 328 | ContentAudience string 329 | } 330 | SupportingResource []struct { 331 | ResourceContentType string // ISBNコード 332 | ResourceMode string 333 | ContentAudience string 334 | ResourceVersion []struct { 335 | ResourceLink string // 画像パス 336 | ResourceForm string 337 | ResourceVersionFeature []struct { 338 | ResourceVersionFeatureType string 339 | FeatureValue string 340 | } 341 | } 342 | } 343 | } 344 | PublishingDetail struct { 345 | Imprint struct { 346 | ImprintName string 347 | ImprintIdentifier []struct { 348 | IDValue string 349 | ImprintIDType string 350 | } 351 | } 352 | Publisher struct { 353 | PublisherIdentifier []struct { 354 | PublisherIDType string 355 | IDValue string 356 | } 357 | PublisherName string 358 | PublishingRole string 359 | } 360 | PublishingDate []struct { 361 | Date string 362 | PublishingDateRole string 363 | } 364 | } 365 | NotificationType string 366 | ProductSupply struct { 367 | SupplyDetail struct { 368 | ReturnsConditions struct { 369 | ReturnsCode string 370 | ReturnsCodeType string 371 | } 372 | ProductAvailability string 373 | Price []struct { 374 | PriceAmount json.Number 375 | CurrencyCode string 376 | PriceType string 377 | } 378 | } 379 | } 380 | } 381 | ``` 382 | 383 | Onix :JPRO-onix準拠項目 384 | 385 | #### type Summary 386 | 387 | ```go 388 | type Summary struct { 389 | Publisher string 390 | ISBN string 391 | Pubdate string 392 | Title string 393 | Series string 394 | Author string 395 | Cover string 396 | Volume string 397 | } 398 | ``` 399 | 400 | Summary :使いやすい基本事項 401 | -------------------------------------------------------------------------------- /book_func.go: -------------------------------------------------------------------------------- 1 | package openbd 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | "time" 7 | ) 8 | 9 | // IsValidData validates book has valid data 10 | func (b *Book) IsValidData() bool { 11 | return b.GetISBN() != "" 12 | } 13 | 14 | // GetPublisher returns Publisher 15 | func (b *Book) GetPublisher() string { 16 | return b.Summary.Publisher 17 | } 18 | 19 | // GetISBN returns ISBN 20 | func (b *Book) GetISBN() string { 21 | return b.Summary.ISBN 22 | } 23 | 24 | // GetPubdateStr returns PubdateStr 25 | func (b *Book) GetPubdateStr() string { 26 | return b.Summary.Pubdate 27 | } 28 | 29 | // GetPubdate returns Pubdate 30 | func (b *Book) GetPubdate() (d time.Time, err error) { 31 | p := b.Summary.Pubdate 32 | if p == "" { 33 | err = errors.New("no pubdate") 34 | return 35 | } 36 | layoutYMD := "20060102" 37 | layoutYM := "200601" 38 | if strings.Contains(p, "-") { 39 | layoutYMD = "2006-01-02" 40 | layoutYM = "2006-01" 41 | } 42 | d, err = time.Parse(layoutYMD, p) 43 | if err != nil { 44 | d, err = time.Parse(layoutYM, p) 45 | } 46 | return 47 | } 48 | 49 | // GetTitle returns Title 50 | func (b *Book) GetTitle() string { 51 | return b.Summary.Title 52 | } 53 | 54 | // GetSeries returns Series 55 | func (b *Book) GetSeries() string { 56 | return b.Summary.Series 57 | } 58 | 59 | // GetAuthor returns Author 60 | func (b *Book) GetAuthor() string { 61 | return b.Summary.Author 62 | } 63 | 64 | // GetCover returns Cover 65 | func (b *Book) GetCover() string { 66 | return b.Summary.Cover 67 | } 68 | 69 | // GetVolume returns Volume 70 | func (b *Book) GetVolume() string { 71 | return b.Summary.Volume 72 | } 73 | 74 | // GetImageLink returns ImageLink 75 | func (b *Book) GetImageLink() (l string) { 76 | if b.Summary.Cover != "" { 77 | l = b.Summary.Cover 78 | return 79 | } 80 | srs := b.Onix.CollateralDetail.SupportingResource 81 | if len(srs) == 0 { 82 | return 83 | } 84 | for _, sr := range srs { 85 | if len(sr.ResourceVersion) > 0 { 86 | l = sr.ResourceVersion[0].ResourceLink 87 | break 88 | } 89 | } 90 | return 91 | } 92 | 93 | // GetDescription returns Description 94 | func (b *Book) GetDescription() string { 95 | tcs := b.Onix.CollateralDetail.TextContent 96 | d := "" 97 | for _, tc := range tcs { 98 | if tc.TextType == textTypeBrief && d == "" { 99 | d = tc.Text 100 | } 101 | if tc.TextType == textTypeDescription { 102 | d = tc.Text 103 | } 104 | } 105 | return d 106 | } 107 | 108 | // GetTableOfContents returns TableOfContents 109 | func (b *Book) GetTableOfContents() string { 110 | tcs := b.Onix.CollateralDetail.TextContent 111 | toc := "" 112 | for _, tc := range tcs { 113 | if tc.TextType == textTypeToc { 114 | toc = tc.Text 115 | } 116 | } 117 | return toc 118 | } 119 | 120 | // GetPages returns Pages 121 | func (b *Book) GetPages() (int, error) { 122 | extents := b.Onix.DescriptiveDetail.Extent 123 | if len(extents) > 0 { 124 | pages, err := extents[0].ExtentValue.Int64() 125 | return int(pages), err 126 | } 127 | return 0, errors.New("no page data") 128 | } 129 | -------------------------------------------------------------------------------- /book_func_test.go: -------------------------------------------------------------------------------- 1 | package openbd 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | 8 | "github.com/seihmd/openbd/test" 9 | ) 10 | 11 | func TestGetter(t *testing.T) { 12 | b, err := mapToBook([]byte(test.BookResponse)) 13 | 14 | if err != nil { 15 | t.Fatal(err.Error()) 16 | } 17 | 18 | if !b.IsValidData() { 19 | t.Fatalf("failed: Book.IsValidData") 20 | } 21 | expectISBN := "9784774183923" 22 | if b.GetISBN() != expectISBN { 23 | t.Errorf(fmt.Sprintf("GetISBN expect:%s actual:%s", expectISBN, b.GetISBN())) 24 | } 25 | expectPublisher := "技術評論社" 26 | if b.GetPublisher() != expectPublisher { 27 | t.Errorf(fmt.Sprintf("GetPublisher expect:%s actual:%s", expectPublisher, b.GetPublisher())) 28 | } 29 | if b.GetPubdateStr() != "2016-10" { 30 | t.Errorf(fmt.Sprintf("GetISBN expect:2016-10 actual:%s", b.GetPubdateStr())) 31 | } 32 | actualPubdate, _ := time.Parse("2006-01", "2016-10") 33 | expectPubdate, _ := b.GetPubdate() 34 | if actualPubdate != expectPubdate { 35 | t.Errorf(fmt.Sprintf("GetISBN expect:%d actual:%d", expectPubdate, actualPubdate)) 36 | } 37 | 38 | expectTitle := "みんなのGo言語 : 現場で使える実践テクニック" 39 | if b.GetTitle() != expectTitle { 40 | t.Errorf(fmt.Sprintf("GetTitle expect:%s actual:%s", expectTitle, b.GetTitle())) 41 | } 42 | 43 | expectSeries := "dummy_series" 44 | if b.GetSeries() != expectSeries { 45 | t.Errorf(fmt.Sprintf("GetSeries expect:%s actual:%s", expectSeries, b.GetSeries())) 46 | } 47 | expectAuthor := "mattn/著 中島大一/著 牧大輔/著 藤原俊一郎/著 鈴木健太/著 松木雅幸/著" 48 | if b.GetAuthor() != expectAuthor { 49 | t.Errorf(fmt.Sprintf("GetAuthor expect:%s actual:%s", expectAuthor, b.GetAuthor())) 50 | 51 | } 52 | expectCover := "http://example.com/xxx.jpg" 53 | if b.GetCover() != expectCover { 54 | t.Errorf(fmt.Sprintf("GetCover expect:%s actual:%s", expectCover, b.GetCover())) 55 | } 56 | expectVolume := "dummy_volume" 57 | if b.GetVolume() != expectVolume { 58 | t.Errorf(fmt.Sprintf("GetVolume expect:%s actual:%s", expectVolume, b.GetVolume())) 59 | 60 | } 61 | 62 | expectImageLink := "http://example.com/xxx.jpg" 63 | if b.GetImageLink() != expectImageLink { 64 | t.Errorf(fmt.Sprintf("GetImageLink expect:%s actual:%s", expectImageLink, b.GetImageLink())) 65 | } 66 | 67 | expectDescription := "dummy_description" 68 | if b.GetDescription() != expectDescription { 69 | t.Errorf(fmt.Sprintf("GetDescription expect:%s actual:%s", expectDescription, b.GetDescription())) 70 | } 71 | 72 | expectTOC := "dummy_toc" 73 | if b.GetTableOfContents() != expectTOC { 74 | t.Errorf(fmt.Sprintf("GetTableOfContents expect:%s actual:%s", expectTOC, b.GetTableOfContents())) 75 | } 76 | 77 | expectPages := 143 78 | pages, err := b.GetPages() 79 | if err != nil { 80 | t.Errorf(err.Error()) 81 | } 82 | if pages != expectPages { 83 | t.Errorf(fmt.Sprintf("GetPages expect: %d actual: %d", expectPages, pages)) 84 | } 85 | } 86 | 87 | func TestPubdate(t *testing.T) { 88 | expect, _ := time.Parse("20060102", "20171001") 89 | 90 | jsons := []string{ 91 | test.PubdateYMDHyphen, 92 | test.PubdateYMHyphen, 93 | test.PubdateYMD, 94 | test.PubdateYM, 95 | } 96 | for _, j := range jsons { 97 | b, _ := mapToBook([]byte(j)) 98 | actual, _ := b.GetPubdate() 99 | if actual != expect { 100 | t.Errorf(fmt.Sprintf("expect:%s actual:%s", expect, actual)) 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /book_struct.go: -------------------------------------------------------------------------------- 1 | package openbd 2 | 3 | import "encoding/json" 4 | 5 | const tagName = "explain" 6 | 7 | const ( 8 | textTypeBrief = "02" 9 | textTypeDescription = "03" 10 | textTypeToc = "04" 11 | ) 12 | 13 | // Book :struct to map whole response 14 | type Book struct { 15 | Onix `json:"onix"` // JPRO-onix準拠項目 16 | Hanmoto `json:"hanmoto"` // 版元ドットコム独自項目 17 | Summary `json:"summary"` // 基本事項 18 | } 19 | 20 | // Onix :JPRO-onix準拠項目 21 | type Onix struct { 22 | RecordReference string // ISBNコード 23 | ProductIdentifier struct { 24 | IDValue string // ISBNコード 25 | ProductIDType string // ISBNコード 26 | } 27 | DescriptiveDetail struct { // シリーズ物等の情報 28 | ProductComposition string // セット商品分売可否 29 | ProductFormDetail string // 判型 30 | Measure []struct { // 判型(実寸) 31 | MeasureType string 32 | MeasureUnitCode string 33 | Measurement string 34 | } 35 | ProductPart []struct { // 付録情報 36 | NumberOfItemsOfThisForm json.Number 37 | ProductForm string 38 | ProductFormDescription string 39 | } 40 | Collection struct { 41 | TitleDetail struct { // シリーズ名/レーベル名 42 | TitleType string 43 | TitleElement []struct { 44 | TitleElementLevel string 45 | TitleText struct { 46 | Content string `json:"content"` 47 | CollationKey string `json:"collationkey"` 48 | } 49 | } 50 | } 51 | CollectionType string 52 | } 53 | TitleDetail struct { // 商品情報 54 | TitleType string 55 | TitleElement struct { 56 | TitleElementLevel string 57 | TitleText struct { 58 | Content string 59 | Collationkey string 60 | } 61 | } 62 | } 63 | Contributor []struct { // 著者情報 64 | ContributorRole []string // 著者区分 65 | PersonName struct { // 著者名 66 | Content string // 氏名 67 | Collationkey string // 照合キー 68 | } 69 | BiographicalNote string // 著者略歴 70 | SequenceNumber json.Number 71 | } 72 | Language []struct { // 言語 73 | LanguageCode string 74 | LanguageRole string 75 | CountryCode string 76 | } 77 | Extent []struct { // ページ数 78 | ExtentValue json.Number 79 | ExtentUnit string 80 | ExtentType string 81 | } 82 | ProductForm string 83 | Subject []struct { // Cコード/ジャンルコード/キーワード 84 | SubjectSchemeIdentifier string 85 | SubjectCode string 86 | SubjectHeadingText string 87 | } 88 | Audience []struct { // 読者対象/成人指定 89 | AudienceCodeType string 90 | AudienceCodeValue string 91 | } 92 | } 93 | Measure []struct { // 判型(実寸) 94 | MeasureType string 95 | MeasureUnitCode string 96 | Measurement string 97 | } 98 | CollateralDetail struct { // 商品付帯項目 99 | TextContent []struct { // 内容紹介/目次 100 | Text string 101 | TextType string 102 | ContentAudience string 103 | } 104 | SupportingResource []struct { // 画像 105 | ResourceContentType string // ISBNコード 106 | ResourceMode string 107 | ContentAudience string 108 | ResourceVersion []struct { 109 | ResourceLink string // 画像パス 110 | ResourceForm string 111 | ResourceVersionFeature []struct { 112 | ResourceVersionFeatureType string 113 | FeatureValue string 114 | } 115 | } 116 | } 117 | } 118 | PublishingDetail struct { // 出版社情報 119 | Imprint struct { // 発行元出版社 120 | ImprintName string 121 | ImprintIdentifier []struct { 122 | IDValue string 123 | ImprintIDType string 124 | } 125 | } 126 | Publisher struct { // 発売元出版社 127 | PublisherIdentifier []struct { 128 | PublisherIDType string 129 | IDValue string 130 | } 131 | PublisherName string 132 | PublishingRole string 133 | } 134 | PublishingDate []struct { // 発売予定日等 135 | Date string 136 | PublishingDateRole string 137 | } 138 | } 139 | NotificationType string 140 | ProductSupply struct { // 出版状況等 141 | SupplyDetail struct { 142 | ReturnsConditions struct { // 販売条件 143 | ReturnsCode string 144 | ReturnsCodeType string 145 | } 146 | ProductAvailability string 147 | Price []struct { // 価格情報 148 | PriceAmount json.Number 149 | CurrencyCode string 150 | PriceType string 151 | } 152 | } 153 | } 154 | } 155 | 156 | // Hanmoto :版元ドットコム独自項目 157 | type Hanmoto struct { 158 | Dateshuppan string // 出版年月日 159 | Datemodified string // 情報更新日時 160 | Datecreated string // 情報作成日時 161 | Lanove bool // ライトノベルフラグ 162 | Hasshohyo string // 書評データありフラグ 163 | Hastameshiyomi bool // ためしよみありフラグ 164 | Reviews []struct { // 書評情報 165 | Han string // 版数 166 | Appearance string // 掲載日 167 | PostUser string `json:"post_user"` // 入力者 168 | KubunID int `json:"kubun_id"` // 掲載元区分ID 169 | Source string // 掲載元 170 | Choyukan string // 朝刊/夕刊 171 | SourceID int `json:"source_id"` // 掲載元ID 172 | Reviewer string // 書評者 173 | Link string // リンク 174 | } 175 | // 版元ドットコム会員社独自項目 -> 176 | Genshomei string // 原書名 177 | Han string // 版"` // 新版、改訂などの版次(エディショ 178 | Datejuuhanyotei string // 重版予定日 179 | Datezeppan string // 絶版日 180 | Toji string // 製本"` // 上製="上製",並製="並 181 | Zaiko int // 在庫"` // 在庫あり=11/在庫僅少=21/重版中=/品切れ・重版未定=33/絶版=34 182 | Maegakinado string // まえがきなど 183 | Hanmotokarahitokoto string // 版元からひとこと 184 | Kaisetsu105W string // 内容紹介TRC(105字) 185 | Kanrensho string // 関連書 186 | KanrenLink string // 関連リンク htmlで記入 187 | Tsuiki string // サイト追記 188 | Genrecodetrc int // ジャンルコード 189 | Genrecodetrcjidou string // ジャンルコード(TRC児童書) 190 | Rubynoumu string // ルビの有無 191 | Ndccode string // NDCコード 192 | Kankoukeitai string // 刊行形態 193 | Sonotatokkijikou string // その他特記事項 194 | Jushoujouhou string // 受賞情報 195 | Furoku string // 付録 196 | Furokusonota string // 付録その他 197 | Dokushakakikomi string // 読者書き込み 198 | Dokushakakikomipagesuu int // 読者書き込みページ数 199 | Fuzokushiryounokangaikashidashi int // 付属資料館外貸出 可=1,不可=2,館内のみ=3 200 | Obinaiyou string // 帯内容 201 | Ruishokyougousho string // 類書・競合書 202 | Bessoushiryou string // 別送資料 203 | Zasshicode string // 雑誌コード 204 | Bikoujpo string // 備考(JPO) 205 | Bikoutrc string // 備考(TRC) 206 | Kanrenshoisbn string // 関連書ISBN 207 | Author []struct { // 独自著者情報 208 | Dokujikubun string // 独自著者区分 209 | Listseq int // リスト順 210 | } 211 | Jyuhan []struct { // 重版情報 212 | Date string // 重版日 213 | Ctime string // レコード作成日時 214 | Suri int // 刷り数 215 | Comment string // 重版コメント 216 | } 217 | // 版元ドットコム会員社独自項目 <- 218 | } 219 | 220 | // Summary :使いやすい基本事項 221 | type Summary struct { 222 | Publisher string 223 | ISBN string 224 | Pubdate string 225 | Title string 226 | Series string 227 | Author string 228 | Cover string 229 | Volume string 230 | } 231 | -------------------------------------------------------------------------------- /openbd.go: -------------------------------------------------------------------------------- 1 | // Package openbd is API wrapper library for openBD: https://openbd.jp/ 2 | package openbd 3 | 4 | import ( 5 | "encoding/json" 6 | "errors" 7 | "io/ioutil" 8 | "net/http" 9 | "strings" 10 | ) 11 | 12 | const ( 13 | getAPI = "https://api.openbd.jp/v1/get" 14 | postAPI = "https://api.openbd.jp/v1/post" 15 | coverageAPI = "https://api.openbd.jp/v1/coverage" 16 | ) 17 | 18 | const ( 19 | maxForGetRequest = 1000 20 | maxForPostRequest = 10000 21 | ) 22 | 23 | var ( 24 | errNoData = errors.New("ERROR: no data") 25 | errInvalidISBN = errors.New("ERROR: invalid isbn code") 26 | errRequest = errors.New("ERROR: request error") 27 | errOverGetMax = errors.New("ERROR: isbns over 1000") 28 | ) 29 | 30 | // OpenBD has api request funcs 31 | type OpenBD struct { 32 | Client *http.Client 33 | } 34 | 35 | // New returns OpenBD 36 | func New() OpenBD { 37 | return OpenBD{ 38 | Client: http.DefaultClient, 39 | } 40 | } 41 | 42 | // Get requests single Book data 43 | func (o *OpenBD) Get(isbn string) (*Book, error) { 44 | u := createGetURL(isbn) 45 | body, err := o.requestGet(u) 46 | if err != nil { 47 | return nil, errRequest 48 | } 49 | b, err := mapToBook(body) 50 | if err != nil { 51 | return nil, err 52 | } 53 | return b, nil 54 | } 55 | 56 | // GetBooks requests multiple Book data 57 | func (o *OpenBD) GetBooks(isbns []string) (*[]Book, error) { 58 | if len(isbns) > maxForGetRequest { 59 | return nil, errOverGetMax 60 | } 61 | u := createISBNsURL(isbns) 62 | body, err := o.requestGet(u) 63 | if err != nil { 64 | return nil, errRequest 65 | } 66 | b, err := mapToBooks(body) 67 | if err != nil { 68 | return nil, err 69 | } 70 | return b, nil 71 | } 72 | 73 | func (o *OpenBD) requestGet(url string) ([]byte, error) { 74 | resp, err := o.Client.Get(url) 75 | if err != nil { 76 | return nil, err 77 | } 78 | defer resp.Body.Close() 79 | return ioutil.ReadAll(resp.Body) 80 | } 81 | 82 | func createGetURL(isbn string) string { 83 | return getAPI + "?isbn=" + isbn 84 | } 85 | 86 | func createISBNsURL(isbns []string) string { 87 | return getAPI + "?isbn=" + strings.Join(isbns, ",") 88 | } 89 | 90 | func mapToBook(response []byte) (b *Book, err error) { 91 | var books []Book 92 | if err = json.Unmarshal(response, &books); err != nil { 93 | return 94 | } 95 | b = &books[0] 96 | if !b.IsValidData() { 97 | err = errNoData 98 | } 99 | return 100 | } 101 | 102 | func mapToBooks(response []byte) (*[]Book, error) { 103 | var b []Book 104 | err := json.Unmarshal(response, &b) 105 | return &b, err 106 | } 107 | -------------------------------------------------------------------------------- /openbd_test.go: -------------------------------------------------------------------------------- 1 | package openbd 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/seihmd/openbd/test" 7 | ) 8 | 9 | func TestMapToBooks(t *testing.T) { 10 | books, err := mapToBooks([]byte(test.BooksResponse)) 11 | if err != nil { 12 | t.Fatal(err.Error()) 13 | } 14 | l := len(*books) 15 | if l != 3 { 16 | t.Errorf("failed books mapping expect: 3, actual: %d", l) 17 | } 18 | 19 | isbn0 := (*books)[0].GetISBN() 20 | if isbn0 != "9784798142418" { 21 | t.Errorf("books[0] isbn expect: 9784798142418, actual: %s", isbn0) 22 | } 23 | 24 | isbn1 := (*books)[1].GetISBN() 25 | if isbn1 != "9784873117522" { 26 | t.Errorf("books[1] isbn expect: 9784873117522, actual: %s", isbn1) 27 | } 28 | 29 | isbn2 := (*books)[2].GetISBN() 30 | if isbn2 != "9784798031804" { 31 | t.Errorf("books[2] isbn expect: 9784798031804 , actual: %s", isbn2) 32 | } 33 | } 34 | 35 | func TestGetBooks(t *testing.T) { 36 | o := New() 37 | books, err := o.GetBooks(test.ISBNs) 38 | if err != nil { 39 | t.Errorf(err.Error()) 40 | } 41 | for _, b := range *books { 42 | execGetter(&b) 43 | } 44 | } 45 | 46 | func execGetter(b *Book) { 47 | b.GetPublisher() 48 | b.GetPubdateStr() 49 | b.GetPubdate() 50 | b.GetTitle() 51 | b.GetSeries() 52 | b.GetAuthor() 53 | b.GetCover() 54 | b.GetVolume() 55 | b.GetImageLink() 56 | b.GetDescription() 57 | b.GetTableOfContents() 58 | b.GetPages() 59 | } 60 | -------------------------------------------------------------------------------- /test/book_json.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | const BookResponse = `[ 4 | { 5 | "onix":{ 6 | "CollateralDetail":{ 7 | "SupportingResource":[ 8 | { 9 | "ResourceContentType":"01", 10 | "ResourceMode":"03", 11 | "ContentAudience":"01", 12 | "ResourceVersion":[ 13 | { 14 | "ResourceLink":"https://example.com/yyy.jpg", 15 | "ResourceForm":"02", 16 | "ResourceVersionFeature":[ 17 | { 18 | "ResourceVersionFeatureType":"01", 19 | "FeatureValue":"D502" 20 | }, 21 | { 22 | "ResourceVersionFeatureType":"04", 23 | "FeatureValue":"9784780802047.jpg" 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | ], 30 | "TextContent":[ 31 | { 32 | "Text":"dummy_brief_description", 33 | "TextType":"02", 34 | "ContentAudience":"00" 35 | }, 36 | { 37 | "Text":"dummy_description", 38 | "TextType":"03", 39 | "ContentAudience":"00" 40 | }, 41 | { 42 | "Text":"dummy_toc", 43 | "TextType":"04", 44 | "ContentAudience":"00" 45 | } 46 | ] 47 | }, 48 | "PublishingDetail":{ 49 | "Imprint":{ 50 | "ImprintName":"技術評論社", 51 | "ImprintIdentifier":[ 52 | { 53 | "IDValue":"7741", 54 | "ImprintIDType":"19" 55 | } 56 | ] 57 | }, 58 | "PublishingDate":[ 59 | { 60 | "Date":"", 61 | "PublishingDateRole":"01" 62 | } 63 | ] 64 | }, 65 | "ProductSupply":{ 66 | "SupplyDetail":{ 67 | "ReturnsConditions":{ 68 | "ReturnsCode":"02", 69 | "ReturnsCodeType":"04" 70 | }, 71 | "ProductAvailability":"99" 72 | } 73 | }, 74 | "NotificationType":"03", 75 | "ProductIdentifier":{ 76 | "IDValue":"9784774183923", 77 | "ProductIDType":"15" 78 | }, 79 | "RecordReference":"9784774183923", 80 | "DescriptiveDetail":{ 81 | "TitleDetail":{ 82 | "TitleType":"01", 83 | "TitleElement":{ 84 | "TitleElementLevel":"01", 85 | "TitleText":{ 86 | "content":"みんなのGo言語 : 現場で使える実践テクニック", 87 | "collationkey":"ミンナ ノ Goゲンゴ : ゲンバ デ ツカエル ジッセン テクニック" 88 | } 89 | } 90 | }, 91 | "Language":[ 92 | { 93 | "LanguageCode":"jpn", 94 | "LanguageRole":"01", 95 | "CountryCode":"JP" 96 | } 97 | ], 98 | "ProductForm":"BZ", 99 | "Extent":[ 100 | { 101 | "ExtentValue":"143", 102 | "ExtentUnit":"03", 103 | "ExtentType":"11" 104 | } 105 | ], 106 | "Measure":[ 107 | { 108 | "MeasureType":"01", 109 | "MeasureUnitCode":"mm", 110 | "Measurement":"260" 111 | }, 112 | { 113 | "MeasureType":"02", 114 | "MeasureUnitCode":"mm", 115 | "Measurement":"0" 116 | } 117 | ], 118 | "Contributor":[ 119 | { 120 | "ContributorRole":[ 121 | "A01" 122 | ], 123 | "PersonName":{ 124 | "content":"mattn" 125 | }, 126 | "SequenceNumber":"1" 127 | }, 128 | { 129 | "ContributorRole":[ 130 | "A01" 131 | ], 132 | "PersonName":{ 133 | "content":"中島 大一" 134 | }, 135 | "SequenceNumber":"2" 136 | }, 137 | { 138 | "ContributorRole":[ 139 | "A01" 140 | ], 141 | "PersonName":{ 142 | "content":"牧 大輔" 143 | }, 144 | "SequenceNumber":"3" 145 | }, 146 | { 147 | "ContributorRole":[ 148 | "A01" 149 | ], 150 | "PersonName":{ 151 | "content":"藤原 俊一郎" 152 | }, 153 | "SequenceNumber":"4" 154 | }, 155 | { 156 | "ContributorRole":[ 157 | "A01" 158 | ], 159 | "PersonName":{ 160 | "content":"鈴木 健太" 161 | }, 162 | "SequenceNumber":"5" 163 | }, 164 | { 165 | "ContributorRole":[ 166 | "A01" 167 | ], 168 | "PersonName":{ 169 | "content":"松木 雅幸" 170 | }, 171 | "SequenceNumber":"6" 172 | } 173 | ], 174 | "ProductComposition":"00" 175 | } 176 | }, 177 | "hanmoto":{ 178 | "dateshuppan":"2016-10", 179 | "datemodified":"2016-09-27 21:06:21", 180 | "datecreated":"2016-09-27 21:06:21" 181 | }, 182 | "summary":{ 183 | "publisher":"技術評論社", 184 | "isbn":"9784774183923", 185 | "pubdate":"2016-10", 186 | "title":"みんなのGo言語 : 現場で使える実践テクニック", 187 | "series":"dummy_series", 188 | "author":"mattn/著 中島大一/著 牧大輔/著 藤原俊一郎/著 鈴木健太/著 松木雅幸/著", 189 | "cover":"http://example.com/xxx.jpg", 190 | "volume":"dummy_volume" 191 | } 192 | } 193 | ] 194 | ` 195 | -------------------------------------------------------------------------------- /test/books_json.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | // BooksResponse is response of https://api.openbd.jp/v1/get?isbn=4798142417,4873117526,4798031801&pretty 4 | const BooksResponse = ` 5 | [ 6 | { 7 | "onix":{ 8 | "CollateralDetail":{ 9 | "SupportingResource":[ 10 | { 11 | "ResourceContentType":"01", 12 | "ResourceMode":"03", 13 | "ContentAudience":"01", 14 | "ResourceVersion":[ 15 | { 16 | "ResourceLink":"https://cover.openbd.jp/9784798142418.jpg", 17 | "ResourceForm":"02", 18 | "ResourceVersionFeature":[ 19 | { 20 | "ResourceVersionFeatureType":"01", 21 | "FeatureValue":"D502" 22 | }, 23 | { 24 | "ResourceVersionFeatureType":"04", 25 | "FeatureValue":"9784798142418.jpg" 26 | } 27 | ] 28 | } 29 | ] 30 | } 31 | ], 32 | "TextContent":[ 33 | { 34 | "Text":"本書はGo言語の入門書です。Go言語の基本的な構文から、特徴的な機能、実際にプログラムを書いてみたい方に必要な知識を解説。", 35 | "TextType":"02", 36 | "ContentAudience":"00" 37 | }, 38 | { 39 | "Text":"Go 1.6に対応!\n構文や動作を「なぜ・どうして」から解説。\n読みやすさ、理解の深さを追求したGo入門書!\n\n本書は、Goプログラミングをこれから始める方のための学習書です。Go言語の基本的な構文から、特徴的な機能、開発ツールや使用頻度の高いパッケージの使い方まで、実際にプログラムを書いてみたい方に必要な知識を解説しています。\n\nGo言語の最新バージョン1.6に対応。データ型からチャネルとゴルーチンなどの特徴的な機能、各種パッケージまで、コード例をふんだんに使って「なぜそうなるのか」から説明していますので、C/C++、Java、C#、PythonやPHP、Rubyなど何かしらのプログラミング言語を学んだ方であれば「なるほど、なるほど」と腹落ちしながら読み進められます。\n\n使用頻度の高いパッケージの使い方は集中的に解説するほか、巻末には標準ライブラリのパッケージカタログ付き。座右において便利に使える一冊です。\n\n■Go言語とは\nGo言語(Golangとも呼ばれます)は、2009年に米Googleが公開したプログラミング言語です。構文は簡潔で可読性が高く、コンパイル言語ゆえの安全性とインタプリタ言語のような開発の軽快さを両立し、マルチコアや並行処理などに対応していることから、次世代のソフトウェア開発を支えるプログラミング言語の1つと期待されています。\n\n", 40 | "TextType":"03", 41 | "ContentAudience":"00" 42 | }, 43 | { 44 | "Text":"はじめに\n Goとは\n Goの特徴\n 本書の想定読者\n 本書の構成\n 対象とするGoのバージョン\n\nChapter 1:開発環境\n ~ Windows・OS X・LinuxへのGoのインストール\n 1.1 はじめに\n 1.2 公式ページ\n 1.3 Goのダウンロード\n 1.4 Windows環境への導入\n 1.5 OS X環境への導入\n 1.6 Linux環境への導入\n 1.7 SCMとの連携\n 1.8 開発環境について\n\nChapter 2:プログラムの構成と実行\n ~ Goプログラムの書き方とビルド・実行・パッケージ作成\n 2.1 はじめに\n 2.2 テキストエディターとエンコーディング\n 2.3 go run\n 2.4 プログラムのビルド\n 2.5 パッケージと構成\n\nChapter 3:言語の基本\n ~変数・型・演算子・関数・定数・スコープ・制御構文・ゴルーチン\n 3.1 コメント\n 3.2 文\n 3.3 定義済み識別子\n 3.4 コード例の表記について\n 3.5 fmtパッケージ\n 3.6 変数\n 3.7 基本型\n 3.8 配列型\n 3.9 interface{}とnil\n 3.10 演算子\n 3.11 関数\n 3.12 定数\n 3.13 スコープ\n 3.14 制御構文\n\nChapter 4:参照型\n ~スライス・マップ・チャネル\n 4.1 参照型とは\n 4.2 組み込み関数make\n 4.3 スライス\n 4.4 マップ\n 4.5 チャネル\n\nChapter 5:構造体とインターフェース\n ~ポインタ・構造体・メソッド・タグ・インターフェース\n 5.1 はじめに\n 5.2 ポインタ\n 5.3 構造体\n 5.4 インターフェース\n\nChapter 6:Goのツール\n ~さまざまなGoコマンド\n 6.1 Goのツール群について\n 6.2 goコマンド\n 6.3 go version\n 6.4 go env\n 6.5 go fmt\n 6.6 go doc\n 6.7 go build\n 6.8 go install\n 6.9 go get\n 6.10 go test\n 6.11 ベンダリング\n\nChapter 7:Goのパッケージ\n ~よく使われるパッケージとコーディング例\n 7.1 はじめに\n 7.2 os\n 7.3 time\n 7.4 math\n 7.5 math/rand\n 7.6 flag\n 7.7 fmt\n 7.8 log\n 7.9 strconv\n 7.10 unicode\n 7.11 strings\n 7.12 io\n 7.13 bufio\n 7.14 ioutil\n 7.15 regexp\n 7.16 json\n 7.17 net/url\n 7.18 net/http\n 7.19 sync\n 7.20 crypto/*\n\n巻末付録:Go標準ライブラリオーバービュー\n", 45 | "TextType":"04", 46 | "ContentAudience":"00" 47 | } 48 | ] 49 | }, 50 | "PublishingDetail":{ 51 | "Imprint":{ 52 | "ImprintName":"翔泳社", 53 | "ImprintIdentifier":[ 54 | { 55 | "IDValue":"7981", 56 | "ImprintIDType":"19" 57 | }, 58 | { 59 | "IDValue":"3602", 60 | "ImprintIDType":"24" 61 | } 62 | ] 63 | }, 64 | "Publisher":{ 65 | "PublisherIdentifier":[ 66 | { 67 | "PublisherIDType":"19", 68 | "IDValue":"7981" 69 | }, 70 | { 71 | "PublisherIDType":"24", 72 | "IDValue":"3602" 73 | } 74 | ], 75 | "PublisherName":"翔泳社", 76 | "PublishingRole":"01" 77 | }, 78 | "PublishingDate":[ 79 | { 80 | "Date":"20160414", 81 | "PublishingDateRole":"01" 82 | }, 83 | { 84 | "Date":"20160311", 85 | "PublishingDateRole":"09" 86 | }, 87 | { 88 | "Date":"20160322", 89 | "PublishingDateRole":"25" 90 | } 91 | ] 92 | }, 93 | "RecordReference":"9784798142418", 94 | "NotificationType":"03", 95 | "ProductIdentifier":{ 96 | "IDValue":"9784798142418", 97 | "ProductIDType":"15" 98 | }, 99 | "ProductSupply":{ 100 | "SupplyDetail":{ 101 | "ReturnsConditions":{ 102 | "ReturnsCode":"03", 103 | "ReturnsCodeType":"04" 104 | }, 105 | "ProductAvailability":"99", 106 | "Price":[ 107 | { 108 | "PriceAmount":"2980", 109 | "CurrencyCode":"JPY", 110 | "PriceType":"03" 111 | } 112 | ] 113 | } 114 | }, 115 | "DescriptiveDetail":{ 116 | "Language":[ 117 | { 118 | "LanguageCode":"jpn", 119 | "LanguageRole":"01" 120 | } 121 | ], 122 | "TitleDetail":{ 123 | "TitleType":"01", 124 | "TitleElement":{ 125 | "TitleElementLevel":"01", 126 | "TitleText":{ 127 | "content":"スターティングGo言語", 128 | "collationkey":"スターティングゴーゲンゴ" 129 | } 130 | } 131 | }, 132 | "ProductForm":"BA", 133 | "Collection":{ 134 | "CollectionType":"10", 135 | "TitleDetail":{ 136 | "TitleType":"01", 137 | "TitleElement":[ 138 | { 139 | "TitleElementLevel":"03", 140 | "TitleText":{ 141 | "content":"CodeZine BOOKS", 142 | "collationkey":"コードジンブックス" 143 | } 144 | } 145 | ] 146 | } 147 | }, 148 | "Audience":[ 149 | { 150 | "AudienceCodeType":"22", 151 | "AudienceCodeValue":"00" 152 | } 153 | ], 154 | "Extent":[ 155 | { 156 | "ExtentValue":"432", 157 | "ExtentUnit":"03", 158 | "ExtentType":"11" 159 | } 160 | ], 161 | "Contributor":[ 162 | { 163 | "ContributorRole":[ 164 | "A01" 165 | ], 166 | "PersonName":{ 167 | "content":"松尾 愛賀", 168 | "collationkey":"マツオ アイガ" 169 | }, 170 | "SequenceNumber":"1" 171 | } 172 | ], 173 | "ProductComposition":"00", 174 | "ProductFormDetail":"B108", 175 | "Subject":[ 176 | { 177 | "SubjectSchemeIdentifier":"78", 178 | "SubjectCode":"3055" 179 | }, 180 | { 181 | "SubjectSchemeIdentifier":"20", 182 | "SubjectHeadingText":"Go言語;Golang;Go Lang;Go;プログラミング言語Go;Goプログラミング;Go入門;並列;並行;ゴルーチン;Goパッケージ;標準ライブラリ;はじめてのGo;やさしいGo;たのしいGo;モダンプログラミング;プログラミング;入門;初心者" 183 | } 184 | ] 185 | } 186 | }, 187 | "hanmoto":{ 188 | "datemodified":"2016-03-17 10:02:12", 189 | "datecreated":"2016-03-12 16:02:11" 190 | }, 191 | "summary":{ 192 | "publisher":"翔泳社", 193 | "isbn":"9784798142418", 194 | "pubdate":"20160414", 195 | "title":"スターティングGo言語", 196 | "series":"CodeZine BOOKS", 197 | "author":"松尾愛賀/著", 198 | "cover":"https://cover.openbd.jp/9784798142418.jpg", 199 | "volume":"" 200 | } 201 | }, 202 | { 203 | "onix":{ 204 | "CollateralDetail":{ 205 | "TextContent":[ 206 | { 207 | "Text":"Goプログラミングによる開発手法および関連技術の使い方をマスターし、ツールやプログラムの開発スキルの向上が可能。", 208 | "TextType":"02", 209 | "ContentAudience":"00" 210 | }, 211 | { 212 | "Text":"Go言語の実践テクニックを身につけたいGoプログラミング経験者は必読!\nGoプログラミングについて一歩踏み込んだプロユースの解説書。読者はシンプルなコードを書きながら、実運用アプリケーションの開発で使うスキルとテクニックを学ぶことができます。本書のサンプルプログラムはどれもシンプルですがとても実践的です。拡張性、並行処理、高可用性といったエンタープライズアプリケーションの開発で直面する現実的な問題に対するソリューションが含まれています。本書を読めば、実際の業務に必要な技能――Goによる開発手法および関連技術の使い方――をマスターし、ツールやプログラムの開発スキルを迅速かつ簡単に向上できます。日本語版では、監訳者の鵜飼文敏氏による巻末付録「Goらしいコードの書き方」を収録しました。", 213 | "TextType":"03", 214 | "ContentAudience":"00" 215 | } 216 | ] 217 | }, 218 | "PublishingDetail":{ 219 | "Imprint":{ 220 | "ImprintName":"オライリー・ジャパン", 221 | "ImprintIdentifier":[ 222 | { 223 | "IDValue":"87311", 224 | "ImprintIDType":"19" 225 | }, 226 | { 227 | "IDValue":"0742", 228 | "ImprintIDType":"24" 229 | } 230 | ] 231 | }, 232 | "Publisher":{ 233 | "PublisherIdentifier":[ 234 | { 235 | "PublisherIDType":"19", 236 | "IDValue":"274" 237 | }, 238 | { 239 | "PublisherIDType":"24", 240 | "IDValue":"0742" 241 | } 242 | ], 243 | "PublisherName":"株式会社オーム社", 244 | "PublishingRole":"01" 245 | }, 246 | "PublishingDate":[ 247 | { 248 | "Date":"20160121", 249 | "PublishingDateRole":"01" 250 | } 251 | ] 252 | }, 253 | "RecordReference":"9784873117522", 254 | "NotificationType":"03", 255 | "ProductIdentifier":{ 256 | "IDValue":"9784873117522", 257 | "ProductIDType":"15" 258 | }, 259 | "ProductSupply":{ 260 | "SupplyDetail":{ 261 | "ReturnsConditions":{ 262 | "ReturnsCode":"03", 263 | "ReturnsCodeType":"04" 264 | }, 265 | "ProductAvailability":"99", 266 | "Price":[ 267 | { 268 | "PriceAmount":"3200", 269 | "CurrencyCode":"JPY", 270 | "PriceType":"03" 271 | } 272 | ] 273 | } 274 | }, 275 | "DescriptiveDetail":{ 276 | "TitleDetail":{ 277 | "TitleType":"01", 278 | "TitleElement":{ 279 | "TitleElementLevel":"01", 280 | "TitleText":{ 281 | "content":"Go言語によるWebアプリケーション開発", 282 | "collationkey":"ゴーゲンゴニヨル ウェブアプリケーションカイハツ" 283 | } 284 | } 285 | }, 286 | "Language":[ 287 | { 288 | "LanguageCode":"jpn", 289 | "LanguageRole":"01", 290 | "CountryCode":"JP" 291 | } 292 | ], 293 | "ProductForm":"BA", 294 | "Audience":[ 295 | { 296 | "AudienceCodeType":"22", 297 | "AudienceCodeValue":"00" 298 | } 299 | ], 300 | "Extent":[ 301 | { 302 | "ExtentValue":"280", 303 | "ExtentUnit":"03", 304 | "ExtentType":"11" 305 | } 306 | ], 307 | "Contributor":[ 308 | { 309 | "ContributorRole":[ 310 | "A01" 311 | ], 312 | "PersonName":{ 313 | "content":"Mat Ryer", 314 | "collationkey":"マット ライヤー" 315 | }, 316 | "SequenceNumber":"1" 317 | }, 318 | { 319 | "ContributorRole":[ 320 | "B20" 321 | ], 322 | "PersonName":{ 323 | "content":"鵜飼 文敏", 324 | "collationkey":"ウカイ フミトシ" 325 | }, 326 | "SequenceNumber":"2" 327 | }, 328 | { 329 | "ContributorRole":[ 330 | "B06" 331 | ], 332 | "PersonName":{ 333 | "content":"牧野 聡", 334 | "collationkey":"マキノ サトシ" 335 | }, 336 | "SequenceNumber":"3" 337 | } 338 | ], 339 | "ProductComposition":"00", 340 | "ProductFormDetail":"B124", 341 | "Subject":[ 342 | { 343 | "SubjectSchemeIdentifier":"78", 344 | "SubjectCode":"3055" 345 | }, 346 | { 347 | "SubjectSchemeIdentifier":"79", 348 | "SubjectCode":"20" 349 | } 350 | ] 351 | } 352 | }, 353 | "hanmoto":{ 354 | "datemodified":"2016-01-06 16:04:16", 355 | "datecreated":"2015-12-24 16:04:45" 356 | }, 357 | "summary":{ 358 | "publisher":"オライリー・ジャパン", 359 | "isbn":"9784873117522", 360 | "pubdate":"20160121", 361 | "title":"Go言語によるWebアプリケーション開発", 362 | "series":"", 363 | "author":"MatRyer/著 鵜飼文敏/監修 牧野聡/翻訳", 364 | "cover":"", 365 | "volume":"" 366 | } 367 | }, 368 | { 369 | "onix":{ 370 | "CollateralDetail":{ 371 | "SupportingResource":[ 372 | { 373 | "ResourceContentType":"01", 374 | "ResourceMode":"03", 375 | "ContentAudience":"01", 376 | "ResourceVersion":[ 377 | { 378 | "ResourceLink":"https://cover.openbd.jp/9784798031804.jpg", 379 | "ResourceForm":"02", 380 | "ResourceVersionFeature":[ 381 | { 382 | "ResourceVersionFeatureType":"01", 383 | "FeatureValue":"D502" 384 | }, 385 | { 386 | "ResourceVersionFeatureType":"04", 387 | "FeatureValue":"9784798031804.jpg" 388 | } 389 | ] 390 | } 391 | ] 392 | } 393 | ], 394 | "TextContent":[ 395 | { 396 | "Text":"Go言語とGoogle App EngineでWebアプリを作る。クラウド環境でWebアプリ製作。", 397 | "TextType":"03", 398 | "ContentAudience":"00" 399 | }, 400 | { 401 | "Text":"1 はじめに\n2 開発環境の構築\n3 Go言語基礎\n4 Google App Engine API\n5 Google App Engine for Goを使ったWebアプリケーション作成\n補章 今後のSDKの変更と、APIの追加に備えて", 402 | "TextType":"04", 403 | "ContentAudience":"00" 404 | } 405 | ] 406 | }, 407 | "PublishingDetail":{ 408 | "Imprint":{ 409 | "ImprintName":"秀和システム", 410 | "ImprintIdentifier":[ 411 | { 412 | "IDValue":"7980", 413 | "ImprintIDType":"19" 414 | } 415 | ] 416 | }, 417 | "PublishingDate":[ 418 | { 419 | "Date":"", 420 | "PublishingDateRole":"01" 421 | } 422 | ] 423 | }, 424 | "RecordReference":"9784798031804", 425 | "NotificationType":"03", 426 | "ProductIdentifier":{ 427 | "IDValue":"9784798031804", 428 | "ProductIDType":"15" 429 | }, 430 | "ProductSupply":{ 431 | "SupplyDetail":{ 432 | "ReturnsConditions":{ 433 | "ReturnsCode":"02", 434 | "ReturnsCodeType":"04" 435 | }, 436 | "ProductAvailability":"99" 437 | } 438 | }, 439 | "DescriptiveDetail":{ 440 | "TitleDetail":{ 441 | "TitleType":"01", 442 | "TitleElement":{ 443 | "TitleElementLevel":"01", 444 | "TitleText":{ 445 | "content":"Go言語プログラミング入門 : on Google App Engine", 446 | "collationkey":"Go ゲンゴ プログラミング ニュウモン : on Google App Engine" 447 | } 448 | } 449 | }, 450 | "Language":[ 451 | { 452 | "LanguageCode":"jpn", 453 | "LanguageRole":"01", 454 | "CountryCode":"JP" 455 | } 456 | ], 457 | "ProductForm":"BZ", 458 | "Extent":[ 459 | { 460 | "ExtentValue":"364", 461 | "ExtentUnit":"03", 462 | "ExtentType":"11" 463 | } 464 | ], 465 | "Measure":[ 466 | { 467 | "MeasureType":"01", 468 | "MeasureUnitCode":"mm", 469 | "Measurement":"240" 470 | }, 471 | { 472 | "MeasureType":"02", 473 | "MeasureUnitCode":"mm", 474 | "Measurement":"0" 475 | } 476 | ], 477 | "Contributor":[ 478 | { 479 | "ContributorRole":[ 480 | "A01" 481 | ], 482 | "PersonName":{ 483 | "content":"横山 隆司" 484 | }, 485 | "SequenceNumber":"1" 486 | } 487 | ], 488 | "ProductComposition":"00" 489 | } 490 | }, 491 | "hanmoto":{ 492 | "dateshuppan":"2011-12", 493 | "datemodified":"2016-06-18 12:01:02", 494 | "datecreated":"2016-06-18 12:01:02" 495 | }, 496 | "summary":{ 497 | "publisher":"秀和システム", 498 | "isbn":"9784798031804", 499 | "pubdate":"2011-12", 500 | "title":"Go言語プログラミング入門 : on Google App Engine", 501 | "series":"", 502 | "author":"横山隆司/著", 503 | "cover":"https://cover.openbd.jp/9784798031804.jpg", 504 | "volume":"" 505 | } 506 | } 507 | ] 508 | ` 509 | -------------------------------------------------------------------------------- /test/isbns.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | // ISBNs is ISBN codes including "1234" 4 | var ISBNs = []string{ 5 | "9780061234002", 6 | "9780071123419", 7 | "9780123403520", 8 | "9780123423207", 9 | "9780123472250", 10 | "9780123493538", 11 | "9780198123484", 12 | "9780262012638", 13 | "9780312345617", 14 | "9780333123492", 15 | "9780333613559", 16 | "9780471234425", 17 | "9780471234852", 18 | "9780521123440", 19 | "9780521234160", 20 | "9780521234375", 21 | "9780521234382", 22 | "9780521234474", 23 | "9780521234733", 24 | "9780521234740", 25 | "9780521234801", 26 | "9780521234887", 27 | "9780521234900", 28 | "9780521234917", 29 | "9780521234979", 30 | "9780571234059", 31 | "9780571234967", 32 | "9780612347311", 33 | "9780631234302", 34 | "9780631234432", 35 | "9780631234517", 36 | "9780669123418", 37 | "9780691123424", 38 | "9780702123474", 39 | "9780712346467", 40 | "9780712346474", 41 | "9780785123415", 42 | "9780785123422", 43 | "9780785123477", 44 | "9780785123491", 45 | "9780792312505", 46 | "9780802123459", 47 | "9780806123462", 48 | "9780817913311", 49 | "9780836915228", 50 | "9780837123417", 51 | "9780859641333", 52 | "9781433813290", 53 | "9781443813150", 54 | "9781578512362", 55 | "9782010123412", 56 | "9782275012391", 57 | "9783428123445", 58 | "9783442123414", 59 | "9783880123472", 60 | "9784000112345", 61 | "9784000261234", 62 | "9784001112344", 63 | "9784003231234", 64 | "9784004312345", 65 | "9784022512345", 66 | "9784022612342", 67 | "9784023312340", 68 | "9784041012345", 69 | "9784046012340", 70 | "9784047123403", 71 | "9784047123410", 72 | "9784047123427", 73 | "9784047123434", 74 | "9784047123441", 75 | "9784047123458", 76 | "9784047123465", 77 | "9784047123472", 78 | "9784047123489", 79 | "9784047123496", 80 | "9784047271234", 81 | "9784047341234", 82 | "9784048912341", 83 | "9784055012348", 84 | "9784061581234", 85 | "9784062123426", 86 | "9784062123433", 87 | "9784062123440", 88 | "9784062123457", 89 | "9784062123471", 90 | "9784062191234", 91 | "9784062711234", 92 | "9784062881234", 93 | "9784063123401", 94 | "9784063123418", 95 | "9784063123425", 96 | "9784063123432", 97 | "9784063123449", 98 | "9784063123456", 99 | "9784063123463", 100 | "9784063123470", 101 | "9784063123487", 102 | "9784063123494", 103 | "9784063412345", 104 | "9784063491234", 105 | "9784063612349", 106 | "9784063631234", 107 | "9784063712346", 108 | "9784063871234", 109 | "9784074123469", 110 | "9784083212345", 111 | "9784086012348", 112 | "9784086191234", 113 | "9784088481234", 114 | "9784088551234", 115 | "9784091234018", 116 | "9784091234025", 117 | "9784091234032", 118 | "9784091234049", 119 | "9784091234056", 120 | "9784091234063", 121 | "9784091234070", 122 | "9784091234087", 123 | "9784091234094", 124 | "9784091234100", 125 | "9784091234223", 126 | "9784091234230", 127 | "9784091234247", 128 | "9784091234254", 129 | "9784091234278", 130 | "9784091234285", 131 | "9784091234292", 132 | "9784091234308", 133 | "9784091234346", 134 | "9784091234353", 135 | "9784091234360", 136 | "9784091234384", 137 | "9784091234391", 138 | "9784091234407", 139 | "9784091234438", 140 | "9784091234445", 141 | "9784091234452", 142 | "9784091234469", 143 | "9784091234476", 144 | "9784091234483", 145 | "9784091234490", 146 | "9784091234506", 147 | "9784091234612", 148 | "9784091234629", 149 | "9784091234636", 150 | "9784091234643", 151 | "9784091234650", 152 | "9784091234667", 153 | "9784091234674", 154 | "9784091234681", 155 | "9784091234704", 156 | "9784091234735", 157 | "9784091234759", 158 | "9784091234766", 159 | "9784091234773", 160 | "9784091234780", 161 | "9784091234797", 162 | "9784091234803", 163 | "9784091234810", 164 | "9784091234827", 165 | "9784091234834", 166 | "9784091234841", 167 | "9784091234858", 168 | "9784091234865", 169 | "9784091234872", 170 | "9784091234889", 171 | "9784091234896", 172 | "9784091234902", 173 | "9784091312341", 174 | "9784091351234", 175 | "9784091412348", 176 | "9784091512345", 177 | "9784091591234", 178 | "9784091812346", 179 | "9784091912343", 180 | "9784092812345", 181 | "9784093881234", 182 | "9784094512342", 183 | "9784101234137", 184 | "9784101234151", 185 | "9784101234175", 186 | "9784101234205", 187 | "9784101234229", 188 | "9784101234236", 189 | "9784101481234", 190 | "9784107712349", 191 | "9784121012340", 192 | "9784125012346", 193 | "9784130261234", 194 | "9784130912341", 195 | "9784140161234", 196 | "9784140912348", 197 | "9784150312343", 198 | "9784150412340", 199 | "9784173521234", 200 | "9784181234157", 201 | "9784191234239", 202 | "9784199501234", 203 | "9784251012340", 204 | "9784255001234", 205 | "9784260021234", 206 | "9784262123417", 207 | "9784262123424", 208 | "9784262123486", 209 | "9784262123493", 210 | "9784272412341", 211 | "9784272612345", 212 | "9784276112346", 213 | "9784276123410", 214 | "9784284401234", 215 | "9784286012346", 216 | "9784309412344", 217 | "9784309621234", 218 | "9784312345196", 219 | "9784315512342", 220 | "9784320012349", 221 | "9784320112346", 222 | "9784320123403", 223 | "9784320123410", 224 | "9784320123427", 225 | "9784320123434", 226 | "9784320123441", 227 | "9784320123458", 228 | "9784320123465", 229 | "9784320123472", 230 | "9784320123489", 231 | "9784320123496", 232 | "9784322123425", 233 | "9784322123432", 234 | "9784322123463", 235 | "9784322123470", 236 | "9784322123487", 237 | "9784322123494", 238 | "9784334012342", 239 | "9784335501234", 240 | "9784338261234", 241 | "9784344012349", 242 | "9784381012340", 243 | "9784384012347", 244 | "9784384701234", 245 | "9784393312346", 246 | "9784395012343", 247 | "9784396112349", 248 | "9784396821234", 249 | "9784397501234", 250 | "9784403501234", 251 | "9784403671234", 252 | "9784408171234", 253 | "9784411012340", 254 | "9784411801234", 255 | "9784416212349", 256 | "9784416312346", 257 | "9784418141234", 258 | "9784419061234", 259 | "9784422812342", 260 | "9784425211234", 261 | "9784425212347", 262 | "9784433212346", 263 | "9784434212345", 264 | "9784469012347", 265 | "9784471123444", 266 | "9784471123451", 267 | "9784475012348", 268 | "9784477001234", 269 | "9784496051234", 270 | "9784498123458", 271 | "9784498123496", 272 | "9784502512346", 273 | "9784532123406", 274 | "9784532131234", 275 | "9784534041234", 276 | "9784535512344", 277 | "9784537212341", 278 | "9784540121234", 279 | "9784542123403", 280 | "9784561234210", 281 | "9784561234418", 282 | "9784561234463", 283 | "9784561234524", 284 | "9784561234609", 285 | "9784561234944", 286 | "9784564431234", 287 | "9784569812342", 288 | "9784571121234", 289 | "9784573012349", 290 | "9784573912342", 291 | "9784579211234", 292 | "9784579212347", 293 | "9784580812345", 294 | "9784582212341", 295 | "9784585221234", 296 | "9784621301234", 297 | "9784623071234", 298 | "9784641031234", 299 | "9784641123434", 300 | "9784641123441", 301 | "9784641123458", 302 | "9784641123472", 303 | "9784641123489", 304 | "9784641123496", 305 | "9784750311234", 306 | "9784750312347", 307 | "9784750512341", 308 | "9784754712341", 309 | "9784757101234", 310 | "9784757123410", 311 | "9784757123427", 312 | "9784757123434", 313 | "9784757123441", 314 | "9784757123458", 315 | "9784757123465", 316 | "9784757123472", 317 | "9784757123489", 318 | "9784757512344", 319 | "9784757712348", 320 | "9784758312349", 321 | "9784759251234", 322 | "9784760112340", 323 | "9784760123407", 324 | "9784760123414", 325 | "9784760123438", 326 | "9784761512347", 327 | "9784765012348", 328 | "9784766123449", 329 | "9784766412345", 330 | "9784768471234", 331 | "9784772612340", 332 | "9784774112343", 333 | "9784774123400", 334 | "9784774123417", 335 | "9784774123424", 336 | "9784774123479", 337 | "9784774791234", 338 | "9784775301234", 339 | "9784775312346", 340 | "9784775912348", 341 | "9784776612346", 342 | "9784779112348", 343 | "9784779121234", 344 | "9784780712346", 345 | "9784780912340", 346 | "9784781612348", 347 | "9784782851234", 348 | "9784784071234", 349 | "9784785201234", 350 | "9784785751234", 351 | "9784787712349", 352 | "9784788341234", 353 | "9784788512344", 354 | "9784788912342", 355 | "9784789712347", 356 | "9784789912341", 357 | "9784790712343", 358 | "9784791761234", 359 | "9784793121234", 360 | "9784794212344", 361 | "9784797212341", 362 | "9784798012346", 363 | "9784798123424", 364 | "9784798123431", 365 | "9784798123448", 366 | "9784798612348", 367 | "9784798912349", 368 | "9784801512344", 369 | "9784803912340", 370 | "9784804612348", 371 | "9784805851234", 372 | "9784806123453", 373 | "9784809412349", 374 | "9784812212349", 375 | "9784816912344", 376 | "9784818651234", 377 | "9784819112345", 378 | "9784827112344", 379 | "9784827712346", 380 | "9784829123409", 381 | "9784829123454", 382 | "9784829123478", 383 | "9784829161234", 384 | "9784829921234", 385 | "9784830112348", 386 | "9784840123419", 387 | "9784840123440", 388 | "9784840123464", 389 | "9784840812344", 390 | "9784842912349", 391 | "9784845211234", 392 | "9784846012342", 393 | "9784860112349", 394 | "9784860371234", 395 | "9784860511234", 396 | "9784862041234", 397 | "9784863101234", 398 | "9784863271234", 399 | "9784863712348", 400 | "9784864641234", 401 | "9784864711234", 402 | "9784864712347", 403 | "9784864912341", 404 | "9784877512347", 405 | "9784877821234", 406 | "9784877912345", 407 | "9784879212344", 408 | "9784880861234", 409 | "9784882081234", 410 | "9784883521234", 411 | "9784884751234", 412 | "9784885612343", 413 | "9784885912344", 414 | "9784886212344", 415 | "9784888881234", 416 | "9784892712340", 417 | "9784893812346", 418 | "9784894341234", 419 | "9784894891234", 420 | "9784895881234", 421 | "9784896012347", 422 | "9784896251234", 423 | "9784896412345", 424 | "9784896912340", 425 | "9784899841234", 426 | "9784900612341", 427 | "9784901234009", 428 | "9784901234061", 429 | "9784901234115", 430 | "9784901234139", 431 | "9784901234160", 432 | "9784901234214", 433 | "9784901234313", 434 | "9784901234344", 435 | "9784901234375", 436 | "9784901234405", 437 | "9784901234436", 438 | "9784901234498", 439 | "9784901234504", 440 | "9784901234511", 441 | "9784901234573", 442 | "9784901234696", 443 | "9784901234719", 444 | "9784901234740", 445 | "9784901234849", 446 | "9784901234887", 447 | "9784901234900", 448 | "9784901234962", 449 | "9784901331234", 450 | "9784902212341", 451 | "9784902251234", 452 | "9784903212340", 453 | "9784904231234", 454 | "9784904611234", 455 | "9784906451234", 456 | "9784906691234", 457 | "9784915361234", 458 | "9784915811234", 459 | "9784916123404", 460 | "9784916123435", 461 | "9784916123442", 462 | "9784938681234", 463 | "9784939051234", 464 | "9784990123406", 465 | "9784990123413", 466 | "9784990123420", 467 | "9784990123437", 468 | "9784990123444", 469 | "9784990123475", 470 | "9784990123482", 471 | "9784990123499", 472 | "9785891234666", 473 | "9787226012345", 474 | "9787801234452", 475 | "9789041112347", 476 | "9789048123490", 477 | "9789264112346", 478 | "9789264123410", 479 | "9789264123496", 480 | "9789812347992", 481 | } 482 | -------------------------------------------------------------------------------- /test/pubdate_json.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | const PubdateYMDHyphen = `[{"summary":{ "pubdate":"2017-10-01" }}]` 4 | const PubdateYMHyphen = `[{"summary":{ "pubdate":"2017-10" }}]` 5 | const PubdateYMD = `[{"summary":{ "pubdate":"20171001" }}]` 6 | const PubdateYM = `[{"summary":{ "pubdate":"201710" }}]` 7 | --------------------------------------------------------------------------------