Merge branch 'master' into pubdate-range

pull/1/head
eric 2015-11-16 11:06:21 -05:00
commit 7b7d7cf174
30 changed files with 699 additions and 306 deletions

View File

@ -47,6 +47,7 @@ def header(facet=None):
def product(edition, facet=None): def product(edition, facet=None):
ebooks=facet.filter_model("Ebook",edition.ebooks.filter(active=True)) if facet else edition.ebooks.filter(active=True) ebooks=facet.filter_model("Ebook",edition.ebooks.filter(active=True)) if facet else edition.ebooks.filter(active=True)
ebooks=ebooks.order_by('-created')
# Just because an edition satisfies 2 facets with multiple ebooks doesn't mean that there is a single ebook satisfies both facets # Just because an edition satisfies 2 facets with multiple ebooks doesn't mean that there is a single ebook satisfies both facets
if not ebooks.exists(): if not ebooks.exists():
return None return None
@ -72,13 +73,18 @@ def product(edition, facet=None):
descriptive_node.append(text_node("ProductForm", "ED" )) # download descriptive_node.append(text_node("ProductForm", "ED" )) # download
ebook = None ebook = None
latest_ebooks = []
ebook_formats = []
for ebook in ebooks: for ebook in ebooks:
if ebook.format=='epub': if ebook.format not in ebook_formats:
descriptive_node.append(text_node("ProductFormDetail", "E101" )) ebook_formats.append(ebook.format)
elif ebook.format=='pdf': latest_ebooks.append(ebook)
descriptive_node.append(text_node("ProductFormDetail", "E107" )) if ebook.format=='epub':
elif ebook.format=='mobi': descriptive_node.append(text_node("ProductFormDetail", "E101" ))
descriptive_node.append(text_node("ProductFormDetail", "E116" )) elif ebook.format=='pdf':
descriptive_node.append(text_node("ProductFormDetail", "E107" ))
elif ebook.format=='mobi':
descriptive_node.append(text_node("ProductFormDetail", "E116" ))
if ebook.rights: if ebook.rights:
license_node = etree.SubElement(descriptive_node, "EpubLicense") license_node = etree.SubElement(descriptive_node, "EpubLicense")
license_node.append(text_node("EpubLicenseName", ebook.rights )) license_node.append(text_node("EpubLicenseName", ebook.rights ))
@ -171,7 +177,7 @@ def product(edition, facet=None):
supplier_node = etree.SubElement(supply_detail_node,"Supplier") supplier_node = etree.SubElement(supply_detail_node,"Supplier")
supplier_node.append(text_node("SupplierRole", '11')) #non-exclusive distributer supplier_node.append(text_node("SupplierRole", '11')) #non-exclusive distributer
supplier_node.append(text_node("SupplierName", 'Unglue.it')) #non-exclusive distributer supplier_node.append(text_node("SupplierName", 'Unglue.it')) #non-exclusive distributer
for ebook in ebooks: for ebook in latest_ebooks:
website_node = etree.SubElement(supplier_node,"Website") website_node = etree.SubElement(supplier_node,"Website")
website_node.append(text_node("WebsiteRole", '29')) #full content website_node.append(text_node("WebsiteRole", '29')) #full content
website_node.append(text_node("WebsiteDescription", '%s file download' % ebook.format, attrib={'textformat':'06'})) #full content website_node.append(text_node("WebsiteDescription", '%s file download' % ebook.format, attrib={'textformat':'06'})) #full content

View File

@ -183,9 +183,9 @@ bisac= {
"notation": "ARC006000", "notation": "ARC006000",
"alt_label": [] "alt_label": []
}, },
"Gardening / Regional / West (ak, Ca, Co, Hi, Id, Mt, Nv, Ut, Wy": { "Gardening / Regional / West (ak, Ca, Co, Hi, Id, Mt, Nv, Ut, Wy)": {
"related": [], "related": [],
"pref_label": "Gardening / Regional / West (ak, Ca, Co, Hi, Id, Mt, Nv, Ut, Wy", "pref_label": "Gardening / Regional / West (ak, Ca, Co, Hi, Id, Mt, Nv, Ut, Wy)",
"notation": "GAR019080", "notation": "GAR019080",
"alt_label": [] "alt_label": []
}, },
@ -213,9 +213,9 @@ bisac= {
"notation": "BIO016000", "notation": "BIO016000",
"alt_label": [] "alt_label": []
}, },
"Religion / Christianity / Church Of Jesus Christ Of Latter-day Saints (mormon": { "Religion / Christianity / Church Of Jesus Christ Of Latter-day Saints (mormon)": {
"related": [], "related": [],
"pref_label": "Religion / Christianity / Church Of Jesus Christ Of Latter-day Saints (mormon", "pref_label": "Religion / Christianity / Church Of Jesus Christ Of Latter-day Saints (mormon)",
"notation": "REL046000", "notation": "REL046000",
"alt_label": [ "alt_label": [
"Religion / Christianity / Mormon" "Religion / Christianity / Mormon"
@ -263,9 +263,9 @@ bisac= {
"notation": "NAT012000", "notation": "NAT012000",
"alt_label": [] "alt_label": []
}, },
"History / Military / Persian Gulf War (1991": { "History / Military / Persian Gulf War (1991)": {
"related": [], "related": [],
"pref_label": "History / Military / Persian Gulf War (1991", "pref_label": "History / Military / Persian Gulf War (1991)",
"notation": "HIS027040", "notation": "HIS027040",
"alt_label": [] "alt_label": []
}, },
@ -460,15 +460,15 @@ bisac= {
"notation": "PHI001000", "notation": "PHI001000",
"alt_label": [] "alt_label": []
}, },
"Gardening / Regional / Southwest (az, Nm, Ok, Tx": { "Gardening / Regional / Southwest (az, Nm, Ok, Tx)": {
"related": [], "related": [],
"pref_label": "Gardening / Regional / Southwest (az, Nm, Ok, Tx", "pref_label": "Gardening / Regional / Southwest (az, Nm, Ok, Tx)",
"notation": "GAR019070", "notation": "GAR019070",
"alt_label": [] "alt_label": []
}, },
"Study Aids / Mcat (medical College Admission Test": { "Study Aids / Mcat (medical College Admission Test)": {
"related": [], "related": [],
"pref_label": "Study Aids / Mcat (medical College Admission Test", "pref_label": "Study Aids / Mcat (medical College Admission Test)",
"notation": "STU032000", "notation": "STU032000",
"alt_label": [] "alt_label": []
}, },
@ -526,9 +526,9 @@ bisac= {
"notation": "PHO015000", "notation": "PHO015000",
"alt_label": [] "alt_label": []
}, },
"Social Science / Holidays (non-religious": { "Social Science / Holidays (non-religious)": {
"related": [], "related": [],
"pref_label": "Social Science / Holidays (non-religious", "pref_label": "Social Science / Holidays (non-religious)",
"notation": "SOC014000", "notation": "SOC014000",
"alt_label": [] "alt_label": []
}, },
@ -976,9 +976,9 @@ bisac= {
"notation": "TRA006030", "notation": "TRA006030",
"alt_label": [] "alt_label": []
}, },
"Travel / United States / West / Pacific (ak, Ca, Hi, Nv, Or, Wa": { "Travel / United States / West / Pacific (ak, Ca, Hi, Nv, Or, Wa)": {
"related": [], "related": [],
"pref_label": "Travel / United States / West / Pacific (ak, Ca, Hi, Nv, Or, Wa", "pref_label": "Travel / United States / West / Pacific (ak, Ca, Hi, Nv, Or, Wa)",
"notation": "TRV025130", "notation": "TRV025130",
"alt_label": [] "alt_label": []
}, },
@ -1720,9 +1720,9 @@ bisac= {
"notation": "REL032010", "notation": "REL032010",
"alt_label": [] "alt_label": []
}, },
"History / Americas (north, Central, South, West Indies": { "History / Americas (north, Central, South, West Indies)": {
"related": [], "related": [],
"pref_label": "History / Americas (north, Central, South, West Indies", "pref_label": "History / Americas (north, Central, South, West Indies)",
"notation": "HIS038000", "notation": "HIS038000",
"alt_label": [] "alt_label": []
}, },
@ -1910,9 +1910,9 @@ bisac= {
"notation": "TEC031000", "notation": "TEC031000",
"alt_label": [] "alt_label": []
}, },
"History / Military / Afghan War (2001-": { "History / Military / Afghan War (2001-)": {
"related": [], "related": [],
"pref_label": "History / Military / Afghan War (2001-", "pref_label": "History / Military / Afghan War (2001-)",
"notation": "HIS027190", "notation": "HIS027190",
"alt_label": [] "alt_label": []
}, },
@ -1990,9 +1990,9 @@ bisac= {
"notation": "BIB004070", "notation": "BIB004070",
"alt_label": [] "alt_label": []
}, },
"Juvenile Nonfiction / Biography & Autobiography / Presidents And First Families (u.s.": { "Juvenile Nonfiction / Biography & Autobiography / Presidents And First Families (u.s.)": {
"related": [], "related": [],
"pref_label": "Juvenile Nonfiction / Biography & Autobiography / Presidents And First Families (u.s.", "pref_label": "Juvenile Nonfiction / Biography & Autobiography / Presidents And First Families (u.s.)",
"notation": "JNF007130", "notation": "JNF007130",
"alt_label": [] "alt_label": []
}, },
@ -2092,9 +2092,9 @@ bisac= {
"notation": "SEL001000", "notation": "SEL001000",
"alt_label": [] "alt_label": []
}, },
"Travel / United States / South / East South Central (al, Ky, Ms, Tn": { "Travel / United States / South / East South Central (al, Ky, Ms, Tn)": {
"related": [], "related": [],
"pref_label": "Travel / United States / South / East South Central (al, Ky, Ms, Tn", "pref_label": "Travel / United States / South / East South Central (al, Ky, Ms, Tn)",
"notation": "TRV025080", "notation": "TRV025080",
"alt_label": [] "alt_label": []
}, },
@ -2452,9 +2452,9 @@ bisac= {
"notation": "MUS023040", "notation": "MUS023040",
"alt_label": [] "alt_label": []
}, },
"History / United States / State & Local / Middle Atlantic (dc, De, Md, Nj, Ny, Pa": { "History / United States / State & Local / Middle Atlantic (dc, De, Md, Nj, Ny, Pa)": {
"related": [], "related": [],
"pref_label": "History / United States / State & Local / Middle Atlantic (dc, De, Md, Nj, Ny, Pa", "pref_label": "History / United States / State & Local / Middle Atlantic (dc, De, Md, Nj, Ny, Pa)",
"notation": "HIS036080", "notation": "HIS036080",
"alt_label": [] "alt_label": []
}, },
@ -2703,9 +2703,9 @@ bisac= {
"notation": "CRA045000", "notation": "CRA045000",
"alt_label": [] "alt_label": []
}, },
"Gardening / Regional / South (al, Ar, Fl, Ga, Ky, La, Ms, Nc, Sc, Tn, Va, Wv": { "Gardening / Regional / South (al, Ar, Fl, Ga, Ky, La, Ms, Nc, Sc, Tn, Va, Wv)": {
"related": [], "related": [],
"pref_label": "Gardening / Regional / South (al, Ar, Fl, Ga, Ky, La, Ms, Nc, Sc, Tn, Va, Wv", "pref_label": "Gardening / Regional / South (al, Ar, Fl, Ga, Ky, La, Ms, Nc, Sc, Tn, Va, Wv)",
"notation": "GAR019060", "notation": "GAR019060",
"alt_label": [] "alt_label": []
}, },
@ -3293,9 +3293,9 @@ bisac= {
"notation": "JUV030110", "notation": "JUV030110",
"alt_label": [] "alt_label": []
}, },
"Travel / Canada / Quebec (qc": { "Travel / Canada / Quebec (qc)": {
"related": [], "related": [],
"pref_label": "Travel / Canada / Quebec (qc", "pref_label": "Travel / Canada / Quebec (qc)",
"notation": "TRV006060", "notation": "TRV006060",
"alt_label": [] "alt_label": []
}, },
@ -3657,9 +3657,9 @@ bisac= {
"notation": "MAT036000", "notation": "MAT036000",
"alt_label": [] "alt_label": []
}, },
"Juvenile Fiction / Historical / Canada / Pre-confederation (to 1867": { "Juvenile Fiction / Historical / Canada / Pre-confederation (to 1867)": {
"related": [], "related": [],
"pref_label": "Juvenile Fiction / Historical / Canada / Pre-confederation (to 1867", "pref_label": "Juvenile Fiction / Historical / Canada / Pre-confederation (to 1867)",
"notation": "JUV016170", "notation": "JUV016170",
"alt_label": [] "alt_label": []
}, },
@ -3687,9 +3687,9 @@ bisac= {
"notation": "JUV032120", "notation": "JUV032120",
"alt_label": [] "alt_label": []
}, },
"History / Canada / Post-confederation (1867-": { "History / Canada / Post-confederation (1867-)": {
"related": [], "related": [],
"pref_label": "History / Canada / Post-confederation (1867-", "pref_label": "History / Canada / Post-confederation (1867-)",
"notation": "HIS006020", "notation": "HIS006020",
"alt_label": [] "alt_label": []
}, },
@ -4198,9 +4198,9 @@ bisac= {
"notation": "JNF052010", "notation": "JNF052010",
"alt_label": [] "alt_label": []
}, },
"History / Canada / Pre-confederation (to 1867": { "History / Canada / Pre-confederation (to 1867)": {
"related": [], "related": [],
"pref_label": "History / Canada / Pre-confederation (to 1867", "pref_label": "History / Canada / Pre-confederation (to 1867)",
"notation": "HIS006010", "notation": "HIS006010",
"alt_label": [] "alt_label": []
}, },
@ -5029,9 +5029,9 @@ bisac= {
"notation": "COM066000", "notation": "COM066000",
"alt_label": [] "alt_label": []
}, },
"Gardening / Regional / Pacific Northwest (or, Wa": { "Gardening / Regional / Pacific Northwest (or, Wa)": {
"related": [], "related": [],
"pref_label": "Gardening / Regional / Pacific Northwest (or, Wa", "pref_label": "Gardening / Regional / Pacific Northwest (or, Wa)",
"notation": "GAR019050", "notation": "GAR019050",
"alt_label": [] "alt_label": []
}, },
@ -5189,9 +5189,9 @@ bisac= {
"notation": "JNF053160", "notation": "JNF053160",
"alt_label": [] "alt_label": []
}, },
"History / United States / Civil War Period (1850-1877": { "History / United States / Civil War Period (1850-1877)": {
"related": [], "related": [],
"pref_label": "History / United States / Civil War Period (1850-1877", "pref_label": "History / United States / Civil War Period (1850-1877)",
"notation": "HIS036050", "notation": "HIS036050",
"alt_label": [ "alt_label": [
"History / Military / United States / Civil War" "History / Military / United States / Civil War"
@ -5320,9 +5320,9 @@ bisac= {
"notation": "TRV014000", "notation": "TRV014000",
"alt_label": [] "alt_label": []
}, },
"History / United States / State & Local / South (al, Ar, Fl, Ga, Ky, La, Ms, Nc, Sc, Tn, Va, Wv": { "History / United States / State & Local / South (al, Ar, Fl, Ga, Ky, La, Ms, Nc, Sc, Tn, Va, Wv)": {
"related": [], "related": [],
"pref_label": "History / United States / State & Local / South (al, Ar, Fl, Ga, Ky, La, Ms, Nc, Sc, Tn, Va, Wv", "pref_label": "History / United States / State & Local / South (al, Ar, Fl, Ga, Ky, La, Ms, Nc, Sc, Tn, Va, Wv)",
"notation": "HIS036120", "notation": "HIS036120",
"alt_label": [] "alt_label": []
}, },
@ -5350,9 +5350,9 @@ bisac= {
"notation": "JNF026100", "notation": "JNF026100",
"alt_label": [] "alt_label": []
}, },
"Health & Fitness / Diseases / Nervous System (incl. Brain": { "Health & Fitness / Diseases / Nervous System (incl. Brain)": {
"related": [], "related": [],
"pref_label": "Health & Fitness / Diseases / Nervous System (incl. Brain", "pref_label": "Health & Fitness / Diseases / Nervous System (incl. Brain)",
"notation": "HEA039110", "notation": "HEA039110",
"alt_label": [] "alt_label": []
}, },
@ -5470,9 +5470,9 @@ bisac= {
"notation": "BUS008000", "notation": "BUS008000",
"alt_label": [] "alt_label": []
}, },
"Travel / United States / South / West South Central (ar, La, Ok, Tx": { "Travel / United States / South / West South Central (ar, La, Ok, Tx)": {
"related": [], "related": [],
"pref_label": "Travel / United States / South / West South Central (ar, La, Ok, Tx", "pref_label": "Travel / United States / South / West South Central (ar, La, Ok, Tx)",
"notation": "TRV025100", "notation": "TRV025100",
"alt_label": [] "alt_label": []
}, },
@ -5846,9 +5846,9 @@ bisac= {
"notation": "BUS022000", "notation": "BUS022000",
"alt_label": [] "alt_label": []
}, },
"Study Aids / Gmat (graduate Management Admission Test": { "Study Aids / Gmat (graduate Management Admission Test)": {
"related": [], "related": [],
"pref_label": "Study Aids / Gmat (graduate Management Admission Test", "pref_label": "Study Aids / Gmat (graduate Management Admission Test)",
"notation": "STU013000", "notation": "STU013000",
"alt_label": [] "alt_label": []
}, },
@ -6022,9 +6022,9 @@ bisac= {
"notation": "TRA004000", "notation": "TRA004000",
"alt_label": [] "alt_label": []
}, },
"Study Aids / Toefl (test Of English As A Foreign Language": { "Study Aids / Toefl (test Of English As A Foreign Language)": {
"related": [], "related": [],
"pref_label": "Study Aids / Toefl (test Of English As A Foreign Language", "pref_label": "Study Aids / Toefl (test Of English As A Foreign Language)",
"notation": "STU028000", "notation": "STU028000",
"alt_label": [] "alt_label": []
}, },
@ -6114,9 +6114,9 @@ bisac= {
"notation": "SOC026000", "notation": "SOC026000",
"alt_label": [] "alt_label": []
}, },
"Foreign Language Study / Slavic Languages (other": { "Foreign Language Study / Slavic Languages (other)": {
"related": [], "related": [],
"pref_label": "Foreign Language Study / Slavic Languages (other", "pref_label": "Foreign Language Study / Slavic Languages (other)",
"notation": "FOR024000", "notation": "FOR024000",
"alt_label": [] "alt_label": []
}, },
@ -6711,9 +6711,9 @@ bisac= {
"notation": "PSY026000", "notation": "PSY026000",
"alt_label": [] "alt_label": []
}, },
"Travel / Canada / Territories & Nunavut (nt, Nu, Yt": { "Travel / Canada / Territories & Nunavut (nt, Nu, Yt)": {
"related": [], "related": [],
"pref_label": "Travel / Canada / Territories & Nunavut (nt, Nu, Yt", "pref_label": "Travel / Canada / Territories & Nunavut (nt, Nu, Yt)",
"notation": "TRV006040", "notation": "TRV006040",
"alt_label": [] "alt_label": []
}, },
@ -6943,9 +6943,9 @@ bisac= {
"notation": "COM021000", "notation": "COM021000",
"alt_label": [] "alt_label": []
}, },
"History / United States / Colonial Period (1600-1775": { "History / United States / Colonial Period (1600-1775)": {
"related": [], "related": [],
"pref_label": "History / United States / Colonial Period (1600-1775", "pref_label": "History / United States / Colonial Period (1600-1775)",
"notation": "HIS036020", "notation": "HIS036020",
"alt_label": [] "alt_label": []
}, },
@ -7593,9 +7593,9 @@ bisac= {
"notation": "OCC019000", "notation": "OCC019000",
"alt_label": [] "alt_label": []
}, },
"Psychology / Psychopathology / Attention-deficit Disorder (add-adhd": { "Psychology / Psychopathology / Attention-deficit Disorder (add-adhd)": {
"related": [], "related": [],
"pref_label": "Psychology / Psychopathology / Attention-deficit Disorder (add-adhd", "pref_label": "Psychology / Psychopathology / Attention-deficit Disorder (add-adhd)",
"notation": "PSY022010", "notation": "PSY022010",
"alt_label": [] "alt_label": []
}, },
@ -7823,9 +7823,9 @@ bisac= {
"notation": "POE010000", "notation": "POE010000",
"alt_label": [] "alt_label": []
}, },
"Travel / United States / Northeast / Middle Atlantic (nj, Ny, Pa": { "Travel / United States / Northeast / Middle Atlantic (nj, Ny, Pa)": {
"related": [], "related": [],
"pref_label": "Travel / United States / Northeast / Middle Atlantic (nj, Ny, Pa", "pref_label": "Travel / United States / Northeast / Middle Atlantic (nj, Ny, Pa)",
"notation": "TRV025050", "notation": "TRV025050",
"alt_label": [] "alt_label": []
}, },
@ -7853,9 +7853,9 @@ bisac= {
"notation": "GAM016000", "notation": "GAM016000",
"alt_label": [] "alt_label": []
}, },
"Travel / Canada / Atlantic Provinces (nb, Nf, Ns, Pe": { "Travel / Canada / Atlantic Provinces (nb, Nf, Ns, Pe)": {
"related": [], "related": [],
"pref_label": "Travel / Canada / Atlantic Provinces (nb, Nf, Ns, Pe", "pref_label": "Travel / Canada / Atlantic Provinces (nb, Nf, Ns, Pe)",
"notation": "TRV006010", "notation": "TRV006010",
"alt_label": [] "alt_label": []
}, },
@ -8070,15 +8070,15 @@ bisac= {
"notation": "JNF063000", "notation": "JNF063000",
"alt_label": [] "alt_label": []
}, },
"Juvenile Nonfiction / History / United States / Civil War Period (1850-1877": { "Juvenile Nonfiction / History / United States / Civil War Period (1850-1877)": {
"related": [], "related": [],
"pref_label": "Juvenile Nonfiction / History / United States / Civil War Period (1850-1877", "pref_label": "Juvenile Nonfiction / History / United States / Civil War Period (1850-1877)",
"notation": "JNF025270", "notation": "JNF025270",
"alt_label": [] "alt_label": []
}, },
"Travel / United States / Northeast / New England (ct, Ma, Me, Nh, Ri, Vt": { "Travel / United States / Northeast / New England (ct, Ma, Me, Nh, Ri, Vt)": {
"related": [], "related": [],
"pref_label": "Travel / United States / Northeast / New England (ct, Ma, Me, Nh, Ri, Vt", "pref_label": "Travel / United States / Northeast / New England (ct, Ma, Me, Nh, Ri, Vt)",
"notation": "TRV025060", "notation": "TRV025060",
"alt_label": [] "alt_label": []
}, },
@ -8288,9 +8288,9 @@ bisac= {
"notation": "JUV039120", "notation": "JUV039120",
"alt_label": [] "alt_label": []
}, },
"Foreign Language Study / Greek (modern": { "Foreign Language Study / Greek (modern)": {
"related": [], "related": [],
"pref_label": "Foreign Language Study / Greek (modern", "pref_label": "Foreign Language Study / Greek (modern)",
"notation": "FOR010000", "notation": "FOR010000",
"alt_label": [] "alt_label": []
}, },
@ -8528,9 +8528,9 @@ bisac= {
"notation": "MAT012000", "notation": "MAT012000",
"alt_label": [] "alt_label": []
}, },
"Travel / United States / West / Mountain (az, Co, Id, Mt, Nm, Ut, Wy": { "Travel / United States / West / Mountain (az, Co, Id, Mt, Nm, Ut, Wy)": {
"related": [], "related": [],
"pref_label": "Travel / United States / West / Mountain (az, Co, Id, Mt, Nm, Ut, Wy", "pref_label": "Travel / United States / West / Mountain (az, Co, Id, Mt, Nm, Ut, Wy)",
"notation": "TRV025120", "notation": "TRV025120",
"alt_label": [] "alt_label": []
}, },
@ -8698,9 +8698,9 @@ bisac= {
"notation": "ART009000", "notation": "ART009000",
"alt_label": [] "alt_label": []
}, },
"Psychology / Psychopathology / Post-traumatic Stress Disorder (ptsd": { "Psychology / Psychopathology / Post-traumatic Stress Disorder (ptsd)": {
"related": [], "related": [],
"pref_label": "Psychology / Psychopathology / Post-traumatic Stress Disorder (ptsd", "pref_label": "Psychology / Psychopathology / Post-traumatic Stress Disorder (ptsd)",
"notation": "PSY022040", "notation": "PSY022040",
"alt_label": [] "alt_label": []
}, },
@ -9056,9 +9056,9 @@ bisac= {
"notation": "REL067070", "notation": "REL067070",
"alt_label": [] "alt_label": []
}, },
"Study Aids / Mat (miller Analogies Test": { "Study Aids / Mat (miller Analogies Test)": {
"related": [], "related": [],
"pref_label": "Study Aids / Mat (miller Analogies Test", "pref_label": "Study Aids / Mat (miller Analogies Test)",
"notation": "STU018000", "notation": "STU018000",
"alt_label": [] "alt_label": []
}, },
@ -9195,9 +9195,9 @@ bisac= {
"notation": "JUV016160", "notation": "JUV016160",
"alt_label": [] "alt_label": []
}, },
"Study Aids / Psat & Nmsqt (national Merit Scholarship Qualifying Test": { "Study Aids / Psat & Nmsqt (national Merit Scholarship Qualifying Test)": {
"related": [], "related": [],
"pref_label": "Study Aids / Psat & Nmsqt (national Merit Scholarship Qualifying Test", "pref_label": "Study Aids / Psat & Nmsqt (national Merit Scholarship Qualifying Test)",
"notation": "STU033000", "notation": "STU033000",
"alt_label": [] "alt_label": []
}, },
@ -9263,9 +9263,9 @@ bisac= {
"notation": "SPO058000", "notation": "SPO058000",
"alt_label": [] "alt_label": []
}, },
"Self-help / Neuro-linguistic Programming (nlp": { "Self-help / Neuro-linguistic Programming (nlp)": {
"related": [], "related": [],
"pref_label": "Self-help / Neuro-linguistic Programming (nlp", "pref_label": "Self-help / Neuro-linguistic Programming (nlp)",
"notation": "SEL037000", "notation": "SEL037000",
"alt_label": [] "alt_label": []
}, },
@ -9652,9 +9652,9 @@ bisac= {
"notation": "JUV032000", "notation": "JUV032000",
"alt_label": [] "alt_label": []
}, },
"Foreign Language Study / Scandinavian Languages (other": { "Foreign Language Study / Scandinavian Languages (other)": {
"related": [], "related": [],
"pref_label": "Foreign Language Study / Scandinavian Languages (other", "pref_label": "Foreign Language Study / Scandinavian Languages (other)",
"notation": "FOR022000", "notation": "FOR022000",
"alt_label": [] "alt_label": []
}, },
@ -10046,9 +10046,9 @@ bisac= {
"notation": "TEC065000", "notation": "TEC065000",
"alt_label": [] "alt_label": []
}, },
"History / Military / Iraq War (2003-": { "History / Military / Iraq War (2003-)": {
"related": [], "related": [],
"pref_label": "History / Military / Iraq War (2003-", "pref_label": "History / Military / Iraq War (2003-)",
"notation": "HIS027170", "notation": "HIS027170",
"alt_label": [] "alt_label": []
}, },
@ -10180,9 +10180,9 @@ bisac= {
"notation": "SPO028000", "notation": "SPO028000",
"alt_label": [] "alt_label": []
}, },
"Body, Mind & Spirit / Healing / Energy (qigong, Reiki, Polarity": { "Body, Mind & Spirit / Healing / Energy (qigong, Reiki, Polarity)": {
"related": [], "related": [],
"pref_label": "Body, Mind & Spirit / Healing / Energy (qigong, Reiki, Polarity", "pref_label": "Body, Mind & Spirit / Healing / Energy (qigong, Reiki, Polarity)",
"notation": "OCC011010", "notation": "OCC011010",
"alt_label": [] "alt_label": []
}, },
@ -10526,15 +10526,15 @@ bisac= {
"notation": "DRA019000", "notation": "DRA019000",
"alt_label": [] "alt_label": []
}, },
"Travel / United States / Midwest / West North Central (ia, Ks, Mn, Mo, Nd, Ne, Sd": { "Travel / United States / Midwest / West North Central (ia, Ks, Mn, Mo, Nd, Ne, Sd)": {
"related": [], "related": [],
"pref_label": "Travel / United States / Midwest / West North Central (ia, Ks, Mn, Mo, Nd, Ne, Sd", "pref_label": "Travel / United States / Midwest / West North Central (ia, Ks, Mn, Mo, Nd, Ne, Sd)",
"notation": "TRV025030", "notation": "TRV025030",
"alt_label": [] "alt_label": []
}, },
"Computers / Networking / Local Area Networks (lans": { "Computers / Networking / Local Area Networks (lans)": {
"related": [], "related": [],
"pref_label": "Computers / Networking / Local Area Networks (lans", "pref_label": "Computers / Networking / Local Area Networks (lans)",
"notation": "COM043020", "notation": "COM043020",
"alt_label": [] "alt_label": []
}, },
@ -10592,9 +10592,9 @@ bisac= {
"notation": "TEC009140", "notation": "TEC009140",
"alt_label": [] "alt_label": []
}, },
"History / United States / State & Local / West (ak, Ca, Co, Hi, Id, Mt, Nv, Ut, Wy": { "History / United States / State & Local / West (ak, Ca, Co, Hi, Id, Mt, Nv, Ut, Wy)": {
"related": [], "related": [],
"pref_label": "History / United States / State & Local / West (ak, Ca, Co, Hi, Id, Mt, Nv, Ut, Wy", "pref_label": "History / United States / State & Local / West (ak, Ca, Co, Hi, Id, Mt, Nv, Ut, Wy)",
"notation": "HIS036140", "notation": "HIS036140",
"alt_label": [] "alt_label": []
}, },
@ -10676,12 +10676,12 @@ bisac= {
"notation": "JNF006050", "notation": "JNF006050",
"alt_label": [] "alt_label": []
}, },
"Fiction / Anthologies (multiple Authors": { "Fiction / Anthologies (multiple Authors)": {
"related": [], "related": [],
"pref_label": "Fiction / Anthologies (multiple Authors", "pref_label": "Fiction / Anthologies (multiple Authors)",
"notation": "FIC003000", "notation": "FIC003000",
"alt_label": [ "alt_label": [
"Fiction / Short Stories (multiple Authors" "Fiction / Short Stories (multiple Authors)"
] ]
}, },
"Juvenile Nonfiction / Religion / General": { "Juvenile Nonfiction / Religion / General": {
@ -11249,9 +11249,9 @@ bisac= {
"notation": "POL051000", "notation": "POL051000",
"alt_label": [] "alt_label": []
}, },
"Juvenile Fiction / Historical / United States / Civil War Period (1850-1877": { "Juvenile Fiction / Historical / United States / Civil War Period (1850-1877)": {
"related": [], "related": [],
"pref_label": "Juvenile Fiction / Historical / United States / Civil War Period (1850-1877", "pref_label": "Juvenile Fiction / Historical / United States / Civil War Period (1850-1877)",
"notation": "JUV016200", "notation": "JUV016200",
"alt_label": [] "alt_label": []
}, },
@ -11625,9 +11625,9 @@ bisac= {
"notation": "ART025000", "notation": "ART025000",
"alt_label": [] "alt_label": []
}, },
"Gardening / Regional / Middle Atlantic (dc, De, Md, Nj, Ny, Pa": { "Gardening / Regional / Middle Atlantic (dc, De, Md, Nj, Ny, Pa)": {
"related": [], "related": [],
"pref_label": "Gardening / Regional / Middle Atlantic (dc, De, Md, Nj, Ny, Pa", "pref_label": "Gardening / Regional / Middle Atlantic (dc, De, Md, Nj, Ny, Pa)",
"notation": "GAR019020", "notation": "GAR019020",
"alt_label": [] "alt_label": []
}, },
@ -11744,9 +11744,9 @@ bisac= {
"notation": "NAT026000", "notation": "NAT026000",
"alt_label": [] "alt_label": []
}, },
"Gardening / Regional / Midwest (ia, Il, In, Ks, Mi, Mn, Mo, Nd, Ne, Oh, Sd, Wi": { "Gardening / Regional / Midwest (ia, Il, In, Ks, Mi, Mn, Mo, Nd, Ne, Oh, Sd, Wi)": {
"related": [], "related": [],
"pref_label": "Gardening / Regional / Midwest (ia, Il, In, Ks, Mi, Mn, Mo, Nd, Ne, Oh, Sd, Wi", "pref_label": "Gardening / Regional / Midwest (ia, Il, In, Ks, Mi, Mn, Mo, Nd, Ne, Oh, Sd, Wi)",
"notation": "GAR019030", "notation": "GAR019030",
"alt_label": [] "alt_label": []
}, },
@ -12066,9 +12066,9 @@ bisac= {
"notation": "JUV039110", "notation": "JUV039110",
"alt_label": [] "alt_label": []
}, },
"History / United States / State & Local / New England (ct, Ma, Me, Nh, Ri, Vt": { "History / United States / State & Local / New England (ct, Ma, Me, Nh, Ri, Vt)": {
"related": [], "related": [],
"pref_label": "History / United States / State & Local / New England (ct, Ma, Me, Nh, Ri, Vt", "pref_label": "History / United States / State & Local / New England (ct, Ma, Me, Nh, Ri, Vt)",
"notation": "HIS036100", "notation": "HIS036100",
"alt_label": [] "alt_label": []
}, },
@ -12104,9 +12104,9 @@ bisac= {
"Law / Study & Teaching" "Law / Study & Teaching"
] ]
}, },
"Foreign Language Study / Romance Languages (other": { "Foreign Language Study / Romance Languages (other)": {
"related": [], "related": [],
"pref_label": "Foreign Language Study / Romance Languages (other", "pref_label": "Foreign Language Study / Romance Languages (other)",
"notation": "FOR041000", "notation": "FOR041000",
"alt_label": [] "alt_label": []
}, },
@ -12562,9 +12562,9 @@ bisac= {
"notation": "BIB001020", "notation": "BIB001020",
"alt_label": [] "alt_label": []
}, },
"History / United States / State & Local / Southwest (az, Nm, Ok, Tx": { "History / United States / State & Local / Southwest (az, Nm, Ok, Tx)": {
"related": [], "related": [],
"pref_label": "History / United States / State & Local / Southwest (az, Nm, Ok, Tx", "pref_label": "History / United States / State & Local / Southwest (az, Nm, Ok, Tx)",
"notation": "HIS036130", "notation": "HIS036130",
"alt_label": [] "alt_label": []
}, },
@ -12654,9 +12654,9 @@ bisac= {
"notation": "HEA020000", "notation": "HEA020000",
"alt_label": [] "alt_label": []
}, },
"Study Aids / Ged (general Educational Development Tests": { "Study Aids / Ged (general Educational Development Tests)": {
"related": [], "related": [],
"pref_label": "Study Aids / Ged (general Educational Development Tests", "pref_label": "Study Aids / Ged (general Educational Development Tests)",
"notation": "STU012000", "notation": "STU012000",
"alt_label": [] "alt_label": []
}, },
@ -12834,9 +12834,9 @@ bisac= {
"notation": "CRA006000", "notation": "CRA006000",
"alt_label": [] "alt_label": []
}, },
"Body, Mind & Spirit / Parapsychology / Esp (clairvoyance, Precognition, Telepathy": { "Body, Mind & Spirit / Parapsychology / Esp (clairvoyance, Precognition, Telepathy)": {
"related": [], "related": [],
"pref_label": "Body, Mind & Spirit / Parapsychology / Esp (clairvoyance, Precognition, Telepathy", "pref_label": "Body, Mind & Spirit / Parapsychology / Esp (clairvoyance, Precognition, Telepathy)",
"notation": "OCC007000", "notation": "OCC007000",
"alt_label": [] "alt_label": []
}, },
@ -12884,9 +12884,9 @@ bisac= {
"Law / Immigration" "Law / Immigration"
] ]
}, },
"Travel / United States / South / South Atlantic (dc, De, Fl, Ga, Md, Nc, Sc, Va, Wv": { "Travel / United States / South / South Atlantic (dc, De, Fl, Ga, Md, Nc, Sc, Va, Wv)": {
"related": [], "related": [],
"pref_label": "Travel / United States / South / South Atlantic (dc, De, Fl, Ga, Md, Nc, Sc, Va, Wv", "pref_label": "Travel / United States / South / South Atlantic (dc, De, Fl, Ga, Md, Nc, Sc, Va, Wv)",
"notation": "TRV025090", "notation": "TRV025090",
"alt_label": [] "alt_label": []
}, },
@ -12959,7 +12959,7 @@ bisac= {
"alt_label": [ "alt_label": [
"Medical / Complementary Medicine", "Medical / Complementary Medicine",
"Medical / Iridology", "Medical / Iridology",
"Medical / Mind-body Medicine (psychoneuroimmunology" "Medical / Mind-body Medicine (psychoneuroimmunology)"
] ]
}, },
"Political Science / Censorship": { "Political Science / Censorship": {
@ -13028,9 +13028,9 @@ bisac= {
"notation": "JUV017010", "notation": "JUV017010",
"alt_label": [] "alt_label": []
}, },
"Art / History / Contemporary (1945-": { "Art / History / Contemporary (1945-)": {
"related": [], "related": [],
"pref_label": "Art / History / Contemporary (1945-", "pref_label": "Art / History / Contemporary (1945-)",
"notation": "ART015110", "notation": "ART015110",
"alt_label": [] "alt_label": []
}, },
@ -13967,9 +13967,9 @@ bisac= {
"notation": "BIB010050", "notation": "BIB010050",
"alt_label": [] "alt_label": []
}, },
"Travel / Europe / Benelux Countries (belgium, Netherlands, Luxembourg": { "Travel / Europe / Benelux Countries (belgium, Netherlands, Luxembourg)": {
"related": [], "related": [],
"pref_label": "Travel / Europe / Benelux Countries (belgium, Netherlands, Luxembourg", "pref_label": "Travel / Europe / Benelux Countries (belgium, Netherlands, Luxembourg)",
"notation": "TRV009020", "notation": "TRV009020",
"alt_label": [] "alt_label": []
}, },
@ -14415,9 +14415,9 @@ bisac= {
"notation": "JNF049130", "notation": "JNF049130",
"alt_label": [] "alt_label": []
}, },
"Study Aids / Nte (national Teacher Examinations": { "Study Aids / Nte (national Teacher Examinations)": {
"related": [], "related": [],
"pref_label": "Study Aids / Nte (national Teacher Examinations", "pref_label": "Study Aids / Nte (national Teacher Examinations)",
"notation": "STU019000", "notation": "STU019000",
"alt_label": [] "alt_label": []
}, },
@ -14444,9 +14444,9 @@ bisac= {
"notation": "ANT015000", "notation": "ANT015000",
"alt_label": [] "alt_label": []
}, },
"Study Aids / Lsat (law School Admission Test": { "Study Aids / Lsat (law School Admission Test)": {
"related": [], "related": [],
"pref_label": "Study Aids / Lsat (law School Admission Test", "pref_label": "Study Aids / Lsat (law School Admission Test)",
"notation": "STU017000", "notation": "STU017000",
"alt_label": [] "alt_label": []
}, },
@ -14630,9 +14630,9 @@ bisac= {
"notation": "FIC044000", "notation": "FIC044000",
"alt_label": [] "alt_label": []
}, },
"Travel / Canada / Western Provinces (ab, Bc": { "Travel / Canada / Western Provinces (ab, Bc)": {
"related": [], "related": [],
"pref_label": "Travel / Canada / Western Provinces (ab, Bc", "pref_label": "Travel / Canada / Western Provinces (ab, Bc)",
"notation": "TRV006050", "notation": "TRV006050",
"alt_label": [] "alt_label": []
}, },
@ -14937,9 +14937,9 @@ bisac= {
"Computers / Internet / Server Maintenance" "Computers / Internet / Server Maintenance"
] ]
}, },
"History / United States / Revolutionary Period (1775-1800": { "History / United States / Revolutionary Period (1775-1800)": {
"related": [], "related": [],
"pref_label": "History / United States / Revolutionary Period (1775-1800", "pref_label": "History / United States / Revolutionary Period (1775-1800)",
"notation": "HIS036030", "notation": "HIS036030",
"alt_label": [] "alt_label": []
}, },
@ -15047,9 +15047,9 @@ bisac= {
"notation": "TRV026050", "notation": "TRV026050",
"alt_label": [] "alt_label": []
}, },
"Fiction / Short Stories (single Author": { "Fiction / Short Stories (single Author)": {
"related": [], "related": [],
"pref_label": "Fiction / Short Stories (single Author", "pref_label": "Fiction / Short Stories (single Author)",
"notation": "FIC029000", "notation": "FIC029000",
"alt_label": [] "alt_label": []
}, },
@ -15535,9 +15535,9 @@ bisac= {
"notation": "GAM004030", "notation": "GAM004030",
"alt_label": [] "alt_label": []
}, },
"Juvenile Fiction / Historical / Canada / Post-confederation (1867-": { "Juvenile Fiction / Historical / Canada / Post-confederation (1867-)": {
"related": [], "related": [],
"pref_label": "Juvenile Fiction / Historical / Canada / Post-confederation (1867-", "pref_label": "Juvenile Fiction / Historical / Canada / Post-confederation (1867-)",
"notation": "JUV016180", "notation": "JUV016180",
"alt_label": [] "alt_label": []
}, },
@ -15583,9 +15583,9 @@ bisac= {
"notation": "ART029000", "notation": "ART029000",
"alt_label": [] "alt_label": []
}, },
"Study Aids / Clep (college-level Examination Program": { "Study Aids / Clep (college-level Examination Program)": {
"related": [], "related": [],
"pref_label": "Study Aids / Clep (college-level Examination Program", "pref_label": "Study Aids / Clep (college-level Examination Program)",
"notation": "STU008000", "notation": "STU008000",
"alt_label": [] "alt_label": []
}, },
@ -15701,9 +15701,9 @@ bisac= {
"notation": "CKB042000", "notation": "CKB042000",
"alt_label": [] "alt_label": []
}, },
"Political Science / Ngos (non-governmental Organizations": { "Political Science / Ngos (non-governmental Organizations)": {
"related": [], "related": [],
"pref_label": "Political Science / Ngos (non-governmental Organizations", "pref_label": "Political Science / Ngos (non-governmental Organizations)",
"notation": "POL041000", "notation": "POL041000",
"alt_label": [] "alt_label": []
}, },
@ -15898,9 +15898,9 @@ bisac= {
"notation": "PSY039000", "notation": "PSY039000",
"alt_label": [] "alt_label": []
}, },
"Gardening / Regional / New England (ct, Ma, Me, Nh, Ri, Vt": { "Gardening / Regional / New England (ct, Ma, Me, Nh, Ri, Vt)": {
"related": [], "related": [],
"pref_label": "Gardening / Regional / New England (ct, Ma, Me, Nh, Ri, Vt", "pref_label": "Gardening / Regional / New England (ct, Ma, Me, Nh, Ri, Vt)",
"notation": "GAR019040", "notation": "GAR019040",
"alt_label": [] "alt_label": []
}, },
@ -16080,9 +16080,9 @@ bisac= {
"notation": "JNF038110", "notation": "JNF038110",
"alt_label": [] "alt_label": []
}, },
"Social Science / Black Studies (global": { "Social Science / Black Studies (global)": {
"related": [], "related": [],
"pref_label": "Social Science / Black Studies (global", "pref_label": "Social Science / Black Studies (global)",
"notation": "SOC056000", "notation": "SOC056000",
"alt_label": [] "alt_label": []
}, },
@ -16640,9 +16640,9 @@ bisac= {
"notation": "CGN004180", "notation": "CGN004180",
"alt_label": [] "alt_label": []
}, },
"Art / History / Modern (late 19th Century To 1945": { "Art / History / Modern (late 19th Century To 1945)": {
"related": [], "related": [],
"pref_label": "Art / History / Modern (late 19th Century To 1945", "pref_label": "Art / History / Modern (late 19th Century To 1945)",
"notation": "ART015100", "notation": "ART015100",
"alt_label": [] "alt_label": []
}, },
@ -16682,9 +16682,9 @@ bisac= {
"notation": "FOR030000", "notation": "FOR030000",
"alt_label": [] "alt_label": []
}, },
"Poetry / Anthologies (multiple Authors": { "Poetry / Anthologies (multiple Authors)": {
"related": [], "related": [],
"pref_label": "Poetry / Anthologies (multiple Authors", "pref_label": "Poetry / Anthologies (multiple Authors)",
"notation": "POE001000", "notation": "POE001000",
"alt_label": [] "alt_label": []
}, },
@ -17618,9 +17618,9 @@ bisac= {
"notation": "HEA042000", "notation": "HEA042000",
"alt_label": [] "alt_label": []
}, },
"Business & Economics / Accounting / Standards (gaap, Ifrs, Etc.": { "Business & Economics / Accounting / Standards (gaap, Ifrs, Etc.)": {
"related": [], "related": [],
"pref_label": "Business & Economics / Accounting / Standards (gaap, Ifrs, Etc.", "pref_label": "Business & Economics / Accounting / Standards (gaap, Ifrs, Etc.)",
"notation": "BUS001050", "notation": "BUS001050",
"alt_label": [] "alt_label": []
}, },
@ -18906,9 +18906,9 @@ bisac= {
"notation": "LCO008000", "notation": "LCO008000",
"alt_label": [] "alt_label": []
}, },
"Architecture / History / Contemporary (1945-": { "Architecture / History / Contemporary (1945-)": {
"related": [], "related": [],
"pref_label": "Architecture / History / Contemporary (1945-", "pref_label": "Architecture / History / Contemporary (1945-)",
"notation": "ARC005080", "notation": "ARC005080",
"alt_label": [] "alt_label": []
}, },
@ -18954,9 +18954,9 @@ bisac= {
"notation": "HIS036000", "notation": "HIS036000",
"alt_label": [] "alt_label": []
}, },
"Family & Relationships / Attention Deficit Disorder (add-adhd": { "Family & Relationships / Attention Deficit Disorder (add-adhd)": {
"related": [], "related": [],
"pref_label": "Family & Relationships / Attention Deficit Disorder (add-adhd", "pref_label": "Family & Relationships / Attention Deficit Disorder (add-adhd)",
"notation": "FAM047000", "notation": "FAM047000",
"alt_label": [] "alt_label": []
}, },
@ -19370,9 +19370,9 @@ bisac= {
"notation": "MED020000", "notation": "MED020000",
"alt_label": [] "alt_label": []
}, },
"History / United States / State & Local / Midwest (ia, Il, In, Ks, Mi, Mn, Mo, Nd, Ne, Oh, Sd, Wi": { "History / United States / State & Local / Midwest (ia, Il, In, Ks, Mi, Mn, Mo, Nd, Ne, Oh, Sd, Wi)": {
"related": [], "related": [],
"pref_label": "History / United States / State & Local / Midwest (ia, Il, In, Ks, Mi, Mn, Mo, Nd, Ne, Oh, Sd, Wi", "pref_label": "History / United States / State & Local / Midwest (ia, Il, In, Ks, Mi, Mn, Mo, Nd, Ne, Oh, Sd, Wi)",
"notation": "HIS036090", "notation": "HIS036090",
"alt_label": [] "alt_label": []
}, },
@ -19436,9 +19436,9 @@ bisac= {
"notation": "JNF019010", "notation": "JNF019010",
"alt_label": [] "alt_label": []
}, },
"Travel / Canada / Ontario (on": { "Travel / Canada / Ontario (on)": {
"related": [], "related": [],
"pref_label": "Travel / Canada / Ontario (on", "pref_label": "Travel / Canada / Ontario (on)",
"notation": "TRV006020", "notation": "TRV006020",
"alt_label": [] "alt_label": []
}, },
@ -19622,9 +19622,9 @@ bisac= {
"notation": "SOC042000", "notation": "SOC042000",
"alt_label": [] "alt_label": []
}, },
"Study Aids / Cpa (certified Public Accountant": { "Study Aids / Cpa (certified Public Accountant)": {
"related": [], "related": [],
"pref_label": "Study Aids / Cpa (certified Public Accountant", "pref_label": "Study Aids / Cpa (certified Public Accountant)",
"notation": "STU011000", "notation": "STU011000",
"alt_label": [] "alt_label": []
}, },
@ -19920,7 +19920,7 @@ bisac= {
"pref_label": "Architecture / Design, Drafting, Drawing & Presentation", "pref_label": "Architecture / Design, Drafting, Drawing & Presentation",
"notation": "ARC004000", "notation": "ARC004000",
"alt_label": [ "alt_label": [
"Architecture / Cad (computer Aided Design" "Architecture / Cad (computer Aided Design)"
] ]
}, },
"Juvenile Fiction / People & Places / Canada / General": { "Juvenile Fiction / People & Places / Canada / General": {
@ -21368,9 +21368,9 @@ bisac= {
"notation": "GAM005000", "notation": "GAM005000",
"alt_label": [] "alt_label": []
}, },
"Architecture / History / Modern (late 19th Century To 1945": { "Architecture / History / Modern (late 19th Century To 1945)": {
"related": [], "related": [],
"pref_label": "Architecture / History / Modern (late 19th Century To 1945", "pref_label": "Architecture / History / Modern (late 19th Century To 1945)",
"notation": "ARC005070", "notation": "ARC005070",
"alt_label": [] "alt_label": []
}, },
@ -21848,9 +21848,9 @@ bisac= {
"notation": "COM010000", "notation": "COM010000",
"alt_label": [] "alt_label": []
}, },
"Technology & Engineering / Engineering (general": { "Technology & Engineering / Engineering (general)": {
"related": [], "related": [],
"pref_label": "Technology & Engineering / Engineering (general", "pref_label": "Technology & Engineering / Engineering (general)",
"notation": "TEC009000", "notation": "TEC009000",
"alt_label": [] "alt_label": []
}, },
@ -22468,9 +22468,9 @@ bisac= {
"notation": "PSY012000", "notation": "PSY012000",
"alt_label": [] "alt_label": []
}, },
"Drama / Anthologies (multiple Authors": { "Drama / Anthologies (multiple Authors)": {
"related": [], "related": [],
"pref_label": "Drama / Anthologies (multiple Authors", "pref_label": "Drama / Anthologies (multiple Authors)",
"notation": "DRA002000", "notation": "DRA002000",
"alt_label": [] "alt_label": []
}, },
@ -22725,9 +22725,9 @@ bisac= {
"notation": "JUV041040", "notation": "JUV041040",
"alt_label": [] "alt_label": []
}, },
"History / United States / State & Local / Pacific Northwest (or, Wa": { "History / United States / State & Local / Pacific Northwest (or, Wa)": {
"related": [], "related": [],
"pref_label": "History / United States / State & Local / Pacific Northwest (or, Wa", "pref_label": "History / United States / State & Local / Pacific Northwest (or, Wa)",
"notation": "HIS036110", "notation": "HIS036110",
"alt_label": [] "alt_label": []
}, },
@ -22749,9 +22749,9 @@ bisac= {
"notation": "JUV030120", "notation": "JUV030120",
"alt_label": [] "alt_label": []
}, },
"Travel / United States / Midwest / East North Central (il, In, Mi, Oh, Wi": { "Travel / United States / Midwest / East North Central (il, In, Mi, Oh, Wi)": {
"related": [], "related": [],
"pref_label": "Travel / United States / Midwest / East North Central (il, In, Mi, Oh, Wi", "pref_label": "Travel / United States / Midwest / East North Central (il, In, Mi, Oh, Wi)",
"notation": "TRV025020", "notation": "TRV025020",
"alt_label": [] "alt_label": []
}, },
@ -22845,9 +22845,9 @@ bisac= {
"notation": "LIT004290", "notation": "LIT004290",
"alt_label": [] "alt_label": []
}, },
"Travel / Canada / Prairie Provinces (mb, Sk": { "Travel / Canada / Prairie Provinces (mb, Sk)": {
"related": [], "related": [],
"pref_label": "Travel / Canada / Prairie Provinces (mb, Sk", "pref_label": "Travel / Canada / Prairie Provinces (mb, Sk)",
"notation": "TRV006030", "notation": "TRV006030",
"alt_label": [] "alt_label": []
}, },

View File

View File

View File

@ -0,0 +1,12 @@
import string
from django.core.management.base import BaseCommand
from regluit.bisac.models import populate_bisac_headings,attach_dangling_branches
class Command(BaseCommand):
help = "build the bisac heading db"
def handle(self, **options):
populate_bisac_headings()
attach_dangling_branches()
print "bisac table is ready"

View File

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'BisacHeading'
db.create_table('bisac_bisacheading', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('full_label', self.gf('django.db.models.fields.CharField')(unique=True, max_length=100)),
('label', self.gf('django.db.models.fields.CharField')(max_length=60)),
('notation', self.gf('django.db.models.fields.CharField')(max_length=9)),
('parent', self.gf('mptt.fields.TreeForeignKey')(blank=True, related_name='children', null=True, to=orm['bisac.BisacHeading'])),
(u'lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
))
db.send_create_signal('bisac', ['BisacHeading'])
def backwards(self, orm):
# Deleting model 'BisacHeading'
db.delete_table('bisac_bisacheading')
models = {
'bisac.bisacheading': {
'Meta': {'object_name': 'BisacHeading'},
'full_label': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'label': ('django.db.models.fields.CharField', [], {'max_length': '60'}),
u'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
u'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'notation': ('django.db.models.fields.CharField', [], {'max_length': '9'}),
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['bisac.BisacHeading']"}),
u'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
u'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
}
}
complete_apps = ['bisac']

View File

39
bisac/models.py Normal file
View File

@ -0,0 +1,39 @@
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
from . import bisac
class BisacHeading(MPTTModel):
full_label = models.CharField(max_length=100, unique=True)
label = models.CharField(max_length=60, unique=False)
notation = models.CharField(max_length=9, unique=False)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)
class MPTTMeta:
order_insertion_by = ['notation']
def __unicode__(self):
return self.full_label
def populate_bisac_headings():
for key in bisac.keys():
full_label = key[0:-10] if key.endswith(' / General') else key
(heading, created)= BisacHeading.objects.get_or_create(full_label = full_label)
cats = full_label.split('/')
heading.label = cats[-1].strip()
heading.notation = bisac[key]['notation']
if len(cats)>1:
parent_label = '/'.join(cats[0:-1]).strip()
(heading.parent, created) = BisacHeading.objects.get_or_create(full_label = parent_label)
heading.save()
def attach_dangling_branches():
# there was no "General" heading to link to
for heading in BisacHeading.objects.filter(notation = "", parent = None):
cats = heading.full_label.split('/')
heading.label = cats[-1].strip()
if len(cats)>1:
parent_label = '/'.join(cats[0:-1]).strip()
(heading.parent, created) = BisacHeading.objects.get_or_create(full_label = parent_label)
heading.save()

5
bisac/urls.py Normal file
View File

@ -0,0 +1,5 @@
from django.conf.urls.defaults import *
urlpatterns = patterns("",
url(r"^tree$", "regluit.bisac.views.tree"),
)

29
bisac/views.py Normal file
View File

@ -0,0 +1,29 @@
import json
from django.template import Context, Template
from django.http import HttpResponse
from mptt.templatetags.mptt_tags import cache_tree_children
from regluit.bisac.models import BisacHeading
nodes = BisacHeading.objects.all()
def recursive_node_to_dict(node):
result = {
'title': node.full_label,
'key': node.pk,
}
children = [recursive_node_to_dict(c) for c in node.get_children()]
if children:
result['children'] = children
result['folder'] = True
return result
root_nodes = cache_tree_children(nodes)
dicts = []
for n in root_nodes:
dicts.append(recursive_node_to_dict(n))
def tree(request):
return HttpResponse(json.dumps(dicts, indent=4), content_type="application/json")

View File

@ -788,7 +788,7 @@ def add_missing_isbn_to_editions(max_num=None, confirm=False):
class LookupFailure(Exception): class LookupFailure(Exception):
pass pass
IDTABLE = [('librarything','ltwk'),('goodreads','gdrd'),('openlibrary','olwk'),('gutenberg','gtbg'),('isbn','isbn'),('oclc','oclc'), ] IDTABLE = [('librarything','ltwk'),('goodreads','gdrd'),('openlibrary','olwk'),('gutenberg','gtbg'),('isbn','isbn'),('oclc','oclc'),('edition_id','edid') ]
def unreverse(name): def unreverse(name):
if not ',' in name: if not ',' in name:
@ -801,77 +801,83 @@ def unreverse(name):
def load_from_yaml(yaml_url): def load_from_yaml(yaml_url):
metadata = Pandata(yaml_url) all_metadata = Pandata(yaml_url)
#find an work to associate for metadata in all_metadata.get_edition_list():
work = edition = None #find an work to associate
if metadata.url: work = edition = None
new_ids = [('http','http', metadata.url)] if metadata.url:
else: new_ids = [('http','http', metadata.url)]
new_ids = []
for (identifier, id_code) in IDTABLE:
value = metadata.identifiers.get(identifier,None)
if value:
value = value[0] if isinstance(value, list) else value
try:
id = models.Identifier.objects.get(type=id_code, value=value)
work = id.work
if id.edition and not edition:
edition = id.edition
except models.Identifier.DoesNotExist:
new_ids.append((identifier, id_code, value))
if not work:
work = models.Work.objects.create(title=metadata.title, language=metadata.language)
if not edition:
edition = models.Edition.objects.create(title=metadata.title, work=work)
for (identifier, id_code, value) in new_ids:
models.Identifier.set(type=id_code, value=value, edition=edition if id_code in ('isbn', 'oclc') else None, work=work)
if metadata.publisher: #always believe yaml
edition.set_publisher(metadata.publisher)
if metadata.publication_date: #always believe yaml
edition.publication_date = metadata.publication_date
if metadata.description and len(metadata.description)>len(work.description): #be careful about overwriting the work description
work.description = metadata.description
if metadata.creator: #always believe yaml
edition.authors.clear()
for key in metadata.creator.keys():
creators=metadata.creator[key]
rel_code=inverse_marc_rels.get(key,'aut')
creators = creators if isinstance(creators,list) else [creators]
for creator in creators:
edition.add_author(unreverse(creator.get('agent_name','')),relation=rel_code)
for yaml_subject in metadata.subjects: #always add yaml subjects (don't clear)
if isinstance(yaml_subject, tuple):
(authority, heading) = yaml_subject
elif isinstance(yaml_subject, str):
(authority, heading) = ( '', yaml_subject)
else: else:
continue new_ids = []
(subject, created) = models.Subject.objects.get_or_create(name=heading) for (identifier, id_code) in IDTABLE:
if not subject.authority and authority: # note that the work chosen is the last associated
subject.authority = authority value = metadata.edition_identifiers.get(identifier,None)
subject.save() if not value:
subject.works.add(work) value = metadata.identifiers.get(identifier,None)
# the default edition uses the first cover in covers. if value:
for cover in metadata.covers: value = value[0] if isinstance(value, list) else value
if cover.get('image_path', False): try:
edition.cover_image=urljoin(yaml_url,cover['image_path']) id = models.Identifier.objects.get(type=id_code, value=value)
break work = id.work
edition.save() if id.edition and not edition:
# if there is a version, assume there is an ebook. if not, not. edition = id.edition
if metadata._version and not metadata._version.startswith('0.0.'): except models.Identifier.DoesNotExist:
#there should be an ebook to link to! new_ids.append((identifier, id_code, value))
try:
ebook= models.Ebook.objects.create(
url=git_download_from_yaml_url(yaml_url,metadata._version,edition_name=metadata._edition ), if not work:
provider='Github', work = models.Work.objects.create(title=metadata.title, language=metadata.language)
rights = metadata.rights if metadata.rights in cc.LICENSE_LIST_ALL else None, if not edition:
format = 'epub', edition = models.Edition.objects.create(title=metadata.title, work=work)
edition = edition, for (identifier, id_code, value) in new_ids:
# version = metadata._version models.Identifier.set(type=id_code, value=value, edition=edition if id_code in ('isbn', 'oclc','edid') else None, work=work)
) if metadata.publisher: #always believe yaml
except IntegrityError: edition.set_publisher(metadata.publisher)
#duplicate url or url isn't a master if metadata.publication_date: #always believe yaml
pass edition.publication_date = metadata.publication_date
if metadata.description and len(metadata.description)>len(work.description): #be careful about overwriting the work description
work.description = metadata.description
if metadata.creator: #always believe yaml
edition.authors.clear()
for key in metadata.creator.keys():
creators=metadata.creator[key]
rel_code=inverse_marc_rels.get(key,'aut')
creators = creators if isinstance(creators,list) else [creators]
for creator in creators:
edition.add_author(unreverse(creator.get('agent_name','')),relation=rel_code)
for yaml_subject in metadata.subjects: #always add yaml subjects (don't clear)
if isinstance(yaml_subject, tuple):
(authority, heading) = yaml_subject
elif isinstance(yaml_subject, str):
(authority, heading) = ( '', yaml_subject)
else:
continue
(subject, created) = models.Subject.objects.get_or_create(name=heading)
if not subject.authority and authority:
subject.authority = authority
subject.save()
subject.works.add(work)
# the default edition uses the first cover in covers.
for cover in metadata.covers:
if cover.get('image_path', False):
edition.cover_image=urljoin(yaml_url,cover['image_path'])
break
edition.save()
# if there is a version, assume there is an ebook. if not, not.
if metadata._version and not metadata._version.startswith('0.0.'):
#there should be an ebook to link to!
try:
ebook= models.Ebook.objects.create(
url=git_download_from_yaml_url(yaml_url,metadata._version,edition_name=metadata._edition ),
provider='Github',
rights = metadata.rights if metadata.rights in cc.LICENSE_LIST_ALL else None,
format = 'epub',
edition = edition,
# version = metadata._version
)
except IntegrityError:
#duplicate url or url isn't a master
pass
return work.id return work.id
def git_download_from_yaml_url(yaml_url, version, edition_name='book'): def git_download_from_yaml_url(yaml_url, version, edition_name='book'):

View File

@ -0,0 +1,17 @@
import string
from django.core.management.base import BaseCommand
from regluit.bisac.models import BisacHeading
from regluit.core.models import Subject
class Command(BaseCommand):
help = "add and convert existing subjects to Bisac"
def handle(self, **options):
matches=0
for bisac_heading in BisacHeading.objects.all():
for subject in Subject.objects.filter(name=bisac_heading.full_label):
subject.authority='bisacsh'
subject.name = bisac_heading.full_label
subject.save()
matches += 1
print "%s bisac headings converted" % matches

View File

@ -84,7 +84,7 @@ class BookLoaderTests(TestCase):
self.assertEqual( noebook.first_ebook(), None) self.assertEqual( noebook.first_ebook(), None)
huck_id = bookloader.load_from_yaml(YAML_HUCKFILE) huck_id = bookloader.load_from_yaml(YAML_HUCKFILE)
huck = models.Work.objects.get(id=huck_id) huck = models.Work.objects.get(id=huck_id)
self.assertEqual( huck.first_ebook().rights, "CC BY-NC") self.assertTrue( huck.ebooks().count()>1)
def test_add_by_yaml(self): def test_add_by_yaml(self):
space_id = bookloader.load_from_yaml('https://github.com/gitenberg-dev/metadata/raw/master/samples/pandata.yaml') space_id = bookloader.load_from_yaml('https://github.com/gitenberg-dev/metadata/raw/master/samples/pandata.yaml')

View File

@ -69,6 +69,7 @@ from regluit.utils.localdatetime import now
from regluit.utils.fields import EpubFileField, ISBNField from regluit.utils.fields import EpubFileField, ISBNField
from regluit.mobi import Mobi from regluit.mobi import Mobi
from regluit.pyepub import EPUB from regluit.pyepub import EPUB
from regluit.bisac.models import BisacHeading
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
nulls = [False, 'delete', ''] nulls = [False, 'delete', '']
@ -78,10 +79,21 @@ CREATOR_RELATIONS = (
('trl', 'Translator'), ('trl', 'Translator'),
('ill', 'Illustrator'), ('ill', 'Illustrator'),
) )
bisac_headings = BisacHeading.objects.all()
class EditionForm(forms.ModelForm): class EditionForm(forms.ModelForm):
add_author = forms.CharField(max_length=500, required=False) add_author = forms.CharField(max_length=500, required=False)
add_author_relation = forms.ChoiceField(choices=CREATOR_RELATIONS, initial=('aut', 'Author')) add_author_relation = forms.ChoiceField(choices=CREATOR_RELATIONS, initial=('aut', 'Author'))
add_subject = forms.CharField(max_length=200, required=False) add_subject = AutoCompleteSelectField(
SubjectLookup,
widget=AutoCompleteSelectWidget(SubjectLookup,allow_new=True),
label='Keyword',
required =False
)
bisac = forms.ModelChoiceField( bisac_headings, required=False )
publisher_name = AutoCompleteSelectField( publisher_name = AutoCompleteSelectField(
PublisherNameLookup, PublisherNameLookup,
label='Publisher Name', label='Publisher Name',
@ -150,7 +162,7 @@ class EditionForm(forms.ModelForm):
} }
) )
language = forms.ChoiceField(choices=LANGUAGES) language = forms.ChoiceField(choices=LANGUAGES)
description = forms.CharField( required=False, widget= forms.Textarea(attrs={'cols': 80, 'rows': 10})) description = forms.CharField( required=False, widget=CKEditorWidget())
coverfile = forms.ImageField(required=False) coverfile = forms.ImageField(required=False)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):

View File

@ -16,7 +16,7 @@
<div class="pressimages"> <div class="pressimages">
<div class="outer"> <div class="outer">
<div><img src="/static/images/headshots/eric.jpg" class="mediaborder" alt="eric" /></div> <div><img src="/static/images/headshots/eric.jpg" class="mediaborder" alt="eric" /></div>
<div class="text"><b>Eric Hellman</b>, President of Gluejar, is a technologist, entrepreneur, and writer. After 10 years at Bell Labs in physics research, Eric became interested in technologies surrounding e-journals and libraries. His first business, Openly Informatics, developed OpenURL linking software and knowledgebases, and was acquired by OCLC in 1996. At OCLC, he led the effort to productize and expand the xISBN service, and began the development of OCLC's Electronic Resource Management offerings. After leaving OCLC, Eric began blogging at <a href="http://go-to-hellman.blogspot.com">Go To Hellman</a>. He covers the intersection of technology, libraries and ebooks, and has written extensively on the Semantic Web and Linked Data. Eric has a B.S.E. from Princeton University, and a Ph. D. in Electrical Engineering from Stanford University</div> <div class="text"><b>Eric Hellman</b>, President of Gluejar, is a technologist, entrepreneur, and writer. After 10 years at Bell Labs in physics research, Eric became interested in technologies surrounding e-journals and libraries. His first business, Openly Informatics, developed OpenURL linking software and knowledgebases, and was acquired by OCLC in 1996. At OCLC, he led the effort to productize and expand the xISBN service, and began the development of OCLC's Electronic Resource Management offerings. After leaving OCLC, Eric began blogging at <a href="https://go-to-hellman.blogspot.com">Go To Hellman</a>. He covers the intersection of technology, libraries and ebooks, and has written extensively on the Semantic Web and Linked Data. Eric has a B.S.E. from Princeton University, and a Ph. D. in Electrical Engineering from Stanford University</div>
</div> </div>
<div class="outer"> <div class="outer">

View File

@ -33,12 +33,13 @@
{% endif %} {% endif %}
{% if not managing %} {% if not managing %}
{% if user.is_staff %} {% if user.is_staff %}
<a href="{% url 'new_edition' work_id edition.id %}">Edit this edition/Add ebook link</a><br /> <a href="{% url 'new_edition' work_id edition.id %}">Edit this edition</a><br />
{% else %}{% if user in work.last_campaign.managers.all %} {% else %}{% if user in work.last_campaign.managers.all %}
<a href="{% url 'new_edition' work_id edition.id %}">Edit this edition/Add ebook link</a><br /> <a href="{% url 'new_edition' work_id edition.id %}">Edit this edition</a><br />
{% else %}{% if user.is_authenticated %} {% endif %}{% endif %}
<a href="{% url 'new_edition' work_id edition.id %}">Add ebook link</a><br /> {% if user.is_authenticated %}
{% endif %}{% endif %}{% endif %} <a href="{% url 'manage_ebooks' edition.id %}">Add ebook link</a><br />
{% endif %}
{% if edition.googlebooks_id %} {% if edition.googlebooks_id %}
See <a href="https://encrypted.google.com/books?id={{ edition.googlebooks_id }}">this edition on Google Books</a><br /> See <a href="https://encrypted.google.com/books?id={{ edition.googlebooks_id }}">this edition on Google Books</a><br />
{% endif %} {% endif %}

View File

@ -49,8 +49,8 @@
<span class="menu level2 answer"> <span class="menu level2 answer">
Funny you should ask. We've told the agonizing story about our search for a payment provider in a series of blog posts. <ul><li> <a href="http://blog.unglue.it/2012/05/03/unglue-it-payment-options-amazon-vs-paypal/">Forget Paypal!</a></li> Funny you should ask. We've told the agonizing story about our search for a payment provider in a series of blog posts. <ul><li> <a href="http://blog.unglue.it/2012/05/03/unglue-it-payment-options-amazon-vs-paypal/">Forget Paypal!</a></li>
<li><a href="http://blog.unglue.it/2012/08/09/open-thread-amazon-forces-unglue-it-to-suspend-crowdfunding-for-creative-commons-ebooks/">Noooooo!</a></li> <li><a href="http://blog.unglue.it/2012/08/09/open-thread-amazon-forces-unglue-it-to-suspend-crowdfunding-for-creative-commons-ebooks/">Noooooo!</a></li>
<li><a href="http://go-to-hellman.blogspot.com/2012/08/why-im-not-mad-at-amazon.html">Forget Amazon!</a></li> <li><a href="https://go-to-hellman.blogspot.com/2012/08/why-im-not-mad-at-amazon.html">Forget Amazon!</a></li>
<li><a href="http://go-to-hellman.blogspot.com/2012/09/stripe-balanced-wepay-for-payments-not.html">Silver Lining</a></li> <li><a href="https://go-to-hellman.blogspot.com/2012/09/stripe-balanced-wepay-for-payments-not.html">Silver Lining</a></li>
<li><a href="http://blog.unglue.it/2012/10/17/weve-relaunched/">Yay, Stripe!</a></li></ul> <li><a href="http://blog.unglue.it/2012/10/17/weve-relaunched/">Yay, Stripe!</a></li></ul>
</span> </span>

View File

@ -69,8 +69,8 @@
<span class="menu level2 answer"> <span class="menu level2 answer">
Funny you should ask. We've told the agonizing story about our search for a payment provider in a series of blog posts. <ul><li> <a href="http://blog.unglue.it/2012/05/03/unglue-it-payment-options-amazon-vs-paypal/">Forget Paypal!</a></li> Funny you should ask. We've told the agonizing story about our search for a payment provider in a series of blog posts. <ul><li> <a href="http://blog.unglue.it/2012/05/03/unglue-it-payment-options-amazon-vs-paypal/">Forget Paypal!</a></li>
<li><a href="http://blog.unglue.it/2012/08/09/open-thread-amazon-forces-unglue-it-to-suspend-crowdfunding-for-creative-commons-ebooks/">Noooooo!</a></li> <li><a href="http://blog.unglue.it/2012/08/09/open-thread-amazon-forces-unglue-it-to-suspend-crowdfunding-for-creative-commons-ebooks/">Noooooo!</a></li>
<li><a href="http://go-to-hellman.blogspot.com/2012/08/why-im-not-mad-at-amazon.html">Forget Amazon!</a></li> <li><a href="https://go-to-hellman.blogspot.com/2012/08/why-im-not-mad-at-amazon.html">Forget Amazon!</a></li>
<li><a href="http://go-to-hellman.blogspot.com/2012/09/stripe-balanced-wepay-for-payments-not.html">Silver Lining</a></li> <li><a href="https://go-to-hellman.blogspot.com/2012/09/stripe-balanced-wepay-for-payments-not.html">Silver Lining</a></li>
<li><a href="http://blog.unglue.it/2012/10/17/weve-relaunched/">Yay, Stripe!</a></li></ul> <li><a href="http://blog.unglue.it/2012/10/17/weve-relaunched/">Yay, Stripe!</a></li></ul>
</span> </span>

View File

@ -0,0 +1,41 @@
{% extends 'basedocumentation.html' %}
{% load url from future %}
{% block extra_extra_head %}
{{ block.super }}
<link rel="stylesheet" href="/static/css/ui-lightness/jquery-ui-1.8.16.custom.css" type="text/css" media="screen">
<script type="text/javascript" src="{{ jquery_ui_home }}" ></script>
{% endblock %}
{% block doccontent %}
<h2>Add Ebook Links for <a href="{% url 'work' edition.work.id %}">{{ edition.work }}</a></h2>
{% if edition.publisher %}
Publisher: <a href="{% url 'bypubname_list' edition.publisher_name.id %}">{{edition.publisher}}</a><br />
{% endif %}
{% if edition.publication_date %}
Published: {{ edition.publication_date }}<br />
{% endif %}
{% if edition.isbn_13 %}
ISBN: <span itemprop="isbn">{{ edition.isbn_13 }}</span><br />
{% endif %}
{% if edition.oclc %}
OCLC: <a href="http://www.worldcat.org/oclc/{{ edition.oclc }}">{{ edition.oclc }}</a><br />
{% endif %}
{% include 'edition_upload.html' %}
{% if request.user.is_staff %}
<h2>More Edition Management</h2>
<div><a href="{% url 'merge' edition.work.id %}">Merge other works into this one</a></div>
<div><a href="{% url 'work_editions' edition.work.id %}">Remove editions from this work</a></div>
<div><a href="{% url 'feature' edition.work.id %}">Feature this work today</a></div>
<div><a href="{% url 'new_edition' edition.work.id edition.id %}">Edit the edition</a></div>
{% endif %}
<br />
{% endblock %}

View File

@ -3,9 +3,84 @@
{% block extra_extra_head %} {% block extra_extra_head %}
{{ block.super }} {{ block.super }}
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/themes/ui-lightness/jquery-ui.css" type="text/css" media="screen"> <link rel="stylesheet" href="/static/css/ui-lightness/jquery-ui-1.8.16.custom.css" type="text/css" media="screen">
<link href="/static/css/ui.fancytree.min.css" rel="stylesheet" type="text/css">
<style type="text/css">
ul.fancytree-container {
width: 100%;
height: 10em;
overflow: auto;
position: relative;
margin-top: 0.5em;
}
</style>
{{ form.media.css }} {{ form.media.css }}
<script type="text/javascript" src="{{ jquery_ui_home }}" ></script> <script type="text/javascript" src="{{ jquery_ui_home }}" ></script>
<script src="/static/js/jquery.fancytree-all.min.js" type="text/javascript"></script>
<script type="text/javascript">
$j(function(){
// Initialize Fancytree
$j("#tree").fancytree({
extensions: ["glyph"],
checkbox: true,
selectMode: 1,
glyph: {
map: {
doc: "fa fa-file-o",
docOpen: "fa fa-file-o",
checkbox: "fa fa-square-o",
checkboxSelected: "fa fa-check-square-o",
checkboxUnknown: "fa fa-square",
dragHelper: "fa arrow-right",
dropMarker: "fa long-arrow-right",
error: "fa fa-warning",
expanderClosed: "fa fa-caret-right",
expanderLazy: "fa fa-angle-right",
expanderOpen: "fa fa-caret-down",
folder: "fa fa-folder-o",
folderOpen: "fa fa-folder-open-o",
loading: "fa fa-spinner fa-pulse"
}
},
source: { url: "/bisac/tree", cache: true }
});
$j("#editform").submit(function() {
// Render hidden <input> elements for active and selected nodes
$j("#tree").fancytree("getTree").generateFormElements(selected="bisac");
//alert("POST data:\n" + $j.param($j(this).serializeArray()));
return true;
});
$j().ready(function(){
var contentblock = $j('#content-block');
contentblock.on("click", "span.deletebutton", function () {
var kw = $j(this).attr('data');
var li = $j(this).parent();
// perform action
{% if edition.work %}
jQuery.post('{% url 'kw_edit' edition.work.id %}', {'remove_kw': kw, 'csrfmiddlewaretoken': '{{ csrf_token }}' }, function(data) {
li.html('kw removed');
});
{% else %}
li.html('kw removed');
{% endif %}
});
// this is the id of the submit button
$j('#add_subject_submit').click(function(event) {
data= $j('#id_add_subject_0').attr('value')
if (data == 'xxbadform'){
alert("bad keyword");
} else {
$j('#kw_list').append('<li>' + data + '<input type="hidden" name="new_subject" value="'+data +'" /><span class="deletebutton" data="' + data +'">x</span></li>')
}; // data will be the added kw.
});
});
});
</script>
{{ form.media.js }} {{ form.media.js }}
{% endblock %} {% endblock %}
@ -25,7 +100,7 @@
{% if admin %} {% if admin %}
<p>Title and ISBN 13 are required; the rest is optional, though a cover image is strongly recommended.</p> <p>Title and ISBN 13 are required; the rest is optional, though a cover image is strongly recommended.</p>
<form enctype="multipart/form-data" method="POST" action="#"> <form id="editform" enctype="multipart/form-data" method="POST" action="#">
{% csrf_token %} {% csrf_token %}
{{ form.work }} {{ form.work }}
{{ form.non_field_errors }} {{ form.non_field_errors }}
@ -77,24 +152,28 @@
{% endif %} {% endif %}
</i>)</p> </i>)</p>
<p><b>Publication Date</b> (<I>four-digit year</I>): {{ form.publication_date.errors }}{{ form.publication_date }}</p> <p><b>Publication Date</b> (<I>four-digit year</I>): {{ form.publication_date.errors }}{{ form.publication_date }}</p>
{% comment %}
this has been removed since there's no point in exposing subject functionality when we're not doing anything with it -- will just confuse people.
<p><b>Subjects</b>: <p><b>Subjects</b>:
<ul> <ul id="kw_list">
{% if edition.work.pk and edition.work.subjects %} {% if edition.work.pk and edition.work.subjects %}
{% for subject in edition.work.subjects.all %} {% for subject in edition.work.subjects.all %}
<li>{{ subject.name }}</li> <li>{{ subject.name }}
{% if subject.authority %}
({{subject.authority}})
{% endif %}
<span class="deletebutton" data="{{ subject.name }}">x</span></li>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% for new_subject in edition.new_subjects %} {% for new_subject in edition.new_subjects %}
<li>{{ new_subject }}<input type="hidden" name="new_subject" value="{{ new_subject }}" /></li> <li>{{ new_subject }}<input type="hidden" name="new_subject" value="{{ new_subject }}" /></li>
{% endfor %} {% endfor %}
</ul> </ul>
<b>Add a Subject</b>: {{ form.add_subject.errors }}{{ form.add_subject }} <b>Add a Subject</b>: {{ form.add_subject.errors }}{{ form.add_subject }}
<input type="submit" name="add_subject_submit" value="Add Subject" id="submit_subject"></p> <a class="fakeinput" id="add_subject_submit" style="font-size: smaller;" >Add Subject</a></p>
{% endcomment %} <p id="tree" name="is_bisac"><b>Add BISAC Subject</b>:
</p>
<p><b>Cover Image</b>: <br /> <p><b>Cover Image</b>: <br />
{% if edition.cover_image %} {% if edition.cover_image %}
<img src="{{edition.cover_image}}" /><br /> <img src="{{edition.cover_image}}" /><br />
@ -109,7 +188,7 @@
(<i>upload a cover image file (we'll automatically size if for you). </i>)<br /> (<i>upload a cover image file (we'll automatically size if for you). </i>)<br />
</p> </p>
</div> </div>
<input type="submit" name="create_new_edition" value="{% if edition.pk %}Save Edits{% else %}Create Edition{% endif %}" id="submit"> <input type="submit" name="create_new_edition" style="font-size: larger;" value="{% if edition.pk %}Save Edits{% else %}Create Edition{% endif %}" id="submit">
</form> </form>
{% if edition.work %} {% if edition.work %}
@ -117,6 +196,9 @@
<div><a href="{% url 'merge' edition.work.id %}">Merge other works into this one</a></div> <div><a href="{% url 'merge' edition.work.id %}">Merge other works into this one</a></div>
<div><a href="{% url 'work_editions' edition.work.id %}">Remove editions from this work</a></div> <div><a href="{% url 'work_editions' edition.work.id %}">Remove editions from this work</a></div>
{% if edition.id %}
<div><a href="{% url 'manage_ebooks' edition.id %}">Add ebooks for this edition</a></div>
{% endif %}
{% if request.user.is_staff %} {% if request.user.is_staff %}
<div><a href="{% url 'feature' edition.work.id %}">Feature this work today</a></div> <div><a href="{% url 'feature' edition.work.id %}">Feature this work today</a></div>
{% endif %} {% endif %}
@ -130,7 +212,6 @@
Sorry, there's no work specified. Sorry, there's no work specified.
{% endif %} {% endif %}
{% endif %} {% endif %}
{% include 'edition_upload.html' %}
{% endblock %} {% endblock %}

View File

@ -29,7 +29,7 @@ We do a bunch of things to stop people from spying on your use of unglue.it. We
<ul class="bullets"> <ul class="bullets">
<li> <li>
All access to unglue.it <a href="https://https.cio.gov/everything/">uses secure, encrypted connections</a>, i.e. HTTPS. This means that if you're using public wifi, other people in the Starbucks <a href="http://www.howtogeek.com/178696/why-using-a-public-wi-fi-network-can-be-dangerous-even-when-accessing-encrypted-websites/">can't snoop on you</a>. Your ISPs and your <a href="http://go-to-hellman.blogspot.com/2014/11/if-your-website-still-uses-http-x-uidh.html">mobile data providers</a> can't see or mess with pages you're reading or downloading. Unglue.it can't be <a href="https://citizenlab.org/2015/04/chinas-great-cannon/">weaponized for cyberattacks</a>. Although Unglue.it is hosted on Amazon Web Services, Amazon can't see your unglue.it click stream. All access to unglue.it <a href="https://https.cio.gov/everything/">uses secure, encrypted connections</a>, i.e. HTTPS. This means that if you're using public wifi, other people in the Starbucks <a href="http://www.howtogeek.com/178696/why-using-a-public-wi-fi-network-can-be-dangerous-even-when-accessing-encrypted-websites/">can't snoop on you</a>. Your ISPs and your <a href="https://go-to-hellman.blogspot.com/2014/11/if-your-website-still-uses-http-x-uidh.html">mobile data providers</a> can't see or mess with pages you're reading or downloading. Unglue.it can't be <a href="https://citizenlab.org/2015/04/chinas-great-cannon/">weaponized for cyberattacks</a>. Although Unglue.it is hosted on Amazon Web Services, Amazon can't see your unglue.it click stream.
</li> </li>
<li> <li>
@ -49,11 +49,11 @@ We support <a href="https://en.wikipedia.org/wiki/Pseudonymity">pseudonymity</a>
</li> </li>
<li> <li>
We self-host static resources. Many sites load sitewide scripts, images and fonts from third parties. for example: JQuery, FontAwesome, Bootstrap, <a href="http://go-to-hellman.blogspot.com/2014/12/stop-making-web-surveillance-bugs-by.html">Creative Commons buttons</a>. Our web pages get to you a bit slower, but we leak less usage data. We self-host static resources. Many sites load sitewide scripts, images and fonts from third parties. for example: JQuery, FontAwesome, Bootstrap, <a href="https://go-to-hellman.blogspot.com/2014/12/stop-making-web-surveillance-bugs-by.html">Creative Commons buttons</a>. Our web pages get to you a bit slower, but we leak less usage data.
</li> </li>
<li> <li>
We use <a href=" http://w3c.github.io/webappsec/specs/referrer-policy">referrer meta tags</a> to instruct your browser <a href="http://go-to-hellman.blogspot.com/2015/06/protect-reader-privacy-with-referrer.html">not to leak your usage trails</a> to the many websites we link to. We use <a href=" http://w3c.github.io/webappsec/specs/referrer-policy">referrer meta tags</a> to instruct your browser <a href="https://go-to-hellman.blogspot.com/2015/06/protect-reader-privacy-with-referrer.html">not to leak your usage trails</a> to the many websites we link to.
</li> </li>
</ul> </ul>

View File

@ -114,6 +114,7 @@ urlpatterns = patterns(
url(r"^work/(?P<work_id>\d+)/openlibrary/$", "work_openlibrary", name="work_openlibrary"), url(r"^work/(?P<work_id>\d+)/openlibrary/$", "work_openlibrary", name="work_openlibrary"),
url(r"^new_edition/(?P<work_id>)(?P<edition_id>)$", "new_edition", name="new_edition"), url(r"^new_edition/(?P<work_id>)(?P<edition_id>)$", "new_edition", name="new_edition"),
url(r"^new_edition/(?P<work_id>\d*)/(?P<edition_id>\d*)$", "new_edition", name="new_edition"), url(r"^new_edition/(?P<work_id>\d*)/(?P<edition_id>\d*)$", "new_edition", name="new_edition"),
url(r"^manage_ebooks/(?P<edition_id>\d*)$", "manage_ebooks", name="manage_ebooks"),
url(r"^googlebooks/(?P<googlebooks_id>.+)/$", "googlebooks", name="googlebooks"), url(r"^googlebooks/(?P<googlebooks_id>.+)/$", "googlebooks", name="googlebooks"),
url(r"^download_ebook/(?P<ebook_id>\w+)/$", "download_ebook", name="download_ebook"), url(r"^download_ebook/(?P<ebook_id>\w+)/$", "download_ebook", name="download_ebook"),
url(r"^download_ebook/acq/(?P<format>\w+)/(?P<nonce>\w+)/$", "download_acq", name="download_acq"), url(r"^download_ebook/acq/(?P<format>\w+)/(?P<nonce>\w+)/$", "download_acq", name="download_acq"),

View File

@ -493,6 +493,13 @@ def edition_uploads(request, edition_id):
}) })
return render(request, 'edition_uploads.html', context ) return render(request, 'edition_uploads.html', context )
def add_subject(subject_name,work, authority=None):
try:
subject= models.Subject.objects.get(name=subject_name)
except models.Subject.DoesNotExist:
subject=models.Subject.objects.create(name=subject_name, authority=authority)
subject.works.add(work)
@login_required @login_required
def new_edition(request, work_id, edition_id, by=None): def new_edition(request, work_id, edition_id, by=None):
if not request.user.is_authenticated() : if not request.user.is_authenticated() :
@ -563,24 +570,6 @@ def new_edition(request, work_id, edition_id, by=None):
author=models.Author.objects.create(name=new_author_name) author=models.Author.objects.create(name=new_author_name)
edition.new_authors.append((new_author_name,new_author_relation)) edition.new_authors.append((new_author_name,new_author_relation))
form = EditionForm(instance=edition, data=request.POST, files=request.FILES) form = EditionForm(instance=edition, data=request.POST, files=request.FILES)
elif request.POST.has_key('add_subject_submit') and admin:
new_subject = request.POST['add_subject'].strip()
try:
subject= models.Subject.objects.get(name=new_subject)
except models.Subject.DoesNotExist:
subject=models.Subject.objects.create(name=new_subject)
edition.new_subjects.append(subject)
form = EditionForm(instance=edition, data=request.POST, files=request.FILES)
edition.ebook_form = EbookForm( instance= models.Ebook(user = request.user, edition = edition, provider = 'x' ), prefix = 'ebook_%d'%edition.id)
elif edition.id and request.POST.has_key('ebook_%d-edition' % edition.id):
edition.ebook_form= EbookForm( data = request.POST, prefix = 'ebook_%d'%edition.id)
if edition.ebook_form.is_valid():
edition.ebook_form.save()
alert = 'Thanks for adding an ebook to unglue.it!'
else:
alert = 'your submitted ebook had errors'
form = EditionForm(instance=edition, initial=initial)
elif not form and admin: elif not form and admin:
form = EditionForm(instance=edition, data=request.POST, files=request.FILES) form = EditionForm(instance=edition, data=request.POST, files=request.FILES)
if form.is_valid(): if form.is_valid():
@ -617,12 +606,13 @@ def new_edition(request, work_id, edition_id, by=None):
relator.set(new_relation) relator.set(new_relation)
for (author_name, author_relation) in edition.new_authors: for (author_name, author_relation) in edition.new_authors:
edition.add_author(author_name,author_relation) edition.add_author(author_name,author_relation)
if form.cleaned_data.has_key('bisac'):
bisacsh=form.cleaned_data['bisac']
while bisacsh:
add_subject(bisacsh.full_label, work, authority="bisacsh")
bisacsh = bisacsh.parent
for subject_name in edition.new_subjects: for subject_name in edition.new_subjects:
try: add_subject(subject_name, work)
subject= models.Subject.objects.get(name=subject_name)
except models.Subject.DoesNotExist:
subject=models.Subject.objects.create(name=subject_name)
subject.works.add(work)
work_url = reverse('work', kwargs={'work_id': edition.work.id}) work_url = reverse('work', kwargs={'work_id': edition.work.id})
cover_file=form.cleaned_data.get("coverfile",None) cover_file=form.cleaned_data.get("coverfile",None)
if cover_file: if cover_file:
@ -636,15 +626,60 @@ def new_edition(request, work_id, edition_id, by=None):
edition.save() edition.save()
return HttpResponseRedirect(work_url) return HttpResponseRedirect(work_url)
else: else:
if edition.pk:
edition.ebook_form = EbookForm( instance= models.Ebook(user = request.user, edition = edition, provider = 'x' ), prefix = 'ebook_%d'%edition.id)
form = EditionForm(instance=edition, initial=initial) form = EditionForm(instance=edition, initial=initial)
return render(request, 'new_edition.html', {
'form': form, 'edition': edition, 'admin':admin, 'alert':alert,
})
@login_required
def manage_ebooks(request, edition_id, by=None):
if edition_id:
try:
edition = models.Edition.objects.get(id = edition_id)
except models.Edition.DoesNotExist:
raise Http404
work = edition.work
else:
raise Http404
if not request.user.is_authenticated() :
return render(request, "admins_only.html")
# if the work and edition are set, we save the edition and set the work
alert = ''
admin = False
if request.user.is_staff :
admin = True
elif work and work.last_campaign():
if request.user in work.last_campaign().managers.all():
admin = True
elif work==None and request.user.rights_holder.count():
admin = True
if request.method == 'POST' :
edition.new_authors=zip(request.POST.getlist('new_author'),request.POST.getlist('new_author_relation'))
edition.new_subjects=request.POST.getlist('new_subject')
if edition.id and admin:
for author in edition.authors.all():
if request.POST.has_key('delete_author_%s' % author.id):
edition.remove_author(author)
form = EditionForm(instance=edition, data=request.POST, files=request.FILES)
break
if request.POST.has_key('ebook_%d-edition' % edition.id):
edition.ebook_form= EbookForm( data = request.POST, prefix = 'ebook_%d'%edition.id)
if edition.ebook_form.is_valid():
edition.ebook_form.save()
alert = 'Thanks for adding an ebook to unglue.it!'
else:
alert = 'your submitted ebook had errors'
else:
edition.ebook_form = EbookForm( instance= models.Ebook(user = request.user, edition = edition, provider = 'x' ), prefix = 'ebook_%d'%edition.id)
try: try:
show_ebook_form = edition.work.last_campaign().status not in ['ACTIVE','INITIALIZED'] show_ebook_form = edition.work.last_campaign().status not in ['ACTIVE','INITIALIZED']
except: except:
show_ebook_form = True show_ebook_form = True
return render(request, 'new_edition.html', { return render(request, 'manage_ebooks.html', {
'form': form, 'edition': edition, 'admin':admin, 'alert':alert, 'edition': edition, 'admin':admin, 'alert':alert,
'show_ebook_form':show_ebook_form, 'show_ebook_form':show_ebook_form,
}) })

View File

@ -30,6 +30,7 @@ django-extensions==0.9
django-jsonfield==0.9.10 django-jsonfield==0.9.10
django-kombu==0.9.4 django-kombu==0.9.4
django-maintenancemode==0.10 django-maintenancemode==0.10
django-mptt==0.7.4
django-nose-selenium==0.7.3 django-nose-selenium==0.7.3
#django-notification==0.2 #django-notification==0.2
git+git://github.com/aladagemre/django-notification.git@2927346f4c513a217ac8ad076e494dd1adbf70e1 git+git://github.com/aladagemre/django-notification.git@2927346f4c513a217ac8ad076e494dd1adbf70e1
@ -41,7 +42,7 @@ django-tastypie==0.9.11
feedparser==5.1.2 feedparser==5.1.2
freebase==1.0.8 freebase==1.0.8
#gitenberg.metadata==0.1.6 #gitenberg.metadata==0.1.6
git+ssh://git@github.com/gitenberg-dev/metadata.git@0.1.8 git+ssh://git@github.com/gitenberg-dev/metadata.git@0.1.11
html5lib==1.0b3 html5lib==1.0b3
httplib2==0.7.5 httplib2==0.7.5
isodate==0.5.1 isodate==0.5.1

View File

@ -131,6 +131,7 @@ INSTALLED_APPS = (
'django_extensions', 'django_extensions',
'regluit.frontend', 'regluit.frontend',
'regluit.api', 'regluit.api',
'regluit.bisac',
'regluit.core', 'regluit.core',
'regluit.marc', 'regluit.marc',
'regluit.payment', 'regluit.payment',
@ -148,6 +149,7 @@ INSTALLED_APPS = (
'ckeditor', 'ckeditor',
'storages', 'storages',
'sorl.thumbnail', 'sorl.thumbnail',
'mptt',
# this must appear *after* django.frontend or else it overrides the # this must appear *after* django.frontend or else it overrides the
# registration templates in frontend/templates/registration # registration templates in frontend/templates/registration
'django.contrib.admin', 'django.contrib.admin',

BIN
static/css/loading.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

6
static/css/ui.fancytree.min.css vendored Normal file

File diff suppressed because one or more lines are too long

47
static/js/jquery.fancytree-all.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -11,12 +11,17 @@ contributor:
gutenberg_agent_id: '37155' gutenberg_agent_id: '37155'
url: http://www.gutenberg.org/2009/agents/37155 url: http://www.gutenberg.org/2009/agents/37155
wikipedia: http://en.wikipedia.org/wiki/E._W._Kemble wikipedia: http://en.wikipedia.org/wiki/E._W._Kemble
covers: edition_list:
- attribution: Priscilla Parizeau, 2015 -
cover_type: original _edition: rtc_isbn
image_path: cover.jpg publisher: Recovering the Classics
rights: Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) rights: CC BY-NC
rights_url: https://creativecommons.org/licenses/by-nc/4.0/ covers:
- attribution: Priscilla Parizeau, 2015
cover_type: original
image_path: cover.jpg
rights: Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
rights_url: https://creativecommons.org/licenses/by-nc/4.0/
creator: creator:
author: author:
agent_name: Twain, Mark agent_name: Twain, Mark
@ -38,8 +43,8 @@ identifiers:
gutenberg: '76' gutenberg: '76'
language: en language: en
publication_date: 2015-08-01 publication_date: 2015-08-01
publisher: Recovering the Classics publisher: Project Gutenberg
rights: CC BY-NC rights: PD-US
rights_url: http://creativecommons.org/licenses/by-nc/4.0/ rights_url: http://creativecommons.org/licenses/by-nc/4.0/
subjects: subjects:
- !lcsh Male friendship -- Fiction - !lcsh Male friendship -- Fiction

View File

@ -18,6 +18,7 @@ urlpatterns = patterns('',
url(r'', include('regluit.payment.urls')), url(r'', include('regluit.payment.urls')),
url(r'', include('regluit.libraryauth.urls')), url(r'', include('regluit.libraryauth.urls')),
url(r'', include('regluit.marc.urls')), url(r'', include('regluit.marc.urls')),
url(r'^bisac/', include('regluit.bisac.urls')),
url(r'^selectable/', include('selectable.urls')), url(r'^selectable/', include('selectable.urls')),
url(r'^admin/', include(admin_site.urls)), url(r'^admin/', include(admin_site.urls)),
url(r'^comments/', include('django.contrib.comments.urls')), url(r'^comments/', include('django.contrib.comments.urls')),