diff --git a/src/main/java/org/jabref/logic/importer/fetcher/IsbnFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/IsbnFetcher.java index 4ab68824481..df78d4f25d2 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/IsbnFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/IsbnFetcher.java @@ -18,7 +18,7 @@ import org.slf4j.LoggerFactory; /** - * Fetcher for ISBN trying ebook.de first and then chimbori.com + * Fetcher for ISBN trying ebook.de first, chimbori.com and then ottobib */ public class IsbnFetcher implements EntryBasedFetcher, IdBasedFetcher { @@ -47,12 +47,19 @@ public Optional performSearchById(String identifier) throws FetcherExc IsbnViaEbookDeFetcher isbnViaEbookDeFetcher = new IsbnViaEbookDeFetcher(importFormatPreferences); Optional bibEntry = isbnViaEbookDeFetcher.performSearchById(identifier); + // nothing found at ebook.de, try chimbori.com if (!bibEntry.isPresent()) { LOGGER.debug("No entry found at ebook.de try chimbori.com"); IsbnViaChimboriFetcher isbnViaChimboriFetcher = new IsbnViaChimboriFetcher(importFormatPreferences); bibEntry = isbnViaChimboriFetcher.performSearchById(identifier); + } + //nothing found at ebook.de and chimbori.com, try ottobib + if (!bibEntry.isPresent()) { + LOGGER.debug("No entry found at ebook.de and chimbori.com try ottobib"); + IsbnViaOttoBibFetcher isbnViaOttoBibFetcher = new IsbnViaOttoBibFetcher(importFormatPreferences); + bibEntry = isbnViaOttoBibFetcher.performSearchById(identifier); } return bibEntry; diff --git a/src/main/java/org/jabref/logic/importer/fetcher/IsbnViaOttoBibFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/IsbnViaOttoBibFetcher.java new file mode 100644 index 00000000000..dfc1e8597bf --- /dev/null +++ b/src/main/java/org/jabref/logic/importer/fetcher/IsbnViaOttoBibFetcher.java @@ -0,0 +1,70 @@ +package org.jabref.logic.importer.fetcher; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Optional; + +import org.jabref.logic.importer.FetcherException; +import org.jabref.logic.importer.ImportFormatPreferences; +import org.jabref.logic.importer.ParseException; +import org.jabref.logic.importer.fileformat.BibtexParser; +import org.jabref.logic.net.URLDownload; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.strings.StringUtil; +import org.jabref.model.util.DummyFileUpdateMonitor; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; + +/** + * Fetcher for ISBN using https://www.ottobib.com + */ +public class IsbnViaOttoBibFetcher extends AbstractIsbnFetcher { + + private static final String BASE_URL = "https://www.ottobib.com/isbn/"; + + public IsbnViaOttoBibFetcher(ImportFormatPreferences importFormatPreferences) { + super(importFormatPreferences); + } + + @Override + public String getName() { + return "ISBN (OttoBib)"; + } + + /** + * @return null, because the identifier is passed using form data. This method is not used. + */ + @Override + public URL getURLForID(String identifier) throws URISyntaxException, MalformedURLException, FetcherException { + return null; + } + + @Override + public Optional performSearchById(String identifier) throws FetcherException { + if (StringUtil.isBlank(identifier)) { + return Optional.empty(); + } + + this.ensureThatIsbnIsValid(identifier); + + Document html; + try { + html = Jsoup.connect(BASE_URL + identifier + "/bibtex").userAgent(URLDownload.USER_AGENT).get(); + } catch (IOException e) { + throw new FetcherException("Could not ", e); + } + Element textArea = html.select("textarea").first(); + Optional entry = Optional.empty(); + try { + entry = BibtexParser.singleFromString(textArea.text(), importFormatPreferences, new DummyFileUpdateMonitor()); + } catch (ParseException e) { + throw new FetcherException("An internal parser error occurred", e); + } + return entry; + + } +} diff --git a/src/main/java/org/jabref/logic/net/URLDownload.java b/src/main/java/org/jabref/logic/net/URLDownload.java index e569adfa1b6..0eb2508cf13 100644 --- a/src/main/java/org/jabref/logic/net/URLDownload.java +++ b/src/main/java/org/jabref/logic/net/URLDownload.java @@ -58,7 +58,7 @@ */ public class URLDownload { - public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0"; + public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0"; private static final Logger LOGGER = LoggerFactory.getLogger(URLDownload.class); private final URL source; diff --git a/src/test/java/org/jabref/logic/importer/WebFetchersTest.java b/src/test/java/org/jabref/logic/importer/WebFetchersTest.java index 7e9107ce061..0655257e133 100644 --- a/src/test/java/org/jabref/logic/importer/WebFetchersTest.java +++ b/src/test/java/org/jabref/logic/importer/WebFetchersTest.java @@ -7,6 +7,7 @@ import org.jabref.logic.importer.fetcher.AbstractIsbnFetcher; import org.jabref.logic.importer.fetcher.IsbnViaChimboriFetcher; import org.jabref.logic.importer.fetcher.IsbnViaEbookDeFetcher; +import org.jabref.logic.importer.fetcher.IsbnViaOttoBibFetcher; import org.jabref.logic.importer.fetcher.MrDLibFetcher; import org.junit.jupiter.api.BeforeEach; @@ -36,6 +37,7 @@ void getIdBasedFetchersReturnsAllFetcherDerivingFromIdBasedFetcher() throws Exce // Remove special ISBN fetcher since we don't want to expose them to the user expected.remove(IsbnViaChimboriFetcher.class); expected.remove(IsbnViaEbookDeFetcher.class); + expected.remove(IsbnViaOttoBibFetcher.class); assertEquals(expected, getClasses(idFetchers)); } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaChimboriFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaChimboriFetcherTest.java index 9b2c311695a..29a168fec02 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaChimboriFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaChimboriFetcherTest.java @@ -31,7 +31,7 @@ public void setUp() { bibEntry.setField(StandardField.AUTHOR, "Joshua Bloch"); bibEntry.setField(StandardField.ISBN, "978-0321356680"); bibEntry.setField(StandardField.URL, - "https://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683?SubscriptionId=AKIAIOBINVZYXZQZ2U3A&tag=chimbori05-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=0321356683"); + "https://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683?SubscriptionId=AKIAIOBINVZYXZQZ2U3A&tag=chimbori05-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=0321356683"); fetcher = new IsbnViaChimboriFetcher(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS)); } @@ -78,7 +78,7 @@ public void authorsAreCorrectlyFormatted() throws Exception { bibEntry.setField(StandardField.AUTHOR, "Marlon Dumas and Marcello La Rosa and Jan Mendling and Hajo A. Reijers"); bibEntry.setField(StandardField.ISBN, "3642434738"); bibEntry.setField(StandardField.URL, - "https://www.amazon.com/Fundamentals-Business-Process-Management-Marlon/dp/3642434738?SubscriptionId=AKIAIOBINVZYXZQZ2U3A&tag=chimbori05-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=3642434738"); + "https://www.amazon.com/Fundamentals-Business-Process-Management-Marlon/dp/3642434738?SubscriptionId=AKIAIOBINVZYXZQZ2U3A&tag=chimbori05-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=3642434738"); Optional fetchedEntry = fetcher.performSearchById("3642434738"); assertEquals(Optional.of(bibEntry), fetchedEntry); diff --git a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java index 104f309879e..d292d0ac3de 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java @@ -29,7 +29,7 @@ public void setUp() { bibEntry.setField(StandardField.PUBLISHER, "Addison Wesley"); bibEntry.setField(StandardField.YEAR, "2018"); bibEntry.setField(StandardField.AUTHOR, "Bloch, Joshua"); - bibEntry.setField(StandardField.DATE, "2018-01-11"); + bibEntry.setField(StandardField.DATE, "2018-01-01"); bibEntry.setField(new UnknownField("ean"), "9780134685991"); bibEntry.setField(StandardField.ISBN, "0134685997"); bibEntry.setField(StandardField.URL, "https://www.ebook.de/de/product/28983211/joshua_bloch_effective_java.html"); @@ -68,26 +68,29 @@ public void searchByIdSuccessfulWithLongISBN() throws FetcherException { public void authorsAreCorrectlyFormatted() throws Exception { BibEntry bibEntry = new BibEntry(); bibEntry.setType(StandardEntryType.Book); - bibEntry.setCiteKey("9783662565094"); + bibEntry.setCiteKey("9783662585856"); bibEntry.setField(StandardField.TITLE, "Fundamentals of Business Process Management"); bibEntry.setField(StandardField.PUBLISHER, "Springer Berlin Heidelberg"); - bibEntry.setField(StandardField.YEAR, "2018"); + bibEntry.setField(StandardField.YEAR, "2019"); bibEntry.setField(StandardField.AUTHOR, "Dumas, Marlon and Rosa, Marcello La and Mendling, Jan and Reijers, Hajo A."); - bibEntry.setField(StandardField.DATE, "2018-03-23"); - bibEntry.setField(new UnknownField("ean"), "9783662565094"); - bibEntry.setField(StandardField.URL, "https://www.ebook.de/de/product/33399253/marlon_dumas_marcello_la_rosa_jan_mendling_hajo_a_reijers_fundamentals_of_business_process_management.html"); + bibEntry.setField(StandardField.DATE, "2019-02-01"); + bibEntry.setField(StandardField.PAGETOTAL, "560"); + bibEntry.setField(new UnknownField("ean"), "9783662585856"); + bibEntry.setField(StandardField.ISBN, "3662585855"); + bibEntry.setField(StandardField.URL, "https://www.ebook.de/de/product/35805105/marlon_dumas_marcello_la_rosa_jan_mendling_hajo_a_reijers_fundamentals_of_business_process_management.html"); - Optional fetchedEntry = fetcher.performSearchById("978-3-662-56509-4"); + Optional fetchedEntry = fetcher.performSearchById("3662585855"); assertEquals(Optional.of(bibEntry), fetchedEntry); } /** * This test searches for a valid ISBN. See https://www.amazon.de/dp/3728128155/?tag=jabref-21 However, this ISBN is - * not available on ebook.de. The fetcher should return nothing rather than throwing an exeption. + * not available on ebook.de. The fetcher should return nothing rather than throwing an exception. */ @Test public void searchForValidButNotFoundISBN() throws Exception { Optional fetchedEntry = fetcher.performSearchById("3728128155"); assertEquals(Optional.empty(), fetchedEntry); } + } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaOttoBibFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaOttoBibFetcherTest.java new file mode 100644 index 00000000000..9076b123f68 --- /dev/null +++ b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaOttoBibFetcherTest.java @@ -0,0 +1,99 @@ +package org.jabref.logic.importer.fetcher; + +import java.util.Optional; + +import org.jabref.logic.importer.FetcherException; +import org.jabref.logic.importer.ImportFormatPreferences; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.StandardEntryType; +import org.jabref.model.entry.field.StandardField; +import org.jabref.testutils.category.FetcherTest; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Answers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; + +@FetcherTest +public class IsbnViaOttoBibFetcherTest extends AbstractIsbnFetcherTest { + + @BeforeEach + public void setUp() { + bibEntry = new BibEntry(); + bibEntry.setType(StandardEntryType.Book); + bibEntry.setCiteKey("bloch2008effective"); + bibEntry.setField(StandardField.TITLE, "Effective Java"); + bibEntry.setField(StandardField.PUBLISHER, "Addison-Wesley"); + bibEntry.setField(StandardField.YEAR, "2008"); + bibEntry.setField(StandardField.AUTHOR, "Bloch, Joshua"); + bibEntry.setField(StandardField.ISBN, "9780321356680"); + bibEntry.setField(StandardField.ADDRESS, "Upper Saddle River, NJ"); + + fetcher = new IsbnViaOttoBibFetcher(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS)); + } + + @Test + @Override + public void testName() { + assertEquals("ISBN (OttoBib)", fetcher.getName()); + } + + @Test + @Override + public void testHelpPage() { + assertEquals("ISBNtoBibTeX", fetcher.getHelpPage().get().getPageName()); + } + + @Test + @Override + public void searchByIdSuccessfulWithShortISBN() throws FetcherException { + Optional fetchedEntry = fetcher.performSearchById("0321356683"); + bibEntry.setField(StandardField.ISBN, "0321356683"); + assertEquals(Optional.of(bibEntry), fetchedEntry); + } + + @Test + @Override + public void searchByIdSuccessfulWithLongISBN() throws FetcherException { + Optional fetchedEntry = fetcher.performSearchById("9780321356680"); + bibEntry.setField(StandardField.ISBN, "9780321356680"); + assertEquals(Optional.of(bibEntry), fetchedEntry); + } + + @Test + @Override + public void authorsAreCorrectlyFormatted() throws Exception { + BibEntry bibEntry = new BibEntry(); + bibEntry.setType(StandardEntryType.Book); + bibEntry.setCiteKey("dumas2018fundamentals"); + bibEntry.setField(StandardField.TITLE, "Fundamentals of business process management"); + bibEntry.setField(StandardField.PUBLISHER, "Springer"); + bibEntry.setField(StandardField.AUTHOR, "Dumas, Marlon"); + bibEntry.setField(StandardField.ADDRESS, "Berlin, Germany"); + bibEntry.setField(StandardField.ISBN, "9783662565094"); + bibEntry.setField(StandardField.YEAR, "2018"); + + Optional fetchedEntry = fetcher.performSearchById("978-3-662-56509-4"); + assertEquals(Optional.of(bibEntry), fetchedEntry); + } + + @Test + public void testISBNNotAvaiableOnEbookDeOrChimbori() throws Exception { + bibEntry = new BibEntry(); + bibEntry.setType(StandardEntryType.Book); + bibEntry.setCiteKey("denis2012les"); + bibEntry.setField(StandardField.TITLE, "Les mots du passé : roman"); + bibEntry.setField(StandardField.PUBLISHER, "Éd. les Nouveaux auteurs"); + bibEntry.setField(StandardField.ADDRESS, "Paris"); + bibEntry.setField(StandardField.YEAR, "2012"); + bibEntry.setField(StandardField.AUTHOR, "Denis, "); + bibEntry.setField(StandardField.ISBN, "9782819502746"); + + Optional fetchedEntry = fetcher.performSearchById("978-2-8195-02746"); + assertEquals(Optional.of(bibEntry), fetchedEntry); + + } + +}