/* * [ConfigurationForMindprodCa.java] * * Summary: This is the customisation implementation of Configuration for mindprod.ca. * * Copyright: (c) 2009-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.8 2009-02-06 include go package in ZIP bundle. * 1.9 2010-01-23 make configuration into an instance and interface rather than static. * 2.0 2012-11-05 add support for set resetfooterpercentage * 2.1 2014-07-02 now checks for dups is fastcats.csv and has more complex defaults. * 2.2 2014-07-12 get rid of fastcats.csv. Estimates calculated dynamically. * 2.3 2014-09-11 make AssignCSSClasses independently configurable to keep down size of ConfigurationForMindprod * 2.4 2016-06-01 cloned from ConfigurationForMindprod */ package com.mindprod.htmlmacros.support; import com.mindprod.common18.Build; import com.mindprod.common18.EIO; import com.mindprod.common18.Misc; import com.mindprod.common18.ST; import com.mindprod.qf.AbstractGlossCustomiser; import com.mindprod.qf.DglossCustomiser; import com.mindprod.qf.EglossCustomiser; import com.mindprod.qf.GglossCustomiser; import com.mindprod.qf.LglossCustomiser; import com.mindprod.stores.OnlineStore; import com.mindprod.stores.StockStatus; import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; import static java.lang.System.*; /** * This is the customisation implementation of Configuration for mindprod.ca. *

* You need to write something similar * that implements the Configuration interface. * Configuration installed in Replacer command line, or programatically * by ReplaceMindprod * * @author Roedy Green, Canadian Mind Products * @version 2.4 2016-06-01 cloned from ConfigurationForMindprod * @see AssignCSSClassesForMindprod * @since 2009 */ public final class ConfigurationForMindprodCa extends Configuration { // declarations /** * do we want verbose output */ private static final boolean verbose = Misc.parseBoolean( System.getenv( "verbose" ), false ); /** * How often we rotate the embedded quotations in Milliseconds on KJV pages. in ms, * values in days. longer less frequent change. */ private static final long ROTATE_INTERVAL_KJV_EMBEDDED_QUOTATION_IN_MILLIS = TimeUnit.DAYS.toMillis( 10 ); /** * How often we rotate the Public Service Ads in Milliseconds on KJV pages. Also how often permit flip psa <--> * quotation. * Effectively changed every time run sendr after updating quotes, i.e. daily */ private static final long ROTATE_INTERVAL_KJV_FOOTER_IN_MILLIS = TimeUnit.DAYS.toMillis( 20 ); /** * How often we rotate the embedded quotations in Milliseconds on index pages */ private static final long ROTATE_INTERVAL_MAJOR_EMBEDDED_QUOTATION_IN_MILLIS = TimeUnit.HOURS.toMillis( 4 ); /** * How often we rotate the Public Service Ads in Milliseconds on index pages * Also how often permit flip psa <--> quotation. */ private static final long ROTATE_INTERVAL_MAJOR_FOOTER_IN_MILLIS = TimeUnit.HOURS.toMillis( 2 ); /** * How often we rotate the embedded quotations in Milliseconds on non-index pages. */ private static final long ROTATE_INTERVAL_MINOR_EMBEDDED_QUOTATION_IN_MILLIS = TimeUnit.HOURS.toMillis( 5 ); /** * How often we rotate the Public Service Ads in Milliseconds on non-index pages. Also controls how often we * might change * both the PSA, considering a Quote, and non-military use only as a type of PSA. * If new PSA sites (but not just new ads) are added, this can trigger massive changes. * Also how often permit flip psa <--> quotation. Adding a new quotation will trigger massive changes too. * Such changes are postponed until the next sendr. */ private static final long ROTATE_INTERVAL_MINOR_FOOTER_IN_MILLIS = TimeUnit.DAYS.toMillis( 3 ); /** * blurb */ private static final String[] CYCLE_BLURB = { "preface", "blurb1", "blurb2", "blurb3", "blurb4", "blurb5", "blurb6", "blurb7", "blurb8", "blurb9", "blurb10", "blurb11", "blurb12", "blurb13", "blurb14", "blurb15", "blurb16", "blurb17", "blurb18", "blurb19", "blurb20", "blurb21", "blurb22", "blurb23", "blurb24", "blurb25", "blurb26", "blurb27", "blurb28", "blurb29", "blurb30", "blurb31", "blurb32", "blurb33", "blurb34", "blurb35", "blurb36", "blurb37", "blurb38", "blurb39", "blurb40", "blurb41", "blurb42", "blurb43", "blurb44", "blurb45", "blurb46", "blurb47", "blurb48", "blurb49", "blurb50" }; /** * bush911 essays */ private static final String[] CYCLE_BUSH911 = { "bush911", "bush911introduction", "bush911bushstory", "bush911preparation", "bush911insidejob", "bush911rubicon", "bush911lawsuits", "bush911andrewjohnson", "bush911nutshell", "bush911evidence", "bush911lies", "bush911vulnerablity", "bush911scramble", "bush911inaction", "bush911goat", "bush911holes", "bush911meaning", "bush911binladen", "bush911ties", "bush911motives", "bush911afghanistan", "bush911history", "bush911collusion", "bush911vreeland", "bush911bushknew", "bush911leaks", "bush911response", "bush911quotes", "bush911psychosis", "bush911distraction", "bush911drugs", "bush911kissinger", "bush911hitler", "bush911scandals", "bush911whodunit", "bush911really", "bush911conclusion", "bush911spoken", "bush911videos", "bush911links", "bush911ringhome", "bush911links", "bush911action", "bush911todo" }; /** * books about Bush */ private static final String[] CYCLE_BUSHBOOKS = { "bushbooks", "bushbookspedophilia", "bushbooksskullandbones", "bushbookscocaine", "bushbookselections", "bushbooksbushisms", "bushbooks911", "bushbooksrecord", "bushbookscorruption", "bushbooksiraq", "bushbookstorture", "bushbookstyranny", "bushbooksrelated", "bushbookskerry", "bushbookslinks" }; /** * bushisms */ private static final String[] CYCLE_BUSHISMS = { "bushisms", "bushismsayatolla", "bushismsbabytalk", "bushismsbudget", "bushismscredibility", "bushismscrime", "bushismsdelusions", "bushismsdissembler", "bushismsdrinking", "bushismsconsistency", "bushismsfreud", "bushismsgeneral", "bushismsgay", "bushismsheart", "bushismsheil", "bushismshitler", "bushismshurricane", "bushismsleaks", "bushismsnapoleon", "bushismslies", "bushismsliteracy", "bushismsmarie", "bushismsduh", "bushismsobscene", "bushismsreally", "bushismsorwell", "bushismsscience", "bushismsslips", "bushismsstatesman", "bushismssure", "bushismsendearment", "bushismsterrorists", "bushismstimetravel", "bushismstruth", "bushismsdyslexia", "bushismsmitty", "bushismssalads", "bushismsquayle", "bushismsfleischer", "bushismsaboutbush", "bushismsnotbush", "bushismsbumperstickers", "bushismswhy", "bushismsvideo", "bushismslinks" }; /** * handbook to higher consciousness */ private static final String[] CYCLE_HANDBOOK = { "about", "toc", "acknowledgements", "foreword", "chapter1", "chapter2", "chapter3", "chapter4", "chapter5", "chapter6", "chapter7", "chapter8", "chapter9", "chapter10", "chapter11", "chapter12", "chapter13", "chapter14", "chapter15", "chapter16", "chapter17", "chapter18", "chapter19", "chapter20", "chapter21", "chapter22", "chapter23", "chapter24", "chapter25", "appendix1", "appendix2", "appendix3", "appendix4", "appendix5" }; /** * index for glossary essays */ private static final String[] CYCLE_INDEX = { "punct", "0-9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "masterindex" }; /** * Iraq essays */ private static final String[] CYCLE_IRAQ = { "iraq", "iraqintroduction", "iraqterrorists", "iraqwarcriminals", "iraqdisrespect", "iraqjoke", "iraqwarpix", "iraqabughraibpix", "iraqseals", "iraqfallujah", "iraqdubabiespix", "iraqculprits", "iraqprotestors", "iraqlinkstopix", "iraqbodycounts", "iraqdsb", "iraqatrocities", "iraqtortures", "iraqtorturegloss", "iraqlies", "iraqmotives", "iraqeconomics", "iraqunderstanding", "iraqdenial", "iraqpretend", "iraqsaddam", "iraqfuture", "iraqmyob", "iraqdespise", "iraqgodonourside", "iraqsheehan", "iraqkill", "iraqdontmarry", "iraqdontenlist", "iraqdoenlist", "iraqdraft", "iraqideal", "iraqspoken", "iraqvideos", "iraqlinks", "iraqend", "iraqconclusions" }; /** * Dirs containing snippet Directories. Distributed, but macros not expanded or compacted. All Live in E:\mindprod\ * not the snippet dirs themselves. */ private static final String[] DIRS_CONTAINING_SNIPPETS = { }; /** * Directories containing HTML files with macros. Does not include redir, includes, snippets, rss * since these do not include HTML needing macro expansion. kjv is handled separated * All Live in E:\mindprodca\ */ private static final String[] HTML_DIRS = { "", "animalrights", "book", "canada", "contact", "carol", "deepthoughts", "dvd", "electronic", "environment", "ethics", "feedback", "feedback/animals", "feedback/environment", "feedback/god", "feedback/hallucination", "feedback/humanrights", "feedback/money", "feedback/peace", "feedback/porn", "feedback/unmain", "ggloss", "ggloss/blurb", "humanrights", "livinglove", "livinglove/handbook", "livinglove/methods", "livinglove/methods/songlyrics", "money", "politics", "politics/laser", "religion", "reunion", "quote", }; /** * include Directories containing HTML files. Distributed. All Live in E:\mindprod\ */ private static final String[] INCLUDE_DIRS = { "environment/include", "ggloss/include", "include", "livinglove/include", "religion/include" }; /** * Dirs that need to be seesorted (links at bottom of page sorted). All live in E:\mindprod\ */ private static final String[] DIRS_TO_SEESORT = { "animalrights", "application", "contact", "deepthoughts", "environment", "feedback", "ggloss", "humanrights", "include", "livinglove", "livinglove/methods", "money", "politics", "quote", "religion", "reunion" }; /** * King James bible Directories containing HTML files. Sorted alphabetically. All Live in E:\mindprod\kjv. * do not have kjv/ prefix */ private static final String[] KJV_DIRS_ALPHABETICALLY = { ""/* root */, "1_Chronicles", "1_Corinthians", "1_John", "1_Kings", "1_Peter", "1_Samuel", "1_Thessalonians", "1_Timothy", "2_Chronicles", "2_Corinthians", "2_John", "2_Kings", "2_Peter", "2_Samuel", "2_Thessalonians", "2_Timothy", "3_John", "Acts", "Amos", "Colossians", "Daniel", "Deuteronomy", "Ecclesiastes", "Ephesians", "Esther", "Exodus", "Ezekiel", "Ezra", "Galatians", "Genesis", "Habakkuk", "Haggai", "Hebrews", "Hosea", "Isaiah", "James", "Jeremiah", "Job", "Joel", "John", "Jonah", "Joshua", "Jude", "Judges", "Lamentations", "Leviticus", "Luke", "Malachi", "Mark", "Matthew", "Micah", "Nahum", "Nehemiah", "Numbers", "Obadiah", "Philemon", "Philippians", "Proverbs", "Psalms", "Revelation", "Romans", "Ruth", "Song_of_Songs", "Titus", "Zechariah", "Zephaniah" }; /** * List of product ids that vendors say have repacements, but do not. */ private static final HashSet NOT_ACTUALLY_NEWER_PRODUCT_IDS_SET = new HashSet<>( Arrays.asList( ) ); /** * major pages the get PSA ads rotated more frequently, these are page names, not directories, without .html * Used by Mindprod custom routines */ private static final HashSet MAJOR_PAGES_SET = new HashSet<>( Arrays.asList( "animalrights", "contact", "deepthoughts", "environment", "ethics", "feedback", "ggloss", "humanrights", "livinglove", "money", "politics", "religion", "reunion", "whatsnew" ) ); /** * dirs that need jdisplay.css */ private static final HashSet NEEDS_JDISPLAY_CSS_SET = new HashSet<>( Arrays.asList( "book", "dvd", "electronic", "feedback/unmain", "quote" ) ); /** * ISBNs of rare books */ private static final HashSet RARE_PRODUCTS = new HashSet<>( Arrays.asList( "9780130889218", "9780131858435", "9780321256171", "9780405036255", "9780405036255", "9780976221432", "9781885223449", "767685975633" ) ); /** * radomiser to determine which quotes to reset */ private static final Random resetQuoteWheel = new Random(); /** * table of what Quote aggrefate to use in th footer for each book */ private static final HashMap quoteAggregateForBookFooter = new HashMap<>( 1000 ); /** * percent of footers we should reset on this run. * If there are no new quotes in the collections, reset quotes will likely remain the same. * If there are new quotes, reset quotes will likely change. */ private static int resetFooterPercentage = -1; // methods /** * CSS assigning configuration **/ private AssignCSSClasses assignCSSClasses; /** * Figure out which page comes before/after this one. * * @param fileBeingDistributed the file currently being processed. * @param calcNextRatherThanPrev true if calc next rather than prev page. * * @return relative link to the previous page, null if no logical next page. */ private static String calcPrevOrNextPage( final File fileBeingDistributed, final boolean calcNextRatherThanPrev ) { final String kjvLink = calcNextRatherThanPrev ? nextInKJV( fileBeingDistributed ) : prevInKJV( fileBeingDistributed ); if ( kjvLink != null ) { return kjvLink; } // e.g. politics or politics/laser final String dir = Tools.dirWithSlashes( fileBeingDistributed ); // just name with ext, no dir. e.g. iraqdontenlist final String coreName = EIO.getCoreName( fileBeingDistributed ); if ( dir.equals( "ggloss/blurb" ) ) { return prevOrNextInCycle( CYCLE_BLURB, coreName, calcNextRatherThanPrev ); } else if ( dir.equals( "livinglove/handbook" ) ) { return prevOrNextInCycle( CYCLE_HANDBOOK, coreName, calcNextRatherThanPrev ); } else if ( dir.equals( "politics" ) && coreName.startsWith( "bush911" ) ) { return prevOrNextInCycle( CYCLE_BUSH911, coreName, calcNextRatherThanPrev ); } else if ( dir.equals( "politics" ) && coreName.startsWith( "bushbooks" ) ) { return prevOrNextInCycle( CYCLE_BUSHBOOKS, coreName, calcNextRatherThanPrev ); } else if ( dir.equals( "politics" ) && coreName.startsWith( "bushisms" ) ) { return prevOrNextInCycle( CYCLE_BUSHISMS, coreName, calcNextRatherThanPrev ); } else if ( coreName.equals( "punct" ) || coreName.equals( "masterindex" ) || coreName.equals( "0-9" ) || coreName.length() == 1 && 'a' <= coreName.charAt( 0 ) && coreName.charAt( 0 ) <= 'z' ) { // works on jgloss, bgloss, ggloss return prevOrNextInCycle( CYCLE_INDEX, coreName, calcNextRatherThanPrev ); } else if ( dir.equals( "politics" ) && coreName.startsWith( "iraq" ) ) { return prevOrNextInCycle( CYCLE_IRAQ, coreName, calcNextRatherThanPrev ); } else { return null; } }// /method private static void initQuoteAggregateForBookFooter() { // table of what Quote aggrefate to use in th footer for each book QuoteAggregate agg = QuoteAggregate.ANIMALRIGHTS; quoteAggregateForBookFooter.put( "9780199551200", agg ); quoteAggregateForBookFooter.put( "9780199551200", agg ); quoteAggregateForBookFooter.put( "9780285622555", agg ); quoteAggregateForBookFooter.put( "9780385025430", agg ); quoteAggregateForBookFooter.put( "9780385110372", agg ); quoteAggregateForBookFooter.put( "9780446330237", agg ); quoteAggregateForBookFooter.put( "9780517565643", agg ); quoteAggregateForBookFooter.put( "9780547445724", agg ); quoteAggregateForBookFooter.put( "9780792271291", agg ); quoteAggregateForBookFooter.put( "9780792275947", agg ); quoteAggregateForBookFooter.put( "9780874775396", agg ); quoteAggregateForBookFooter.put( "9780914171720", agg ); quoteAggregateForBookFooter.put( "9780970647566", agg ); quoteAggregateForBookFooter.put( "9781550135992", agg ); quoteAggregateForBookFooter.put( "9781558214484", agg ); agg = QuoteAggregate.ENVIRONMENT; quoteAggregateForBookFooter.put( "9780060746872", agg ); quoteAggregateForBookFooter.put( "9780060915872", agg ); quoteAggregateForBookFooter.put( "9780061137921", agg ); quoteAggregateForBookFooter.put( "9780061252792", agg ); quoteAggregateForBookFooter.put( "9780143038580", agg ); quoteAggregateForBookFooter.put( "9780143038986", agg ); quoteAggregateForBookFooter.put( "9780143117001", agg ); quoteAggregateForBookFooter.put( "9780151012879", agg ); quoteAggregateForBookFooter.put( "9780199291151", agg ); quoteAggregateForBookFooter.put( "9780231152549", agg ); quoteAggregateForBookFooter.put( "9780307398246", agg ); quoteAggregateForBookFooter.put( "9780312360061", agg ); quoteAggregateForBookFooter.put( "9780316666084", agg ); quoteAggregateForBookFooter.put( "9780340416686", agg ); quoteAggregateForBookFooter.put( "9780345371980", agg ); quoteAggregateForBookFooter.put( "9780345376596", agg ); quoteAggregateForBookFooter.put( "9780374166854", agg ); quoteAggregateForBookFooter.put( "9780375760396", agg ); quoteAggregateForBookFooter.put( "9780385662222", agg ); quoteAggregateForBookFooter.put( "9780393071030", agg ); quoteAggregateForBookFooter.put( "9780452296305", agg ); quoteAggregateForBookFooter.put( "9780465022724", agg ); quoteAggregateForBookFooter.put( "9780465027620", agg ); quoteAggregateForBookFooter.put( "9780470840986", agg ); quoteAggregateForBookFooter.put( "9780521010689", agg ); quoteAggregateForBookFooter.put( "9780521864718", agg ); quoteAggregateForBookFooter.put( "9780618056736", agg ); quoteAggregateForBookFooter.put( "9780618485390", agg ); quoteAggregateForBookFooter.put( "9780618562114", agg ); quoteAggregateForBookFooter.put( "9780671888251", agg ); quoteAggregateForBookFooter.put( "9780679314653", agg ); quoteAggregateForBookFooter.put( "9780684800639", agg ); quoteAggregateForBookFooter.put( "9780684837376", agg ); quoteAggregateForBookFooter.put( "9780684863528", agg ); quoteAggregateForBookFooter.put( "9780771042317", agg ); quoteAggregateForBookFooter.put( "9780802142498", agg ); quoteAggregateForBookFooter.put( "9780805037517", agg ); quoteAggregateForBookFooter.put( "9780805091731", agg ); quoteAggregateForBookFooter.put( "9780807085837", agg ); quoteAggregateForBookFooter.put( "9780865477131", agg ); quoteAggregateForBookFooter.put( "9780865714076", agg ); quoteAggregateForBookFooter.put( "9780865714212", agg ); quoteAggregateForBookFooter.put( "9780865715103", agg ); quoteAggregateForBookFooter.put( "9780865715295", agg ); quoteAggregateForBookFooter.put( "9780865715639", agg ); quoteAggregateForBookFooter.put( "9780865716957", agg ); quoteAggregateForBookFooter.put( "9780870812422", agg ); quoteAggregateForBookFooter.put( "9780871139351", agg ); quoteAggregateForBookFooter.put( "9780871568007", agg ); quoteAggregateForBookFooter.put( "9780889204423", agg ); quoteAggregateForBookFooter.put( "9780894202995", agg ); quoteAggregateForBookFooter.put( "9780906522394", agg ); quoteAggregateForBookFooter.put( "9781400051571", agg ); quoteAggregateForBookFooter.put( "9781426202131", agg ); quoteAggregateForBookFooter.put( "9781550549263", agg ); quoteAggregateForBookFooter.put( "9781552637814", agg ); quoteAggregateForBookFooter.put( "9781553654858", agg ); quoteAggregateForBookFooter.put( "9781553658313", agg ); quoteAggregateForBookFooter.put( "9781554698042", agg ); quoteAggregateForBookFooter.put( "9781559637848", agg ); quoteAggregateForBookFooter.put( "9781565848139", agg ); quoteAggregateForBookFooter.put( "9781583227305", agg ); quoteAggregateForBookFooter.put( "9781594201455", agg ); quoteAggregateForBookFooter.put( "9781594865671", agg ); quoteAggregateForBookFooter.put( "9781594867347", agg ); quoteAggregateForBookFooter.put( "9781603582643", agg ); quoteAggregateForBookFooter.put( "9781851687428", agg ); quoteAggregateForBookFooter.put( "9781878271686", agg ); quoteAggregateForBookFooter.put( "9781894439305", agg ); agg = QuoteAggregate.EVOLUTION; quoteAggregateForBookFooter.put( "9780300108651", agg ); quoteAggregateForBookFooter.put( "9780307277459", agg ); quoteAggregateForBookFooter.put( "9780393039306", agg ); quoteAggregateForBookFooter.put( "9780393061635", agg ); quoteAggregateForBookFooter.put( "9780393308198", agg ); quoteAggregateForBookFooter.put( "9780451529060", agg ); quoteAggregateForBookFooter.put( "9780553374698", agg ); quoteAggregateForBookFooter.put( "9780618005833", agg ); quoteAggregateForBookFooter.put( "9780670020539", agg ); quoteAggregateForBookFooter.put( "9781416594789", agg ); agg = QuoteAggregate.GAY; quoteAggregateForBookFooter.put( "9780060080846", agg ); quoteAggregateForBookFooter.put( "9780141180281", agg ); quoteAggregateForBookFooter.put( "9780312241353", agg ); quoteAggregateForBookFooter.put( "9780312253776", agg ); quoteAggregateForBookFooter.put( "9780316371377", agg ); quoteAggregateForBookFooter.put( "9780380804436", agg ); quoteAggregateForBookFooter.put( "9780679751649", agg ); quoteAggregateForBookFooter.put( "9780679757016", agg ); quoteAggregateForBookFooter.put( "9780684868622", agg ); quoteAggregateForBookFooter.put( "9780802085702", agg ); quoteAggregateForBookFooter.put( "9780802151988", agg ); quoteAggregateForBookFooter.put( "9780873377904", agg ); quoteAggregateForBookFooter.put( "9780923183240", agg ); quoteAggregateForBookFooter.put( "9780923550127", agg ); quoteAggregateForBookFooter.put( "9780970773517", agg ); quoteAggregateForBookFooter.put( "9782070368075", agg ); agg = QuoteAggregate.ISRAEL; quoteAggregateForBookFooter.put( "9780393058260", agg ); quoteAggregateForBookFooter.put( "9780896086012", agg ); quoteAggregateForBookFooter.put( "9781851684670", agg ); agg = QuoteAggregate.LIVINGLOVE; quoteAggregateForBookFooter.put( "9780020777502", agg ); quoteAggregateForBookFooter.put( "9780060919832", agg ); quoteAggregateForBookFooter.put( "9780060972929", agg ); quoteAggregateForBookFooter.put( "9780345410030", agg ); quoteAggregateForBookFooter.put( "9780452272040", agg ); quoteAggregateForBookFooter.put( "9780452281325", agg ); quoteAggregateForBookFooter.put( "9780498067525", agg ); quoteAggregateForBookFooter.put( "9780671733353", agg ); quoteAggregateForBookFooter.put( "9780671734206", agg ); quoteAggregateForBookFooter.put( "9780676977400", agg ); quoteAggregateForBookFooter.put( "9780890879092", agg ); quoteAggregateForBookFooter.put( "9780895560711", agg ); quoteAggregateForBookFooter.put( "9780915972012", agg ); quoteAggregateForBookFooter.put( "9780915972029", agg ); quoteAggregateForBookFooter.put( "9780915972081", agg ); quoteAggregateForBookFooter.put( "9780915972128", agg ); quoteAggregateForBookFooter.put( "9780915972135", agg ); quoteAggregateForBookFooter.put( "9780915972159", agg ); quoteAggregateForBookFooter.put( "9780915972166", agg ); quoteAggregateForBookFooter.put( "9780915972180", agg ); quoteAggregateForBookFooter.put( "9780915972197", agg ); quoteAggregateForBookFooter.put( "9780915972210", agg ); quoteAggregateForBookFooter.put( "9780915972227", agg ); quoteAggregateForBookFooter.put( "9780935616033", agg ); quoteAggregateForBookFooter.put( "9780935616095", agg ); quoteAggregateForBookFooter.put( "9780942024012", agg ); quoteAggregateForBookFooter.put( "9780960068845", agg ); quoteAggregateForBookFooter.put( "9780960068883", agg ); quoteAggregateForBookFooter.put( "9780968810200", agg ); quoteAggregateForBookFooter.put( "9781559272889", agg ); quoteAggregateForBookFooter.put( "9781571781802", agg ); quoteAggregateForBookFooter.put( "9781582700649", agg ); quoteAggregateForBookFooter.put( "9781870845243", agg ); quoteAggregateForBookFooter.put( "9781892005021", agg ); quoteAggregateForBookFooter.put( "9781904424963", agg ); quoteAggregateForBookFooter.put( "9788441404687", agg ); quoteAggregateForBookFooter.put( "9789506710118", agg ); agg = QuoteAggregate.MONEY; quoteAggregateForBookFooter.put( "9780140187953", agg ); quoteAggregateForBookFooter.put( "9780262541152", agg ); quoteAggregateForBookFooter.put( "9780262541169", agg ); quoteAggregateForBookFooter.put( "9780307589941", agg ); quoteAggregateForBookFooter.put( "9780374533656", agg ); quoteAggregateForBookFooter.put( "9780385527828", agg ); quoteAggregateForBookFooter.put( "9780393330281", agg ); quoteAggregateForBookFooter.put( "9780446386364", agg ); quoteAggregateForBookFooter.put( "9780465003525", agg ); quoteAggregateForBookFooter.put( "9780520231788", agg ); quoteAggregateForBookFooter.put( "9780670064199", agg ); quoteAggregateForBookFooter.put( "9780671746216", agg ); quoteAggregateForBookFooter.put( "9780676978018", agg ); quoteAggregateForBookFooter.put( "9780712699914", agg ); quoteAggregateForBookFooter.put( "9780912986395", agg ); quoteAggregateForBookFooter.put( "9780969439424", agg ); quoteAggregateForBookFooter.put( "9781550287356", agg ); quoteAggregateForBookFooter.put( "9781551642802", agg ); quoteAggregateForBookFooter.put( "9781552637340", agg ); quoteAggregateForBookFooter.put( "9781576753019", agg ); quoteAggregateForBookFooter.put( "9781579546274", agg ); quoteAggregateForBookFooter.put( "9781585423132", agg ); quoteAggregateForBookFooter.put( "9781591841913", agg ); quoteAggregateForBookFooter.put( "9781594201929", agg ); quoteAggregateForBookFooter.put( "9781594485695", agg ); quoteAggregateForBookFooter.put( "9781596915985", agg ); agg = QuoteAggregate.POLITICS; quoteAggregateForBookFooter.put( "9780060188771", agg ); quoteAggregateForBookFooter.put( "9780060195915", agg ); quoteAggregateForBookFooter.put( "9780060392451", agg ); quoteAggregateForBookFooter.put( "9780060565237", agg ); quoteAggregateForBookFooter.put( "9780061430657", agg ); quoteAggregateForBookFooter.put( "9780140124958", agg ); quoteAggregateForBookFooter.put( "9780143034315", agg ); quoteAggregateForBookFooter.put( "9780143034896", agg ); quoteAggregateForBookFooter.put( "9780156030052", agg ); quoteAggregateForBookFooter.put( "9780195166347", agg ); quoteAggregateForBookFooter.put( "9780199898398", agg ); quoteAggregateForBookFooter.put( "9780297851141", agg ); quoteAggregateForBookFooter.put( "9780307237699", agg ); quoteAggregateForBookFooter.put( "9780307237927", agg ); quoteAggregateForBookFooter.put( "9780307263773", agg ); quoteAggregateForBookFooter.put( "9780307265616", agg ); quoteAggregateForBookFooter.put( "9780307590619", agg ); quoteAggregateForBookFooter.put( "9780312160524", agg ); quoteAggregateForBookFooter.put( "9780312284534", agg ); quoteAggregateForBookFooter.put( "9780312315603", agg ); quoteAggregateForBookFooter.put( "9780312352417", agg ); quoteAggregateForBookFooter.put( "9780312378455", agg ); quoteAggregateForBookFooter.put( "9780312861872", agg ); quoteAggregateForBookFooter.put( "9780316000239", agg ); quoteAggregateForBookFooter.put( "9780316085960", agg ); quoteAggregateForBookFooter.put( "9780316720915", agg ); quoteAggregateForBookFooter.put( "9780375423024", agg ); quoteAggregateForBookFooter.put( "9780375509032", agg ); quoteAggregateForBookFooter.put( "9780375714498", agg ); quoteAggregateForBookFooter.put( "9780375757143", agg ); quoteAggregateForBookFooter.put( "9780375760747", agg ); quoteAggregateForBookFooter.put( "9780385503242", agg ); quoteAggregateForBookFooter.put( "9780385660129", agg ); quoteAggregateForBookFooter.put( "9780385721677", agg ); quoteAggregateForBookFooter.put( "9780393322965", agg ); quoteAggregateForBookFooter.put( "9780415926478", agg ); quoteAggregateForBookFooter.put( "9780446532235", agg ); quoteAggregateForBookFooter.put( "9780446556248", agg ); quoteAggregateForBookFooter.put( "9780446694889", agg ); quoteAggregateForBookFooter.put( "9780451112040", agg ); quoteAggregateForBookFooter.put( "9780451524935", agg ); quoteAggregateForBookFooter.put( "9780451528698", agg ); quoteAggregateForBookFooter.put( "9780452289574", agg ); quoteAggregateForBookFooter.put( "9780465003365", agg ); quoteAggregateForBookFooter.put( "9780465027262", agg ); quoteAggregateForBookFooter.put( "9780465031337", agg ); quoteAggregateForBookFooter.put( "9780471471400", agg ); quoteAggregateForBookFooter.put( "9780471679950", agg ); quoteAggregateForBookFooter.put( "9780471853169", agg ); quoteAggregateForBookFooter.put( "9780517055717", agg ); quoteAggregateForBookFooter.put( "9780517556153", agg ); quoteAggregateForBookFooter.put( "9780520242869", agg ); quoteAggregateForBookFooter.put( "9780525947646", agg ); quoteAggregateForBookFooter.put( "9780525949060", agg ); quoteAggregateForBookFooter.put( "9780525949688", agg ); quoteAggregateForBookFooter.put( "9780525953722", agg ); quoteAggregateForBookFooter.put( "9780595261758", agg ); quoteAggregateForBookFooter.put( "9780618344208", agg ); quoteAggregateForBookFooter.put( "9780670031412", agg ); quoteAggregateForBookFooter.put( "9780670032600", agg ); quoteAggregateForBookFooter.put( "9780676974645", agg ); quoteAggregateForBookFooter.put( "9780679313120", agg ); quoteAggregateForBookFooter.put( "9780679314028", agg ); quoteAggregateForBookFooter.put( "9780684873190", agg ); quoteAggregateForBookFooter.put( "9780742529779", agg ); quoteAggregateForBookFooter.put( "9780743214780", agg ); quoteAggregateForBookFooter.put( "9780743222228", agg ); quoteAggregateForBookFooter.put( "9780743247443", agg ); quoteAggregateForBookFooter.put( "9780743247726", agg ); quoteAggregateForBookFooter.put( "9780743253376", agg ); quoteAggregateForBookFooter.put( "9780743255455", agg ); quoteAggregateForBookFooter.put( "9780743255479", agg ); quoteAggregateForBookFooter.put( "9780743255752", agg ); quoteAggregateForBookFooter.put( "9780743260244", agg ); quoteAggregateForBookFooter.put( "9780743262514", agg ); quoteAggregateForBookFooter.put( "9780743271097", agg ); quoteAggregateForBookFooter.put( "9780743272230", agg ); quoteAggregateForBookFooter.put( "9780743273091", agg ); quoteAggregateForBookFooter.put( "9780743284578", agg ); quoteAggregateForBookFooter.put( "9780743285025", agg ); quoteAggregateForBookFooter.put( "9780743287128", agg ); quoteAggregateForBookFooter.put( "9780743442671", agg ); quoteAggregateForBookFooter.put( "9780745318462", agg ); quoteAggregateForBookFooter.put( "9780745330402", agg ); quoteAggregateForBookFooter.put( "9780771029752", agg ); quoteAggregateForBookFooter.put( "9780771029776", agg ); quoteAggregateForBookFooter.put( "9780771029783", agg ); quoteAggregateForBookFooter.put( "9780771029806", agg ); quoteAggregateForBookFooter.put( "9780771041655", agg ); quoteAggregateForBookFooter.put( "9780771057601", agg ); quoteAggregateForBookFooter.put( "9780771080791", agg ); quoteAggregateForBookFooter.put( "9780781206617", agg ); quoteAggregateForBookFooter.put( "9780786713783", agg ); quoteAggregateForBookFooter.put( "9780786715381", agg ); quoteAggregateForBookFooter.put( "9780786718320", agg ); quoteAggregateForBookFooter.put( "9780805057874", agg ); quoteAggregateForBookFooter.put( "9780805070040", agg ); quoteAggregateForBookFooter.put( "9780805075595", agg ); quoteAggregateForBookFooter.put( "9780805076882", agg ); quoteAggregateForBookFooter.put( "9780805079128", agg ); quoteAggregateForBookFooter.put( "9780805079678", agg ); quoteAggregateForBookFooter.put( "9780805091410", agg ); quoteAggregateForBookFooter.put( "9780809012480", agg ); quoteAggregateForBookFooter.put( "9780812694222", agg ); quoteAggregateForBookFooter.put( "9780812966534", agg ); quoteAggregateForBookFooter.put( "9780865715066", agg ); quoteAggregateForBookFooter.put( "9780865715400", agg ); quoteAggregateForBookFooter.put( "9780871139542", agg ); quoteAggregateForBookFooter.put( "9780872863231", agg ); quoteAggregateForBookFooter.put( "9780872865372", agg ); quoteAggregateForBookFooter.put( "9780889080102", agg ); quoteAggregateForBookFooter.put( "9780889086753", agg ); quoteAggregateForBookFooter.put( "9780930852405", agg ); quoteAggregateForBookFooter.put( "9780930852511", agg ); quoteAggregateForBookFooter.put( "9780953881024", agg ); quoteAggregateForBookFooter.put( "9780962008672", agg ); quoteAggregateForBookFooter.put( "9780963215802", agg ); quoteAggregateForBookFooter.put( "9780970195081", agg ); quoteAggregateForBookFooter.put( "9780971004214", agg ); quoteAggregateForBookFooter.put( "9780972020701", agg ); quoteAggregateForBookFooter.put( "9780973110906", agg ); quoteAggregateForBookFooter.put( "9780973110920", agg ); quoteAggregateForBookFooter.put( "9780973311600", agg ); quoteAggregateForBookFooter.put( "9780973314007", agg ); quoteAggregateForBookFooter.put( "9780973314021", agg ); quoteAggregateForBookFooter.put( "9780973714715", agg ); quoteAggregateForBookFooter.put( "9780974060514", agg ); quoteAggregateForBookFooter.put( "9780975276310", agg ); quoteAggregateForBookFooter.put( "9781400030347", agg ); quoteAggregateForBookFooter.put( "9781400041510", agg ); quoteAggregateForBookFooter.put( "9781400047284", agg ); quoteAggregateForBookFooter.put( "9781400050666", agg ); quoteAggregateForBookFooter.put( "9781400061945", agg ); quoteAggregateForBookFooter.put( "9781400065783", agg ); quoteAggregateForBookFooter.put( "9781400065837", agg ); quoteAggregateForBookFooter.put( "9781400066766", agg ); quoteAggregateForBookFooter.put( "9781400067879", agg ); quoteAggregateForBookFooter.put( "9781400082773", agg ); quoteAggregateForBookFooter.put( "9781403963680", agg ); quoteAggregateForBookFooter.put( "9781410102034", agg ); quoteAggregateForBookFooter.put( "9781416569930", agg ); quoteAggregateForBookFooter.put( "9781451626650", agg ); quoteAggregateForBookFooter.put( "9781452817132", agg ); quoteAggregateForBookFooter.put( "9781552777305", agg ); quoteAggregateForBookFooter.put( "9781554701797", agg ); quoteAggregateForBookFooter.put( "9781560254058", agg ); quoteAggregateForBookFooter.put( "9781560254423", agg ); quoteAggregateForBookFooter.put( "9781560255024", agg ); quoteAggregateForBookFooter.put( "9781560255611", agg ); quoteAggregateForBookFooter.put( "9781560255697", agg ); quoteAggregateForBookFooter.put( "9781560255857", agg ); quoteAggregateForBookFooter.put( "9781560258520", agg ); quoteAggregateForBookFooter.put( "9781564148407", agg ); quoteAggregateForBookFooter.put( "9781566565523", agg ); quoteAggregateForBookFooter.put( "9781566565844", agg ); quoteAggregateForBookFooter.put( "9781566566599", agg ); quoteAggregateForBookFooter.put( "9781566566865", agg ); quoteAggregateForBookFooter.put( "9781567511949", agg ); quoteAggregateForBookFooter.put( "9781568584164", agg ); quoteAggregateForBookFooter.put( "9781574888621", agg ); quoteAggregateForBookFooter.put( "9781574889673", agg ); quoteAggregateForBookFooter.put( "9781576754634", agg ); quoteAggregateForBookFooter.put( "9781576756270", agg ); quoteAggregateForBookFooter.put( "9781583226445", agg ); quoteAggregateForBookFooter.put( "9781585422760", agg ); quoteAggregateForBookFooter.put( "9781586483142", agg ); quoteAggregateForBookFooter.put( "9781586484521", agg ); quoteAggregateForBookFooter.put( "9781586485566", agg ); quoteAggregateForBookFooter.put( "9781586486389", agg ); quoteAggregateForBookFooter.put( "9781590171523", agg ); quoteAggregateForBookFooter.put( "9781590512388", agg ); quoteAggregateForBookFooter.put( "9781591845539", agg ); quoteAggregateForBookFooter.put( "9781592090266", agg ); quoteAggregateForBookFooter.put( "9781593154813", agg ); quoteAggregateForBookFooter.put( "9781594200663", agg ); quoteAggregateForBookFooter.put( "9781594200984", agg ); quoteAggregateForBookFooter.put( "9781594201226", agg ); quoteAggregateForBookFooter.put( "9781594201868", agg ); quoteAggregateForBookFooter.put( "9781595550972", agg ); quoteAggregateForBookFooter.put( "9781595580665", agg ); quoteAggregateForBookFooter.put( "9781599869773", agg ); quoteAggregateForBookFooter.put( "9781608190362", agg ); quoteAggregateForBookFooter.put( "9781609803438", agg ); quoteAggregateForBookFooter.put( "9781859842584", agg ); quoteAggregateForBookFooter.put( "9781859843987", agg ); quoteAggregateForBookFooter.put( "9781859845011", agg ); quoteAggregateForBookFooter.put( "9781878825155", agg ); quoteAggregateForBookFooter.put( "9781883536060", agg ); quoteAggregateForBookFooter.put( "9781887128841", agg ); quoteAggregateForBookFooter.put( "9781888375510", agg ); quoteAggregateForBookFooter.put( "9781891053948", agg ); quoteAggregateForBookFooter.put( "9781905303649", agg ); quoteAggregateForBookFooter.put( "9781930722293", agg ); quoteAggregateForBookFooter.put( "9781931947053", agg ); agg = QuoteAggregate.PROGRAMMING; quoteAggregateForBookFooter.put( "9780060958336", agg ); quoteAggregateForBookFooter.put( "9780061093982", agg ); quoteAggregateForBookFooter.put( "9780061093999", agg ); quoteAggregateForBookFooter.put( "9780071350938", agg ); quoteAggregateForBookFooter.put( "9780071591065", agg ); quoteAggregateForBookFooter.put( "9780077072476", agg ); quoteAggregateForBookFooter.put( "9780077074326", agg ); quoteAggregateForBookFooter.put( "9780079136961", agg ); quoteAggregateForBookFooter.put( "9780123706430", agg ); quoteAggregateForBookFooter.put( "9780123743428", agg ); quoteAggregateForBookFooter.put( "9780123744791", agg ); quoteAggregateForBookFooter.put( "9780130115195", agg ); quoteAggregateForBookFooter.put( "9780130172969", agg ); quoteAggregateForBookFooter.put( "9780130183804", agg ); quoteAggregateForBookFooter.put( "9780130284464", agg ); quoteAggregateForBookFooter.put( "9780130676146", agg ); quoteAggregateForBookFooter.put( "9780130796660", agg ); quoteAggregateForBookFooter.put( "9780130801043", agg ); quoteAggregateForBookFooter.put( "9780130803603", agg ); quoteAggregateForBookFooter.put( "9780130804501", agg ); quoteAggregateForBookFooter.put( "9780130832924", agg ); quoteAggregateForBookFooter.put( "9780130850867", agg ); quoteAggregateForBookFooter.put( "9780130894083", agg ); quoteAggregateForBookFooter.put( "9780130897930", agg ); quoteAggregateForBookFooter.put( "9780130952493", agg ); quoteAggregateForBookFooter.put( "9780131103627", agg ); quoteAggregateForBookFooter.put( "9780131422469", agg ); quoteAggregateForBookFooter.put( "9780131482111", agg ); quoteAggregateForBookFooter.put( "9780131482609", agg ); quoteAggregateForBookFooter.put( "9780131489066", agg ); quoteAggregateForBookFooter.put( "9780131532717", agg ); quoteAggregateForBookFooter.put( "9780131872486", agg ); quoteAggregateForBookFooter.put( "9780131872844", agg ); quoteAggregateForBookFooter.put( "9780132158718", agg ); quoteAggregateForBookFooter.put( "9780132162708", agg ); quoteAggregateForBookFooter.put( "9780132575669", agg ); quoteAggregateForBookFooter.put( "9780132761611", agg ); quoteAggregateForBookFooter.put( "9780132923736", agg ); quoteAggregateForBookFooter.put( "9780133017601", agg ); quoteAggregateForBookFooter.put( "9780133033892", agg ); quoteAggregateForBookFooter.put( "9780136291558", agg ); quoteAggregateForBookFooter.put( "9780136798958", agg ); quoteAggregateForBookFooter.put( "9780137012893", agg ); quoteAggregateForBookFooter.put( "9780137081899", agg ); quoteAggregateForBookFooter.put( "9780138063320", agg ); quoteAggregateForBookFooter.put( "9780138577490", agg ); quoteAggregateForBookFooter.put( "9780139111815", agg ); quoteAggregateForBookFooter.put( "9780139194245", agg ); quoteAggregateForBookFooter.put( "9780140067484", agg ); quoteAggregateForBookFooter.put( "9780140128673", agg ); quoteAggregateForBookFooter.put( "9780140282023", agg ); quoteAggregateForBookFooter.put( "9780143037880", agg ); quoteAggregateForBookFooter.put( "9780201101799", agg ); quoteAggregateForBookFooter.put( "9780201143966", agg ); quoteAggregateForBookFooter.put( "9780201178883", agg ); quoteAggregateForBookFooter.put( "9780201305647", agg ); quoteAggregateForBookFooter.put( "9780201309553", agg ); quoteAggregateForBookFooter.put( "9780201309720", agg ); quoteAggregateForBookFooter.put( "9780201309805", agg ); quoteAggregateForBookFooter.put( "9780201325775", agg ); quoteAggregateForBookFooter.put( "9780201360653", agg ); quoteAggregateForBookFooter.put( "9780201379228", agg ); quoteAggregateForBookFooter.put( "9780201379372", agg ); quoteAggregateForBookFooter.put( "9780201379433", agg ); quoteAggregateForBookFooter.put( "9780201403534", agg ); quoteAggregateForBookFooter.put( "9780201432947", agg ); quoteAggregateForBookFooter.put( "9780201485394", agg ); quoteAggregateForBookFooter.put( "9780201485677", agg ); quoteAggregateForBookFooter.put( "9780201488371", agg ); quoteAggregateForBookFooter.put( "9780201498271", agg ); quoteAggregateForBookFooter.put( "9780201498370", agg ); quoteAggregateForBookFooter.put( "9780201514599", agg ); quoteAggregateForBookFooter.put( "9780201543308", agg ); quoteAggregateForBookFooter.put( "9780201570441", agg ); quoteAggregateForBookFooter.put( "9780201596076", agg ); quoteAggregateForBookFooter.put( "9780201612462", agg ); quoteAggregateForBookFooter.put( "9780201616224", agg ); quoteAggregateForBookFooter.put( "9780201619133", agg ); quoteAggregateForBookFooter.put( "9780201622775", agg ); quoteAggregateForBookFooter.put( "9780201633610", agg ); quoteAggregateForBookFooter.put( "9780201633856", agg ); quoteAggregateForBookFooter.put( "9780201634532", agg ); quoteAggregateForBookFooter.put( "9780201634594", agg ); quoteAggregateForBookFooter.put( "9780201657586", agg ); quoteAggregateForBookFooter.put( "9780201700435", agg ); quoteAggregateForBookFooter.put( "9780201702521", agg ); quoteAggregateForBookFooter.put( "9780201703535", agg ); quoteAggregateForBookFooter.put( "9780201708424", agg ); quoteAggregateForBookFooter.put( "9780201709063", agg ); quoteAggregateForBookFooter.put( "9780201709698", agg ); quoteAggregateForBookFooter.put( "9780201710915", agg ); quoteAggregateForBookFooter.put( "9780201725889", agg ); quoteAggregateForBookFooter.put( "9780201738292", agg ); quoteAggregateForBookFooter.put( "9780201750447", agg ); quoteAggregateForBookFooter.put( "9780201775822", agg ); quoteAggregateForBookFooter.put( "9780201889543", agg ); quoteAggregateForBookFooter.put( "9780201964264", agg ); quoteAggregateForBookFooter.put( "9780262693257", agg ); quoteAggregateForBookFooter.put( "9780321109293", agg ); quoteAggregateForBookFooter.put( "9780321173843", agg ); quoteAggregateForBookFooter.put( "9780321256171", agg ); quoteAggregateForBookFooter.put( "9780321278654", agg ); quoteAggregateForBookFooter.put( "9780321288158", agg ); quoteAggregateForBookFooter.put( "9780321303479", agg ); quoteAggregateForBookFooter.put( "9780321304780", agg ); quoteAggregateForBookFooter.put( "9780321333025", agg ); quoteAggregateForBookFooter.put( "9780321336330", agg ); quoteAggregateForBookFooter.put( "9780321336781", agg ); quoteAggregateForBookFooter.put( "9780321349606", agg ); quoteAggregateForBookFooter.put( "9780321349804", agg ); quoteAggregateForBookFooter.put( "9780321356680", agg ); quoteAggregateForBookFooter.put( "9780321480910", agg ); quoteAggregateForBookFooter.put( "9780321486813", agg ); quoteAggregateForBookFooter.put( "9780321556059", agg ); quoteAggregateForBookFooter.put( "9780321751041", agg ); quoteAggregateForBookFooter.put( "9780321769381", agg ); quoteAggregateForBookFooter.put( "9780321774095", agg ); quoteAggregateForBookFooter.put( "9780321813848", agg ); quoteAggregateForBookFooter.put( "9780380780471", agg ); quoteAggregateForBookFooter.put( "9780385199735", agg ); quoteAggregateForBookFooter.put( "9780385235693", agg ); quoteAggregateForBookFooter.put( "9780385267748", agg ); quoteAggregateForBookFooter.put( "9780393058505", agg ); quoteAggregateForBookFooter.put( "9780470084113", agg ); quoteAggregateForBookFooter.put( "9780470565520", agg ); quoteAggregateForBookFooter.put( "9780470891520", agg ); quoteAggregateForBookFooter.put( "9780471034650", agg ); quoteAggregateForBookFooter.put( "9780471165071", agg ); quoteAggregateForBookFooter.put( "9780471180418", agg ); quoteAggregateForBookFooter.put( "9780471197133", agg ); quoteAggregateForBookFooter.put( "9780471207665", agg ); quoteAggregateForBookFooter.put( "9780471251699", agg ); quoteAggregateForBookFooter.put( "9780471319528", agg ); quoteAggregateForBookFooter.put( "9780471389408", agg ); quoteAggregateForBookFooter.put( "9780471390657", agg ); quoteAggregateForBookFooter.put( "9780471941484", agg ); quoteAggregateForBookFooter.put( "9780486414546", agg ); quoteAggregateForBookFooter.put( "9780517527573", agg ); quoteAggregateForBookFooter.put( "9780521291804", agg ); quoteAggregateForBookFooter.put( "9780521777681", agg ); quoteAggregateForBookFooter.put( "9780521885409", agg ); quoteAggregateForBookFooter.put( "9780534950972", agg ); quoteAggregateForBookFooter.put( "9780553290028", agg ); quoteAggregateForBookFooter.put( "9780553342536", agg ); quoteAggregateForBookFooter.put( "9780553380163", agg ); quoteAggregateForBookFooter.put( "9780553384666", agg ); quoteAggregateForBookFooter.put( "9780586082768", agg ); quoteAggregateForBookFooter.put( "9780596000400", agg ); quoteAggregateForBookFooter.put( "9780596000455", agg ); quoteAggregateForBookFooter.put( "9780596001087", agg ); quoteAggregateForBookFooter.put( "9780596001230", agg ); quoteAggregateForBookFooter.put( "9780596001438", agg ); quoteAggregateForBookFooter.put( "9780596002374", agg ); quoteAggregateForBookFooter.put( "9780596002886", agg ); quoteAggregateForBookFooter.put( "9780596003777", agg ); quoteAggregateForBookFooter.put( "9780596004088", agg ); quoteAggregateForBookFooter.put( "9780596004200", agg ); quoteAggregateForBookFooter.put( "9780596004217", agg ); quoteAggregateForBookFooter.put( "9780596006099", agg ); quoteAggregateForBookFooter.put( "9780596006204", agg ); quoteAggregateForBookFooter.put( "9780596007126", agg ); quoteAggregateForBookFooter.put( "9780596007300", agg ); quoteAggregateForBookFooter.put( "9780596007348", agg ); quoteAggregateForBookFooter.put( "9780596007607", agg ); quoteAggregateForBookFooter.put( "9780596007737", agg ); quoteAggregateForBookFooter.put( "9780596007829", agg ); quoteAggregateForBookFooter.put( "9780596008765", agg ); quoteAggregateForBookFooter.put( "9780596008819", agg ); quoteAggregateForBookFooter.put( "9780596009076", agg ); quoteAggregateForBookFooter.put( "9780596009205", agg ); quoteAggregateForBookFooter.put( "9780596100506", agg ); quoteAggregateForBookFooter.put( "9780596100575", agg ); quoteAggregateForBookFooter.put( "9780596100650", agg ); quoteAggregateForBookFooter.put( "9780596101428", agg ); quoteAggregateForBookFooter.put( "9780596101497", agg ); quoteAggregateForBookFooter.put( "9780596155933", agg ); quoteAggregateForBookFooter.put( "9780596157623", agg ); quoteAggregateForBookFooter.put( "9780596158026", agg ); quoteAggregateForBookFooter.put( "9780596510299", agg ); quoteAggregateForBookFooter.put( "9780596510435", agg ); quoteAggregateForBookFooter.put( "9780596514273", agg ); quoteAggregateForBookFooter.put( "9780596515812", agg ); quoteAggregateForBookFooter.put( "9780596516680", agg ); quoteAggregateForBookFooter.put( "9780596522049", agg ); quoteAggregateForBookFooter.put( "9780596527082", agg ); quoteAggregateForBookFooter.put( "9780596527334", agg ); quoteAggregateForBookFooter.put( "9780596527402", agg ); quoteAggregateForBookFooter.put( "9780596527624", agg ); quoteAggregateForBookFooter.put( "9780596527754", agg ); quoteAggregateForBookFooter.put( "9780596528126", agg ); quoteAggregateForBookFooter.put( "9780672315855", agg ); quoteAggregateForBookFooter.put( "9780672319020", agg ); quoteAggregateForBookFooter.put( "9780672321825", agg ); quoteAggregateForBookFooter.put( "9780672322587", agg ); quoteAggregateForBookFooter.put( "9780672323997", agg ); quoteAggregateForBookFooter.put( "9780672324505", agg ); quoteAggregateForBookFooter.put( "9780672324536", agg ); quoteAggregateForBookFooter.put( "9780672326387", agg ); quoteAggregateForBookFooter.put( "9780674576186", agg ); quoteAggregateForBookFooter.put( "9780684039992", agg ); quoteAggregateForBookFooter.put( "9780684846149", agg ); quoteAggregateForBookFooter.put( "9780735610217", agg ); quoteAggregateForBookFooter.put( "9780735617797", agg ); quoteAggregateForBookFooter.put( "9780735619654", agg ); quoteAggregateForBookFooter.put( "9780735622180", agg ); quoteAggregateForBookFooter.put( "9780735665873", agg ); quoteAggregateForBookFooter.put( "9780743411462", agg ); quoteAggregateForBookFooter.put( "9780748619825", agg ); quoteAggregateForBookFooter.put( "9780764508820", agg ); quoteAggregateForBookFooter.put( "9780764558313", agg ); quoteAggregateForBookFooter.put( "9780764574832", agg ); quoteAggregateForBookFooter.put( "9780764576775", agg ); quoteAggregateForBookFooter.put( "9780764577048", agg ); quoteAggregateForBookFooter.put( "9780764596339", agg ); quoteAggregateForBookFooter.put( "9780782120974", agg ); quoteAggregateForBookFooter.put( "9780782144192", agg ); quoteAggregateForBookFooter.put( "9780805327205", agg ); quoteAggregateForBookFooter.put( "9780805860160", agg ); quoteAggregateForBookFooter.put( "9780823004898", agg ); quoteAggregateForBookFooter.put( "9780879305154", agg ); quoteAggregateForBookFooter.put( "9780887306297", agg ); quoteAggregateForBookFooter.put( "9780891348573", agg ); quoteAggregateForBookFooter.put( "9780961392147", agg ); quoteAggregateForBookFooter.put( "9780976221432", agg ); quoteAggregateForBookFooter.put( "9780976458708", agg ); quoteAggregateForBookFooter.put( "9780976694083", agg ); quoteAggregateForBookFooter.put( "9780977240616", agg ); quoteAggregateForBookFooter.put( "9780978638894", agg ); quoteAggregateForBookFooter.put( "9780980839616", agg ); quoteAggregateForBookFooter.put( "9780983386728", agg ); quoteAggregateForBookFooter.put( "9781430219200", agg ); quoteAggregateForBookFooter.put( "9781430226598", agg ); quoteAggregateForBookFooter.put( "9781435458086", agg ); quoteAggregateForBookFooter.put( "9781440456947", agg ); quoteAggregateForBookFooter.put( "9781449311520", agg ); quoteAggregateForBookFooter.put( "9781449318529", agg ); quoteAggregateForBookFooter.put( "9781449319243", agg ); quoteAggregateForBookFooter.put( "9781449396107", agg ); quoteAggregateForBookFooter.put( "9781449396794", agg ); quoteAggregateForBookFooter.put( "9781556154843", agg ); quoteAggregateForBookFooter.put( "9781558605169", agg ); quoteAggregateForBookFooter.put( "9781565921948", agg ); quoteAggregateForBookFooter.put( "9781565924024", agg ); quoteAggregateForBookFooter.put( "9781565924178", agg ); quoteAggregateForBookFooter.put( "9781565924529", agg ); quoteAggregateForBookFooter.put( "9781565924888", agg ); quoteAggregateForBookFooter.put( "9781565925366", agg ); quoteAggregateForBookFooter.put( "9781565925427", agg ); quoteAggregateForBookFooter.put( "9781565926165", agg ); quoteAggregateForBookFooter.put( "9781565927193", agg ); quoteAggregateForBookFooter.put( "9781568989693", agg ); quoteAggregateForBookFooter.put( "9781575211022", agg ); quoteAggregateForBookFooter.put( "9781576100561", agg ); quoteAggregateForBookFooter.put( "9781576101599", agg ); quoteAggregateForBookFooter.put( "9781579510657", agg ); quoteAggregateForBookFooter.put( "9781581804362", agg ); quoteAggregateForBookFooter.put( "9781584884309", agg ); quoteAggregateForBookFooter.put( "9781590590430", agg ); quoteAggregateForBookFooter.put( "9781590590782", agg ); quoteAggregateForBookFooter.put( "9781590592656", agg ); quoteAggregateForBookFooter.put( "9781590594797", agg ); quoteAggregateForBookFooter.put( "9781590595374", agg ); quoteAggregateForBookFooter.put( "9781590595596", agg ); quoteAggregateForBookFooter.put( "9781590596937", agg ); quoteAggregateForBookFooter.put( "9781590598177", agg ); quoteAggregateForBookFooter.put( "9781592730056", agg ); quoteAggregateForBookFooter.put( "9781593272869", agg ); quoteAggregateForBookFooter.put( "9781598639735", agg ); quoteAggregateForBookFooter.put( "9781844804184", agg ); quoteAggregateForBookFooter.put( "9781846283444", agg ); quoteAggregateForBookFooter.put( "9781846289620", agg ); quoteAggregateForBookFooter.put( "9781849685627", agg ); quoteAggregateForBookFooter.put( "9781850329220", agg ); quoteAggregateForBookFooter.put( "9781861000880", agg ); quoteAggregateForBookFooter.put( "9781861003645", agg ); quoteAggregateForBookFooter.put( "9781884777493", agg ); quoteAggregateForBookFooter.put( "9781884777653", agg ); quoteAggregateForBookFooter.put( "9781890774448", agg ); quoteAggregateForBookFooter.put( "9781893115026", agg ); quoteAggregateForBookFooter.put( "9781893115101", agg ); quoteAggregateForBookFooter.put( "9781930110120", agg ); quoteAggregateForBookFooter.put( "9781930110885", agg ); quoteAggregateForBookFooter.put( "9781932394580", agg ); quoteAggregateForBookFooter.put( "9781932394801", agg ); quoteAggregateForBookFooter.put( "9781932394887", agg ); quoteAggregateForBookFooter.put( "9781933988139", agg ); quoteAggregateForBookFooter.put( "9781936280063", agg ); quoteAggregateForBookFooter.put( "9782970036906", agg ); quoteAggregateForBookFooter.put( "9783540425809", agg ); quoteAggregateForBookFooter.put( "9783540541523", agg ); quoteAggregateForBookFooter.put( "9783827323613", agg ); quoteAggregateForBookFooter.put( "9783898428385", agg ); agg = QuoteAggregate.RELIGION; quoteAggregateForBookFooter.put( "9780060000738", agg ); quoteAggregateForBookFooter.put( "9780060738174", agg ); quoteAggregateForBookFooter.put( "9780062012616", agg ); quoteAggregateForBookFooter.put( "9780062504081", agg ); quoteAggregateForBookFooter.put( "9780140283891", agg ); quoteAggregateForBookFooter.put( "9780140481389", agg ); quoteAggregateForBookFooter.put( "9780141026169", agg ); quoteAggregateForBookFooter.put( "9780195157420", agg ); quoteAggregateForBookFooter.put( "9780306816086", agg ); quoteAggregateForBookFooter.put( "9780306817502", agg ); quoteAggregateForBookFooter.put( "9780307265777", agg ); quoteAggregateForBookFooter.put( "9780307275639", agg ); quoteAggregateForBookFooter.put( "9780307377906", agg ); quoteAggregateForBookFooter.put( "9780307379108", agg ); quoteAggregateForBookFooter.put( "9780307949301", agg ); quoteAggregateForBookFooter.put( "9780310209300", agg ); quoteAggregateForBookFooter.put( "9780310234692", agg ); quoteAggregateForBookFooter.put( "9780316734912", agg ); quoteAggregateForBookFooter.put( "9780345349248", agg ); quoteAggregateForBookFooter.put( "9780345409461", agg ); quoteAggregateForBookFooter.put( "9780345450401", agg ); quoteAggregateForBookFooter.put( "9780385336536", agg ); quoteAggregateForBookFooter.put( "9780393327656", agg ); quoteAggregateForBookFooter.put( "9780405036255", agg ); quoteAggregateForBookFooter.put( "9780415472388", agg ); quoteAggregateForBookFooter.put( "9780415473705", agg ); quoteAggregateForBookFooter.put( "9780415487375", agg ); quoteAggregateForBookFooter.put( "9780440136484", agg ); quoteAggregateForBookFooter.put( "9780446579803", agg ); quoteAggregateForBookFooter.put( "9780486440279", agg ); quoteAggregateForBookFooter.put( "9780517345825", agg ); quoteAggregateForBookFooter.put( "9780521618243", agg ); quoteAggregateForBookFooter.put( "9780553263589", agg ); quoteAggregateForBookFooter.put( "9780553263824", agg ); quoteAggregateForBookFooter.put( "9780553354249", agg ); quoteAggregateForBookFooter.put( "9780618680009", agg ); quoteAggregateForBookFooter.put( "9780664231170", agg ); quoteAggregateForBookFooter.put( "9780670034727", agg ); quoteAggregateForBookFooter.put( "9780670034864", agg ); quoteAggregateForBookFooter.put( "9780671203238", agg ); quoteAggregateForBookFooter.put( "9780671219819", agg ); quoteAggregateForBookFooter.put( "9780679744061", agg ); quoteAggregateForBookFooter.put( "9780684801582", agg ); quoteAggregateForBookFooter.put( "9780684824710", agg ); quoteAggregateForBookFooter.put( "9780738712772", agg ); quoteAggregateForBookFooter.put( "9780743284431", agg ); quoteAggregateForBookFooter.put( "9780767920667", agg ); quoteAggregateForBookFooter.put( "9780805070897", agg ); quoteAggregateForBookFooter.put( "9780805083064", agg ); quoteAggregateForBookFooter.put( "9780807029565", agg ); quoteAggregateForBookFooter.put( "9780809142477", agg ); quoteAggregateForBookFooter.put( "9780879757427", agg ); quoteAggregateForBookFooter.put( "9780887621956", agg ); quoteAggregateForBookFooter.put( "9780887842122", agg ); quoteAggregateForBookFooter.put( "9780913990056", agg ); quoteAggregateForBookFooter.put( "9780937958162", agg ); quoteAggregateForBookFooter.put( "9780970950512", agg ); quoteAggregateForBookFooter.put( "9780970950543", agg ); quoteAggregateForBookFooter.put( "9780979963117", agg ); quoteAggregateForBookFooter.put( "9780984493210", agg ); quoteAggregateForBookFooter.put( "9780985281526", agg ); quoteAggregateForBookFooter.put( "9781412034814", agg ); quoteAggregateForBookFooter.put( "9781412080125", agg ); quoteAggregateForBookFooter.put( "9781439192818", agg ); quoteAggregateForBookFooter.put( "9781451610369", agg ); quoteAggregateForBookFooter.put( "9781455523009", agg ); quoteAggregateForBookFooter.put( "9781554700875", agg ); quoteAggregateForBookFooter.put( "9781559708203", agg ); quoteAggregateForBookFooter.put( "9781563990168", agg ); quoteAggregateForBookFooter.put( "9781565849204", agg ); quoteAggregateForBookFooter.put( "9781570625190", agg ); quoteAggregateForBookFooter.put( "9781570972034", agg ); quoteAggregateForBookFooter.put( "9781577314806", agg ); quoteAggregateForBookFooter.put( "9781578633081", agg ); quoteAggregateForBookFooter.put( "9781579510374", agg ); quoteAggregateForBookFooter.put( "9781579510381", agg ); quoteAggregateForBookFooter.put( "9781579510596", agg ); quoteAggregateForBookFooter.put( "9781581345612", agg ); quoteAggregateForBookFooter.put( "9781591020653", agg ); quoteAggregateForBookFooter.put( "9781591024811", agg ); quoteAggregateForBookFooter.put( "9781604244274", agg ); quoteAggregateForBookFooter.put( "9781605981109", agg ); quoteAggregateForBookFooter.put( "9781616144050", agg ); quoteAggregateForBookFooter.put( "9781880418116", agg ); quoteAggregateForBookFooter.put( "9781933330174", agg ); agg = QuoteAggregate.GENERAL; quoteAggregateForBookFooter.put( "books", agg ); } /** * get next file in a cycle of files. * * @param cycle array of filenames without .html or directory. * @param name filename without .html or directory * * @return relative link to next filename, e.g. filename without directory but with .html */ private static String nextInCycle( final String[] cycle, final String name ) { for ( int i = 0; i < cycle.length; i++ ) { if ( cycle[ i ].equals( name ) ) { if ( i == cycle.length - 1 ) { // wrap around to beginning return cycle[ 0 ] + ".html"; } else { return cycle[ i + 1 ] + ".html"; } } } // fell out bottom without finding it. throw new IllegalArgumentException( "Bad nextInCycle config: name " + name + " not found in assigned cycle " + cycle[ 0 ] ); }// /method /** * get next file a KJV file. * * @param fileBeingDistributed file currently being processed * * @return relative link to next filename, null if this is not a kjv file. */ private static String nextInKJV( File fileBeingDistributed ) { // might be: // kjv.index.html -- master chronological index // kjv.alpha.html -- master alpha index // kjv/Genesis/index.html -- chapter index // kjv/Genesis/1.html -- actual chapter final String webrootName = Tools.uPathName( fileBeingDistributed ); if ( !webrootName.startsWith( "kjv/" ) ) { return null; } if ( webrootName.equals( "kjv/index.html" ) ) { return "Genesis/index.html"; } else if ( webrootName.equals( "kjv/alpha.html" ) ) { return "index.html"; } int place = webrootName.indexOf( '/', 4 ); if ( place >= 0 ) { // have name like kvj/Hosea/1.html final String book = webrootName.substring( 4, place ); BibleBook b; try { b = BibleBook.valueOfAlias( book ); } catch ( IllegalArgumentException e ) { throw new IllegalArgumentException( "unrecognised BibleBook file " + fileBeingDistributed ); } final String possChapter = EIO.getCoreName( fileBeingDistributed ); if ( possChapter.equals( "index" ) ) { return "1.html"; } // should have nn.html chapter final int chapter = Integer.parseInt( possChapter ); final int nextChapter = chapter + 1; if ( nextChapter <= b.getChapters() ) { return nextChapter + ".html"; } else { // last chapter in book, jump to index next book final int books = BibleBook.values().length; final int nextBookOrdinal = b.ordinal() + 1; if ( nextBookOrdinal < books ) { // go to index next book. final BibleBook nextBook = BibleBook.values()[ nextBookOrdinal ]; return "../" + nextBook.toString() + "/index.html"; } else { // back around to master index // this is not the home page. return "../index.html"; } } } else { throw new IllegalArgumentException( "unrecognised BibleBook file " + fileBeingDistributed ); } }// /method /** * get previous file in a cycle of files. * * @param cycle array of filenames without .html or directory. * @param name filename without .html or directory * * @return relative link to prev filename, e.g. filename without directory but with .html */ private static String prevInCycle( final String[] cycle, final String name ) { for ( int i = 0; i < cycle.length; i++ ) { if ( cycle[ i ].equals( name ) ) { if ( i == 0 ) { // wrap around from beginning back to end. return cycle[ cycle.length - 1 ] + ".html"; } else { return cycle[ i - 1 ] + ".html"; } } } // fell out bottom without finding it. throw new IllegalArgumentException( "Bad prevInCycle config: name " + name + " not found in assigned cycle " + cycle[ 0 ] ); }// /method /** * get prev file for KJV file. * * @param fileBeingDistributed file currently being processed * * @return relative link to prev filename, null if this is not a kjv file. */ private static String prevInKJV( File fileBeingDistributed ) { // might be: // kjv.index.html -- master chronological index // kjv.alpha.html -- master alpha index // kjv/Genesis/index.html -- chapter index // kjv/Genesis/1.html -- actual chapter final String webrootName = Tools.uPathName( fileBeingDistributed ); if ( !webrootName.startsWith( "kjv/" ) ) { return null; } if ( webrootName.equals( "kjv/index.html" ) ) { return "Revelation/22.html"; } else if ( webrootName.equals( "kjv/alpha.html" ) ) { return "index.html"; } int place = webrootName.indexOf( '/', 4 ); if ( place >= 0 ) { // have name like kjv/Hosea/1.html final String book = webrootName.substring( 4, place ); BibleBook b; try { b = BibleBook.valueOfAlias( book ); } catch ( IllegalArgumentException e ) { throw new IllegalArgumentException( "unrecognised BibleBook file " + fileBeingDistributed ); } final String possChapter = EIO.getCoreName( fileBeingDistributed ); if ( possChapter.equals( "index" ) ) { final int prevBookOrdinal = b.ordinal() - 1; if ( prevBookOrdinal >= 0 ) { final BibleBook prevBook = BibleBook.values()[ prevBookOrdinal ]; // go to last chapter of prev book return "../" + prevBook.toString() + "/" + prevBook.getChapters() + ".html"; } else { // is no previous book, go to master index // this is not the home page return "../index.html"; } } // should be nn.html chapter file final int chapter = Integer.parseInt( possChapter ); final int prevChapter = chapter - 1; if ( prevChapter >= 1 ) { return prevChapter + ".html"; } else { // first chapter in book, jump index for chapter return "index.html"; } } else { throw new IllegalArgumentException( "unrecognised BibleBook file " + fileBeingDistributed ); } }// /method /** * get previous or next file in a cycle of files. * * @param cycle array of filenames without .html or directory. * @param name filename without .html or directory * @param calcNext true if calc next rather than prev page. * * @return relative link to prev filename, e.g. filename without directory but with .html */ private static String prevOrNextInCycle( final String[] cycle, final String name, final boolean calcNext ) { return calcNext ? nextInCycle( cycle, name ) : prevInCycle( cycle, name ); }// /method private QuoteAggregate getQuoteAggregateCanadaFooter( final String coreName ) { switch ( coreName ) { case "remembrance": return QuoteAggregate.REMEMBRANCE; default: return QuoteAggregate.CANADA; } } @NotNull private QuoteAggregate getQuoteAggregateElectronicFooter( final String coreName ) { switch ( coreName ) { case "B000ER1G3E": case "B000FJ9SUO": case "B000GWG0T2": case "B000LCPVMY": case "B002R90N7W": case "B004KAA6KK": case "B0051H6330": case "B0054JJ0QW": return QuoteAggregate.GENERAL; default: return QuoteAggregate.PROGRAMMING; } } @NotNull private QuoteAggregate getQuoteAggregateForBookFooter( final String coreName ) { if ( quoteAggregateForBookFooter.size() == 0 ) { initQuoteAggregateForBookFooter(); // for some reason static init does not work. } final QuoteAggregate aggregate = quoteAggregateForBookFooter.get( coreName ); if ( aggregate != null ) { return aggregate; } else { return QuoteAggregate.GENERAL; } } @NotNull private QuoteAggregate getQuoteAggregateForDVDFooter( final String coreName ) { switch ( coreName ) { case "024543613336": case "094922891136": case "097363480846": case "097363480860": case "634479999642": case "689076361026": case "698193208893": case "698452207230": case "774212106378": case "826262006792": case "841887010214": return QuoteAggregate.ENVIRONMENT; case "767685975633": case "796019795128": case "796019799119": case "858423001711": return QuoteAggregate.GAY; case "698452208732": case "717119830342": case "795975106535": case "826262001896": case "876964003568": case "881394108820": return QuoteAggregate.MONEY; case "011301646330": case "031398105374": case "031398131212": case "031398169321": case "031398209119": case "043396086708": case "045778667192": case "720229910576": case "727994754022": case "767685158869": case "767685169490": case "767685253335": case "767685262795": case "795975101332": case "796019807500": case "826262000493": case "826262000592": case "826262004491": case "829567077429": case "829567078723": case "881751501660": case "897246001201": return QuoteAggregate.POLITICS; case "031398210702": case "837101074865": case "882224444477": return QuoteAggregate.RELIGION; default: return QuoteAggregate.GENERAL; } } private QuoteAggregate getQuoteAggregateHumanRightsFooter( final String coreName ) { switch ( coreName ) { case "abortion": return QuoteAggregate.ABORTION; default: return QuoteAggregate.POLITICS; } } private QuoteAggregate getQuoteAggregatePoliticsFooter( final String coreName ) { switch ( coreName ) { case "israel": return QuoteAggregate.ISRAEL; default: return QuoteAggregate.POLITICS; } } /** * Do we need to regenerate this file even if generated recently successfully and not changed since then. * * @param fileBeingDistributed file with embedded macros. * * @return tre if should force regeneration */ public boolean alwaysRegenerate( File fileBeingDistributed ) { switch ( Tools.uPathName( fileBeingDistributed ) ) { case "book/books.html": case "dvd/dvds.html": case "electronic/electronics.html": return true; default: return false; } }// /method /** * get URL of corresponding blog for this page, possibly empty. * * @param fileBeingDistributed the file currently being processed. * * @return Url to blog, or "" */ @Override public String blogForPage( File fileBeingDistributed ) { // all my blogs are gone return ""; }// /method /** * Figure out which page comes next. * * @param fileBeingDistributed the file currently being processed. * * @return relative link to the next page, null if no logical next page. */ public String calcNextPage( final File fileBeingDistributed ) { return calcPrevOrNextPage( fileBeingDistributed, true ); }// /method /** * Figure out which page comes before this one. * * @param fileBeingDistributed the file currently being processed. * * @return relative link to the previous page, null if no logical next page. */ public String calcPrevPage( final File fileBeingDistributed ) { return calcPrevOrNextPage( fileBeingDistributed, false ); }// /method /** * get uPath of corresponding feedback page for this page, defaulting to feedback/feedback.html, * not empty. * * @param fileBeingDistributed the file currently being processed. * * @return webroot relative corresponding feedback page. */ @Override public String correspondingFeedbackPage( File fileBeingDistributed ) { final String dir = Tools.dirWithSlashes( fileBeingDistributed ); switch ( dir ) { case "canada": case "feedback/peace": case "politics": return "feedback/peace/peace.html"; case "feedback/unmain": return "feedback/unmain/unmain.html"; case "animalrights": case "feedback/animalrights": return "feedback/animals/animals.html"; case "deepthoughts": case "feedback/hallucination": return "feedback/hallucination/hallucination.html"; case "environment": case "feedback/environment": return "feedback/environment/environment.html"; case "feedback/money": case "money": return "feedback/money/money.html"; case "ethics": case "feedback/god": case "kjv": case "religion": return "feedback/god/god.html"; case "feedback/porn": return "feedback/porn/porn.html"; case "humanrights": if ( fileBeingDistributed.getName().startsWith( "porn" ) ) { return "feedback/porn/porn.html"; } else { return "feedback/feedback.html"; } default: // ggloss, bgloss, applets, project ... return "feedback/feedback.html"; } }// /method /** * @return AllPosters.com affiliate account number, aid, not account number, */ @Override public int getAccountForAllpostersCom() { return 1025105019; }// /method /** * @return account number for amazon.ca bookstore, null if none. */ @Override public String getAccountForAmazonCa() { return "canadianmin07-20"; }// /method /** * @return account number for amazon.cn China bookstore, null if none. */ @Override public String getAccountForAmazonCn() { return "canamindprod-23"; }// /method /** * @return account number for amazon.com bookstore, null if none. */ @Override public String getAccountForAmazonCom() { return "canadianmindprod"; }// /method /** * @return account number for amazon.de bookstore, null if none. */ @Override public String getAccountForAmazonDe() { return "canadianmin0b-21"; }// /method /** * @return account number for amazon.es bookstore, null if none. */ @Override public String getAccountForAmazonEs() { return "httpmindprcom-21"; // yes with http }// /method /** * @return account number for amazon.fr bookstore, null if none. */ @Override public String getAccountForAmazonFr() { return "canamindprod-21"; }// /method /** * @return account number for amazon.it bookstore, null if none. */ @Override public String getAccountForAmazonIt() { return "httpmindprc0b-21"; }// /method /** * @return account number for amazon.uk bookstore, null if none. */ @Override public String getAccountForAmazonUk() { return "canadianmindp-21"; }// /method /** * @return Art.com affiliate account number. PID, always an integer m */ @Override public int getAccountForArtCom() { return 15035854; }// /method /** * @return account number for Barnes and Noble bookstore */ @Override public String getAccountForBarnesAndNoble() { return "vSCiQT/Cnuo"; // handled by LinkSys. vendor encoded in offerid }// /method /** * @return account number, aka PID, for chapters indigo bookstore, null if none. */ @Override public String getAccountForChaptersIndigo() { return null; /* was "2358048"; CJ rejected us */ }// /method /** * @return Google adSense account number. cmp google account "ca-pub-7275336356867641" Randy Richardson's google * account * "ca0-pub-3625079171090429" . We use his account in return for free website hosting. */ @Override public String getAccountForGoogleAdsense() { return "ca-pub-7275336356867641"; }// /method /** * @return Google Custom Search Engine Account#. */ public String getAccountForGoogleCSE() { return "005260666645288681202"; }// /method /** * get junglee.com account # * * @return account number for junglee.com (amazon india) bookstore, null if none. Only Indian residents may be affiliates. */ public String getAccountForJungleeCom() { return null; }// /method /** * @return account number for Kobo */ @Override public String getAccountForKobo() { return "vSCiQT/Cnuo"; // handled by LinkSys. vendor encoded in offerid. also has Google id }// /method /** * @return account number for Powells bookstore, 0 if none. */ @Override public String getAccountForPowells() { return "28995"; }// /method /** * @return account number for TigerDirect.ca */ @Override public String getAccountForTigerDirectCa() { return "vSCiQT/Cnuo:234830"; // handled by LinkSys. vendor encoded in offerid }// /method /** * @return account number for TigerDirect.ca */ @Override public String getAccountForTigerDirectCom() { return "vSCiQT/Cnuo:272649"; // handled by LinkSys. vendor encoded in offerid }// /method /** * @return account name for WebRing, null if none. */ @Override public String getAccountForWebring() { return "roedygr"; }// /method /** * @return NCIX canada affiliate number. PID, always an integer in string form */ @Override public String getAccountNCIXCaCom() { return "11195336"; }// /method /** * @return NCIX us affiliate number. PID, always an integer in string form */ @Override public String getAccountNCIXUsCom() { return "11195336"; }// /method /** * get age in millis of changes to web pages that would be unpected. When age is longer than this we * display how the page changed for analysis. Recent changes from edits are expected. * * @return age in miliis */ public long getAgeOfUnexpectedChanges() { return TimeUnit.MINUTES.toMillis( 45 ); }// /method /** * get CSS configuring configuration */ public AssignCSSClasses getAssignCSSClasses() { if ( assignCSSClasses == null ) { assignCSSClasses = new AssignCSSClassesForMindprodCa(); } return assignCSSClasses; } /** * @return default author for web pages */ @Override public String getAuthor() { return "Roedy Green"; }// /method /** * @return name of the code signing cert without .cer, possibly self-signed. e.g. "mindprodcert2017rsa"; */ @Override public String getCodeSigningCert() { return Build.MINDPRODCERT; }// /method /** * @return *=compactStringStrippingMacrosAndComments, with separate masters * +=compactStringKeepingMacrosAndComments, classical, expand macros in place. * -=does nothing * Q=Quick If first 400 chars contain a double space, compactStringKeepingMacrosAndComments, * otherwise do nothing. */ @Override public char getCompacting() { return '+'; }// /method /** * convert a webrootroot relative UNL to an absolute URL to the corresponding page on the companion website * * @param webrootRelative e.g. bgloss/dsk.html such as would be passed to Link, with / * * @return http://mindprod.com/bgloss/dsk.html or null if no equivalent */ public String getCompanionURL( final String webrootRelative ) { final String companion = "http://mindprod.com/" + webrootRelative; final int p1 = webrootRelative.indexOf( '/' ); if ( p1 < 0 ) { // in root dir switch ( webrootRelative ) { case "products.html": return companion; default: return null; } } switch ( webrootRelative.substring( 0, p1 ) ) { case "applet": case "application": case "bgloss": case "esperanto": case "jgloss": case "phone": case "project": case "utility": case "webstart": return companion; case "feedback": int p2 = webrootRelative.indexOf( '/', p1 + 1 ); if ( p2 < 0 ) { return null; } switch ( webrootRelative.substring( p1 + 1, p2 ) ) { case "unmain": return companion; default: return null; } default: return null; } } /** * @return corporate logo. Stored in image/logo as .png or .jpg file * @see #getCompanyName * @see #getCompanyNameFancyHtml */ @Override public String getCompanyLogo() { return "cmpmartylogomid.png"; }// /method /** * @return company responsible for the web pages, hard coded in */ @Override public String getCompanyName() { return "Canadian Mind Products"; }// /method /** * @return Company responsible for the web pages * Prettified as you please with HTML. */ @Override public String getCompanyNameFancyHtml() { return "Canadian\nMind\n" + "Products"; }// /method /** * @return phone number of webmaster as a string, no format restrictions. */ @Override public String getCompanyPhone() { return "(250) 361-9093"; }// /method /** * get name copyrightholder for this page * * @param fileBeingDistributed the file currently being processed. * * @return Case-sensitive name of copyright holder for this page. Might contain some markup or entities. * @see #getFirstCopyrightYear */ public String getCopyrightHolderForPage( final File fileBeingDistributed ) { final String dir = Tools.dirWithSlashes( fileBeingDistributed ); final String grandparent; int place = dir.indexOf( '/' ); if ( place >= 0 ) { grandparent = dir.substring( 0, place ); } else { grandparent = dir; } place = dir.lastIndexOf( '/' ); final String parent; if ( place >= 0 ) { parent = dir.substring( place + 1 ); } else { parent = dir; } final String coreName = EIO.getCoreName( fileBeingDistributed ); if ( parent.equals( "animalrights" ) && coreName.equals( "watson" ) ) { return "Captain Paul Watson of the Sea Shepherd Society"; } else if ( parent.equals( "blurb" ) && coreName.equals( "blurb" ) ) { return "Roedy Green"; } else if ( parent.equals( "handbook" ) ) { return "Living Love Center"; } else if ( grandparent.equals( "kjv" ) || parent.equals( "kjv" ) ) { return "public domain"; /* not copyrighted */ } else if ( parent.equals( "politics" ) && fileBeingDistributed.getName().equals( "grass.html" ) ) { return "Günter Grass"; } else if ( parent.equals( "politics" ) && coreName.equals( "wounds" ) ) { return "Dr. Norman Bethune"; } else if ( parent.equals( "religion" ) && coreName.equals( "notchristian" ) ) { return "Bertrand Russell"; } else { return "Roedy Green of Canadian Mind Products"; } }// /method /** * @return array of Directories containing HTML files with macros. Does not include redir, includes, kjv, * snippets, rss * since these do not include HTML needing macro expansion. * All Live in E:\mindprodCa\ */ @Override public List getDirsContainingHTMLMacros() { return Collections.unmodifiableList( Arrays.asList( HTML_DIRS ) ); }// /method /** * @return include Directories containing included HTML files. Distributed. All Live in E:\mindprodCa\ */ @Override public List getDirsContainingIncludes() { return Collections.unmodifiableList( Arrays.asList( INCLUDE_DIRS ) ); }// /method /** * get snippet dirs * * @return array of Directories containing snippet dirs, webroot relative. * JPrep uses the command line, not this. */ public List getDirsContainingSnippets() { return Collections.unmodifiableList( Arrays.asList( DIRS_CONTAINING_SNIPPETS ) ); }// /method /** * get dirs that need to be seesorted * * @return array of Directories that are * seesortad. All Live in E:\mindprod\ */ public List getDirsToSeeSort() { return Collections.unmodifiableList( Arrays.asList( DIRS_TO_SEESORT ) ); }// /method /** * get dirs with hit counts macro expansion * * @return array of Directories that have hit counts. Does not include redir, includes, snippets, rss * includes kjv * All Live in E:\mindprodCa\ */ @Override public List getDirsWithHitCounts() { ArrayList join = new ArrayList<>( HTML_DIRS.length + KJV_DIRS_ALPHABETICALLY.length ); join.addAll( Arrays.asList( HTML_DIRS ) ); for ( String dir : KJV_DIRS_ALPHABETICALLY ) { join.add( "kjv/" + dir ); } return Collections.unmodifiableList( join ); }// /method /** * @param fileBeingDistributed the file we are generating * * @return Case-sensitive default doctype+ to got at the top of generated webpages. */ public String getDoctypeDefault( final File fileBeingDistributed ) { return "\n"; }// /method /** * as part of your configuring, you will also likely want to use a * completely different header and footer macro, perhaps giving them different names from mine, e.g. * Header and Footer. You will want to modify the various header macros and invent your * own. * * @param fileBeingDistributed the file we are generating * * @return Case-sensitive frame doctype+ to be used on frames */ @Override public String getDoctypeForFrame( final File fileBeingDistributed ) { return "\n"; }// /method /** * @param fileBeingDistributed the file we are generating * * @return Case-sensitive frame doctype+ for iframe snippets */ @Override public String getDoctypeForIframe( final File fileBeingDistributed ) { // use HTML5 if enclosing doc is html5 return "\n"; }// /method /** * How frequently do we rotate the a Quotation embedded in a page? Customise frequency of rotation for different * types of pages on the website. * * @param fileBeingDistributed the file currently being processed. * * @return rotation interval in milliseconds. */ @Override public long getEmbeddedQuotationRotateIntervalInMillis( File fileBeingDistributed ) { // just name with ext, no dir. final String coreName = EIO.getCoreName( fileBeingDistributed ); // rotate ad more frequently on major pages. if ( MAJOR_PAGES_SET.contains( coreName ) ) { return ROTATE_INTERVAL_MAJOR_EMBEDDED_QUOTATION_IN_MILLIS; } // get dir name without lead E:\mindprodca or \ and without trailing \, just embedded. final String dir = Tools.dirWithSlashes( fileBeingDistributed ); // handle index.html in root dir // only the root index.html counts as major if ( coreName.equals( "index" ) && dir.length() == 0 ) { return ROTATE_INTERVAL_MAJOR_EMBEDDED_QUOTATION_IN_MILLIS; } else if ( dir.startsWith( "kjv" ) ) { // handle kjv tree return ROTATE_INTERVAL_KJV_EMBEDDED_QUOTATION_IN_MILLIS; } else { return ROTATE_INTERVAL_MINOR_EMBEDDED_QUOTATION_IN_MILLIS; } }// /method /** * @return first year this page was copyright if not otherwise specified * @see #getCopyrightHolderForPage */ @Override public int getFirstCopyrightYear( File fileBeingDistributed ) { final String coreName = EIO.getCoreName( fileBeingDistributed ); final String dir = Tools.dirWithSlashes( fileBeingDistributed ); final String grandparent; int place = dir.indexOf( '/' ); if ( place >= 0 ) { grandparent = dir.substring( 0, place ); } else { grandparent = dir; } place = dir.lastIndexOf( '/' ); final String parent; if ( place >= 0 ) { parent = dir.substring( place + 1 ); } else { parent = dir; } // carol handled by CarolHead if ( grandparent.equals( "kjv" ) || parent.equals( "kjv" ) ) { return 0; /* not copyrighted */ } else if ( parent.equals( "encoding" ) ) { return 2013; } else if ( parent.equals( "song" ) ) { return 2009; } else if ( parent.equals( "quote" ) ) { return 2008; } else if ( coreName.startsWith( "iraq" ) ) { return 2002; } else if ( coreName.startsWith( "bush911" ) ) { return 2001; } else if ( coreName.startsWith( "bushbooks" ) || coreName.startsWith( "unmain" ) || parent.equals( "god" ) || parent.equals( "money" ) || parent.equals( "peace" ) || parent.equals( "porn" ) || parent.equals( "politics" ) || parent.equals( "canada" ) ) { return 2000; } else if ( parent.equals( "animalrights" ) ) { if ( coreName.equals( "watson" ) ) { return 2014; } else { return 1998; } } else if ( parent.equals( "ggloss" ) ) { return 1997; } else if ( parent.equals( "handbook" ) ) { return 1975; } else if ( parent.equals( "blurb" ) || fileBeingDistributed.getName().equals( "blurb.html" ) ) { return 1971; } else if ( parent.equals( "politics" ) && fileBeingDistributed.getName().equals( "grass.html" ) ) { return 2012; } else if ( parent.equals( "politics" ) && fileBeingDistributed.getName().equals( "wounds.html" ) ) { return 1940; } else if ( parent.equals( "religion" ) && fileBeingDistributed.getName().equals( "notchristian.html" ) ) { return 1927; } else { return 1996; } }// /method /** * How frequently do we rotate the PSA ad/quotation on a given page? Customise frequency of rotation for different * types of pages on the website. Also how often permit flip psa <--> quotation. * * @param fileBeingDistributed the file currently being processed. * * @return rotation interval in milliseconds. * @see #getQuoteAggregateForFooter(File) */ @Override public long getFooterRotateIntervalInMillis( File fileBeingDistributed ) { // just name with ext, no dir. final String coreName = EIO.getCoreName( fileBeingDistributed ); // rotate ad more frequently on major pages. if ( MAJOR_PAGES_SET.contains( coreName ) ) { return ROTATE_INTERVAL_MAJOR_FOOTER_IN_MILLIS; } // get dir name without lead E:\mindprodca or \ and without trailing \, just embedded. final String dir = Tools.dirWithSlashes( fileBeingDistributed ); // handle index.html in root dir // only the root index.html counts as major if ( coreName.equals( "index" ) && dir.length() == 0 ) { return ROTATE_INTERVAL_MAJOR_FOOTER_IN_MILLIS; } else if ( dir.startsWith( "kjv" ) ) { // handle kjv tree return ROTATE_INTERVAL_KJV_FOOTER_IN_MILLIS; } else { return ROTATE_INTERVAL_MINOR_FOOTER_IN_MILLIS; } }// /method /** * get a list of the glossary customisers that need indexing * * @return array of AbstractGlossCustomisers */ public AbstractGlossCustomiser[] getGlossCustomisers() { return new AbstractGlossCustomiser[] { // Darwin glossary new DglossCustomiser(), // environmental glossary new EglossCustomiser(), // gay glossary new GglossCustomiser(), // living love glossary new LglossCustomiser() }; } /** * @return tallest we allow an image to be to use in a page header */ @Override public int getHeaderImageMaxHeight() { return 400; }// /method /** * @return widest we allow an image to be to use in a page header */ @Override public int getHeaderImageMaxWidth() { return 900; }// /method /** * get language of the webpages e.g. "en-CA" * * @return fr-FR en-CA en-US etc. */ public String getLanguage( File fileBeingDistributed ) { final String dir = Tools.dirWithSlashes( fileBeingDistributed ); return dir.equals( "livinglove/handbook" ) ? "en-US" : "en-CA"; }// /method /** * @return where the website is stored locally on author's machines. Use local separator conventions e.g. \\ for * each \ for windows. Uses E: */ @Override public String getLocalWebrootWithBackslashes() { return "E:\\mindprodca"; }// /method /** * @return where the website is stored locally on author's machines. Use local separator conventions using * slashes, Uses E: not ltrailing / */ @Override public String getLocalWebrootWithSlashes() { return "E:/mindprodca"; }// /method /** * @return preferred line separator in generated files. Normally \n since this is most compact. Possibly set to * System.getProperty( "line.separator" ); or "\r\n" or "\r". * If you have compaction turned on, this ignored. The lineSeparator is always \n because it is the most * compact * and web-centric. */ @Override public String getPreferredLineSeparator() { return System.getProperty( "line.separator", "\r\n" ); }// /method /** * get quotation Aggregate category to use an a footer for a given page. * * @param footerFile web page where ad will go * * @return html to display banner and link */ @Override public QuoteAggregate getQuoteAggregateForFooter( File footerFile ) { // decide aggregate to use for footer quote. final String dir = ST.chopTrailingString( Tools.dirWithSlashes( footerFile ), "/foot" ); final String coreName = EIO.getCoreName( footerFile ); if ( dir.startsWith( "kjv" ) ) { return QuoteAggregate.RELIGION; } else { switch ( dir ) { case "animalrights": return QuoteAggregate.ANIMALRIGHTS; case "book": return getQuoteAggregateForBookFooter( coreName ); case "canada": return getQuoteAggregateCanadaFooter( coreName ); case "dvd": return getQuoteAggregateForDVDFooter( coreName ); case "electronic": return getQuoteAggregateElectronicFooter( coreName ); case "environment": return QuoteAggregate.ENVIRONMENT; case "feedback/animals": return QuoteAggregate.ANIMALRIGHTS; case "feedback/environment": return QuoteAggregate.ENVIRONMENT; case "feedback/god": return QuoteAggregate.RELIGION; case "feedback/hallucination": return QuoteAggregate.GENERAL; case "feedback/humanrights": return getQuoteAggregateHumanRightsFooter( coreName ); case "feedback/money": return QuoteAggregate.MONEY; case "feedback/peace": return QuoteAggregate.POLITICS; case "feedback/porn": return QuoteAggregate.GAY; case "ggloss": case "gloss/blurb": return QuoteAggregate.GAY; case "livinglove": case "livinglove/handbook": case "livinglove/methods": case "livinglove/methodssonglyrics": return QuoteAggregate.LIVINGLOVE; case "money": return QuoteAggregate.MONEY; case "politics": return getQuoteAggregatePoliticsFooter( coreName ); case "religion": return QuoteAggregate.RELIGION; default: return QuoteAggregate.GENERAL; } } }// /method /** * @return how many days to keep RSS newsfeed items in the HTML display */ @Override public int getRSSDisplayDays() { return 62; }// /method /** * @return how many days to keep RSS newsfeed items in the RSS feed */ @Override public int getRSSKeepDays() { return 32; }// /method /** * generate \n"; if ( fileBeingDistributed.getParent().equalsIgnoreCase( webroot + "\\ggloss" ) ) { return " tags. */ public boolean isUsingXHTML() { return false; }// /method /** * do we give the verbose informational messages? * * @return true if want verbose version. */ public boolean isVerbose() { return verbose; }// /method // methods /** * Does this product possibly have a newer version? * If no, we have checked it out at the new product is not really a replacmenent. * * @param productId isbn, sku etc. * * @return false if we have researched and their is not really a newer replacement product. */ public boolean possiblyNewer( String productId ) { return !NOT_ACTUALLY_NEWER_PRODUCT_IDS_SET.contains( productId ); }// /method /** * should we recompute footers, even if they have not yet expired? * This should be true when run shortly after midnight to readjust footers for different birthday weightings. */ public boolean shouldWeUpdateThisFooterNow( final File fileBeingDistributed ) { // we usually reset just some of the footers randomly // to avoid a massive upload just because one new quote was added disturbing the assignments. if ( resetFooterPercentage == -1 ) { // first time, fetch value from SET environment. final String resetFooterPercentageString = System.getenv( "resetfooterPercentage" ); if ( ST.isEmpty( resetFooterPercentageString ) ) { err.println( "Fatal Error: Environment set resetfooterpercentage missing." ); System.exit( 2 ); } try { resetFooterPercentage = Integer.parseInt( resetFooterPercentageString ); } catch ( NumberFormatException e ) { err.println( "Fatal Error: Environment set resetfooterpercentage=" + resetFooterPercentageString + " not valid number 0..100." ); System.exit( 2 ); } if ( !( 0 <= resetFooterPercentage && resetFooterPercentage <= 100 ) ) { err.println( "Fatal Error: Environment set resetfooterpercentage=" + resetFooterPercentage + " out of range 0..100." ); System.exit( 2 ); } } // resetFooterPercentage = 0 always generates false, 100 always generates true, // resetFooterPercentage = 5 generates true 5% of the time, randomly. // nextInt returns value 0..99 return resetQuoteWheel.nextInt( 100 ) < resetFooterPercentage; }// /method /** * override the usual stock mechanism because of errors in vendor * databbase. * * @param store * @param product * * @return null if no override, stockStatus if override */ public StockStatus stockStatusOverride( OnlineStore store, String product ) { return null; } }