Querying a book database online and returning results

Share your advanced PureBasic knowledge/code with the community.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Querying a book database online and returning results

Post by Fangbeast »

Code updated for 5.20+

This is something I have been bashing around for a while. It only works with the ifsdb.org online book database but it could be adapted to any web pages when you know which commands they use, how they return results ect.

I just made a simple program with other peoples code and lots of help to query the page for author and title and then return certain results that I wanted. Still needs cleaning up and a few extras added but it works here quite well. There is a small gui to make it easier to see what you are doing and return results graphically.

Let me know if it is of any use and can be improved somehow.

Code: Select all

;----------------------------------------------------------------------------------------------------------------------------
; Original code from from:  El_Choni,  http://forums.purebasic.com/english/viewtopic.php?t=15891
; Adapted by:               F.Weil 20050719
; Bashed soundly by:        MrMat
; Stuffed up thoroughly:    Fang
; Forms and extra code:     Fang
;
;============================================================================================================================
; prototypes
;============================================================================================================================


;============================================================================================================================
; declarations
;============================================================================================================================

Structure bookdetails
  title.s
  authors.s
  year.s
  isbn.s
  publisher.s
  price.s
  pages.s
  type.s
  picture.s
EndStructure

;============================================================================================================================
; 
;============================================================================================================================

Declare.s GetTitle(Author.s, Title.s)
Declare   GetPage(URL.s)
Declare   CheckError(value, sMessage.s, terminate)
Declare.s GetTitlePage(TitleNumber.s, Title.s)
Declare.l GetBookDetails(Bookreference.s, *details.bookdetails)

;============================================================================================================================
; constants
;============================================================================================================================

Enumeration 1
  #Window_getbook
EndEnumeration

#WindowIndex = #PB_Compiler_EnumerationValue

Enumeration 1
  #Gadget_getbook_fmain
  #Gadget_getbook_lsauthor
  #Gadget_getbook_sauthor
  #Gadget_getbook_lstitle
  #Gadget_getbook_stitle
  #Gadget_getbook_fdetails
  #Gadget_getbook_lauthor
  #Gadget_getbook_author
  #Gadget_getbook_ltitle
  #Gadget_getbook_title
  #Gadget_getbook_lyear
  #Gadget_getbook_year
  #Gadget_getbook_lisbn
  #Gadget_getbook_isbn
  #Gadget_getbook_lpublisher
  #Gadget_getbook_publisher
  #Gadget_getbook_lprice
  #Gadget_getbook_price
  #Gadget_getbook_lpages
  #Gadget_getbook_pages
  #Gadget_getbook_ltype
  #Gadget_getbook_type
  #Gadget_getbook_lpicture
  #Gadget_getbook_picture
  #Gadget_getbook_lnote
  #Gadget_getbook_note
  #Shortcut_getbook_enter
EndEnumeration

#GadgetIndex = #PB_Compiler_EnumerationValue

Enumeration 1
  #StatusBar_getbook
EndEnumeration

#StatusBarIndex =#PB_Compiler_EnumerationValue

#StatusBar_getbook_messages = 0

;============================================================================================================================
; windows
;============================================================================================================================

Procedure.l Window_getbook()
  If OpenWindow(#Window_getbook,108,81,500,345,"Get book details, press ENTER in title field to start the search",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible)
    FrameGadget(#Gadget_getbook_fmain,0,0,500,65,"")
    TextGadget(#Gadget_getbook_lsauthor,5,15,100,20,"Author",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lsauthor,LoadFont(#Gadget_getbook_lsauthor,"Arial",12,0))
    StringGadget(#Gadget_getbook_sauthor,105,10,390,25,"")
      SetGadgetFont(#Gadget_getbook_sauthor,LoadFont(#Gadget_getbook_sauthor,"Arial",12,0))
    TextGadget(#Gadget_getbook_lstitle,5,40,100,20,"Title",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lstitle,LoadFont(#Gadget_getbook_lstitle,"Arial",12,0))
    StringGadget(#Gadget_getbook_stitle,105,35,390,25,"")
      SetGadgetFont(#Gadget_getbook_stitle,LoadFont(#Gadget_getbook_stitle,"Arial",12,0))
    FrameGadget(#Gadget_getbook_fdetails,0,60,500,265,"")
    TextGadget(#Gadget_getbook_lauthor,5,75,100,20,"Author",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lauthor,LoadFont(#Gadget_getbook_lauthor,"Arial",12,0))
    StringGadget(#Gadget_getbook_author,105,70,390,25,"")
      SetGadgetFont(#Gadget_getbook_author,LoadFont(#Gadget_getbook_author,"Arial",12,0))
    TextGadget(#Gadget_getbook_ltitle,5,100,100,20,"Title",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_ltitle,LoadFont(#Gadget_getbook_ltitle,"Arial",12,0))
    StringGadget(#Gadget_getbook_title,105,95,390,25,"")
      SetGadgetFont(#Gadget_getbook_title,LoadFont(#Gadget_getbook_title,"Arial",12,0))
    TextGadget(#Gadget_getbook_lyear,5,125,100,20,"Year",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lyear,LoadFont(#Gadget_getbook_lyear,"Arial",12,0))
    StringGadget(#Gadget_getbook_year,105,120,390,25,"")
      SetGadgetFont(#Gadget_getbook_year,LoadFont(#Gadget_getbook_year,"Arial",12,0))
    TextGadget(#Gadget_getbook_lisbn,5,150,100,20,"ISBN",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lisbn,LoadFont(#Gadget_getbook_lisbn,"Arial",12,0))
    StringGadget(#Gadget_getbook_isbn,105,145,390,25,"")
      SetGadgetFont(#Gadget_getbook_isbn,LoadFont(#Gadget_getbook_isbn,"Arial",12,0))
    TextGadget(#Gadget_getbook_lpublisher,5,175,100,20,"Publisher",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lpublisher,LoadFont(#Gadget_getbook_lpublisher,"Arial",12,0))
    StringGadget(#Gadget_getbook_publisher,105,170,390,25,"")
      SetGadgetFont(#Gadget_getbook_publisher,LoadFont(#Gadget_getbook_publisher,"Arial",12,0))
    TextGadget(#Gadget_getbook_lprice,5,200,100,20,"Price",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lprice,LoadFont(#Gadget_getbook_lprice,"Arial",12,0))
    StringGadget(#Gadget_getbook_price,105,195,390,25,"")
      SetGadgetFont(#Gadget_getbook_price,LoadFont(#Gadget_getbook_price,"Arial",12,0))
    TextGadget(#Gadget_getbook_lpages,5,225,100,20,"Pages",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lpages,LoadFont(#Gadget_getbook_lpages,"Arial",12,0))
    StringGadget(#Gadget_getbook_pages,105,220,390,25,"")
      SetGadgetFont(#Gadget_getbook_pages,LoadFont(#Gadget_getbook_pages,"Arial",12,0))
    TextGadget(#Gadget_getbook_ltype,5,250,100,20,"Type",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_ltype,LoadFont(#Gadget_getbook_ltype,"Arial",12,0))
    StringGadget(#Gadget_getbook_type,105,245,390,25,"")
      SetGadgetFont(#Gadget_getbook_type,LoadFont(#Gadget_getbook_type,"Arial",12,0))
    TextGadget(#Gadget_getbook_lpicture,5,275,100,20,"Picture",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lpicture,LoadFont(#Gadget_getbook_lpicture,"Arial",12,0))
    StringGadget(#Gadget_getbook_picture,105,270,390,25,"")
      SetGadgetFont(#Gadget_getbook_picture,LoadFont(#Gadget_getbook_picture,"Arial",12,0))
    TextGadget(#Gadget_getbook_lnote,5,300,100,20,"Note",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lnote,LoadFont(#Gadget_getbook_lnote,"Arial",12,0))
    StringGadget(#Gadget_getbook_note,105,295,390,25,"")
      SetGadgetFont(#Gadget_getbook_note,LoadFont(#Gadget_getbook_note,"Arial",12,0))
    CreateStatusBar(#StatusBar_getbook,WindowID(#Window_getbook))
      AddStatusBarField(500)
    HideWindow(#Window_getbook,0)
    ProcedureReturn WindowID(#Window_getbook)
  EndIf
EndProcedure

;============================================================================================================================
; my constants
;============================================================================================================================

Enumeration
  #File
EndEnumeration

;============================================================================================================================
; 
;============================================================================================================================

#INTERNET_FLAG_RELOAD       = $80000000
#INTERNET_DEFAULT_HTTP_PORT = 80
#INTERNET_SERVICE_HTTP      = 3
#HTTP_QUERY_FLAG_NUMBER     = $20000000
#HTTP_QUERY_CONTENT_LENGTH  = 5
#HTTP_QUERY_STATUS_CODE     = 19
#HTTP_STATUS_OK             = 200
#INTERNET_OPEN_TYPE_DIRECT  = 1

;============================================================================================================================
; 
;============================================================================================================================

Global CacheFilename.s = "C:\CacheFile.txt"

;============================================================================================================================
; my procedures
;============================================================================================================================

Procedure CheckError(value, sMessage.s, terminate)
  If value = 0
      If terminate
        Debug("Error: " + sMessage)
      End
    EndIf
  EndIf
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================

Procedure GetPage(URL.s)
  If FindString(URL, "/", 8) = 0
   Url.s = Url + "/"
  EndIf
  DeleteUrlCacheEntry_(URL)
  If URLDownloadToFile_(#Null, URL, CacheFilename, #Null, #Null) = 0
      Domain.s = RemoveString(Left(URL, FindString(URL, "/", 8) - 1), "http://")
      dwordSize = 4
      hInet = InternetOpen_("Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.7.8) Gecko/20050511 Firefox/1.0.4", #INTERNET_OPEN_TYPE_DIRECT, #Null, #Null, 0)
      CheckError(hInet, "Internet connection not available.", #True)
      hURL = InternetOpenUrl_(hInet, URL, #Null, 0, #INTERNET_FLAG_RELOAD, 0)
      CheckError(hURL, "InternetOpenUrl_() failed", #True)
      hInetCon = InternetConnect_(hInet, Domain, #INTERNET_DEFAULT_HTTP_PORT, #Null, #Null, #INTERNET_SERVICE_HTTP, 0, 0)
      CheckError(hInetCon, "Unable to connect to " + Domain, #True)
      hHttpOpenRequest = HttpOpenRequest_(hInetCon, "HEAD", RemoveString(URL, "http://" + Domain + "/"), "http/1.0", #Null, 0, #INTERNET_FLAG_RELOAD, 0)
      CheckError(hHttpOpenRequest, "Http open request to " + Domain + " failed", #True)
      CheckError(HttpSendRequest_(hHttpOpenRequest, #Null, 0, 0, 0), "Http send request to " + Domain + " failed.", #True)
      CheckError(HttpQueryInfo_(hHttpOpenRequest, #HTTP_QUERY_FLAG_NUMBER | #HTTP_QUERY_STATUS_CODE, @sCode, @dwordSize, @lpdwIndex), "Http query failed.", #False)
      CheckError(Bool(sCode = #HTTP_STATUS_OK), "Status code query failed.", #False)
      CheckError(HttpQueryInfo_(hHttpOpenRequest, #HTTP_QUERY_FLAG_NUMBER | #HTTP_QUERY_CONTENT_LENGTH, @sCode, @dwordSize, @lpdwIndex), "CONTENT_LENGTH query failed.", #False)
      If sCode
          DataBufferLength = sCode
        Else
          DataBufferLength = 4096
      EndIf
      *DataBuffer = AllocateMemory(DataBufferLength)
      CheckError(*DataBuffer, "Not enough memory.", #True)
      CheckError(CreateFile(#File, CacheFileName), "Unable to create file.", #True)
      Repeat
        CheckError(InternetReadFile_(hURL, *DataBuffer, DataBufferLength, @Bytes), "Download failed.", #True)
        If Bytes
            WriteData(#File, *DataBuffer, Bytes)
        EndIf
      Until Bytes = 0
      CloseFile(#File)
      FreeMemory(*DataBuffer)
      InternetCloseHandle_(hInetCon)
      InternetCloseHandle_(hURL)
      InternetCloseHandle_(hInet)
  EndIf
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================

Procedure.s GetTitle(Author.s, Title.s)
  GetPage("http://www.isfdb.org/cgi-bin/ea.cgi?" + LCase(Author.s))
    foundtitle.s = ""
  If ReadFile(#File, CacheFileName)
    Repeat
      a$ = ReadString(#File)
      TitlePos.l     = FindString(LCase(a$), LCase(Title.s), 1)
      If TitlePos.l <> 0
        TitleNumPos.l = FindString(a$, "?", 1)
        foundtitle = Mid(a$, TitleNumPos + 1, TitlePos - TitleNumPos - 13)
      EndIf
    Until Eof(#File) Or foundtitle <> ""
    CloseFile(#File)
  Else
    Debug("Couldn't read file in GetTitle")
  EndIf
  DeleteFile(CacheFileName)
  ProcedureReturn foundtitle
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================

Procedure.s GetTitlePage(TitleNumber.s, Title.s)
  GetPage("http://www.isfdb.org/cgi-bin/title.cgi?" + TitleNumber.s)
  CompoundTitle.s = ""
  If ReadFile(#File, CacheFileName)
    Repeat
      a$ = ReadString(#File)
      CompoundIndex.l     = FindString(a$, "http://www.isfdb.org/cgi-bin/pl.cgi", 1)
      If CompoundIndex.l <> 0
        CompoundIndexPos  = FindString(a$, "?", 1)
        TitlePos.l        = FindString(LCase(a$), LCase(Title.s), 1)
        CompoundTitle.s   = Mid(a$, CompoundIndexPos + 1, TitlePos - CompoundIndexPos - 13)
      EndIf
    Until Eof(#File) Or CompoundTitle <> ""
    CloseFile(#File)
  Else
    Debug("Couldn't read file in GetTitlePage")
  EndIf
  DeleteFile(CacheFileName)
  ProcedureReturn CompoundTitle
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================

Procedure.s ReadField(origtext.s, search.s)
  found.s = ""
  findpos.l = FindString(LCase(origtext), LCase(search), 1)
  If findpos <> 0
    found = Trim(Right(origtext, Len(origtext) - (findpos + Len(search) + 3)))
  EndIf
  ProcedureReturn found
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================

Procedure.s ReadPicture(origtext.s, search.s)
  found.s = ""
  findpos.l = FindString(LCase(origtext), LCase(search), 1)
  If findpos <> 0
    searchlen = Len(search)
    endpos  = FindString(LCase(origtext), LCase(".JPG"), 1)
    found = search.s + Mid(origtext, searchlen, endpos - searchlen + 4)
  EndIf
  ProcedureReturn found
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================

Procedure.l GetBookDetails(Bookreference.s, *details.bookdetails)
  GetPage("http://www.isfdb.org/cgi-bin/pl.cgi?" + Bookreference.s)
  found.l = #False
  If ReadFile(#File, CacheFileName)
    authortext.s = "http://www.isfdb.org/cgi-bin/ea.cgi?"
    Repeat
      origtext.s = ReadString(#File)
      If found = #False
        If FindString(LCase(origtext), LCase("metadata"), 1) <> 0
          found = #True
        EndIf
      EndIf
      If found = #True
        If *details\title = "" : *details\title = ReadField(origtext, "Title:") : EndIf
        findpos.l = FindString(origtext, authortext, 1) ; Author search
        If findpos <> 0
          findpos2.l = FindString(origtext, Chr(34) + ">", findpos + Len(authortext))
          If findpos2 <> 0
            author.s = Trim(Mid(origtext, findpos2 + 2, Len(origtext) - (findpos2 + 1) - 4))
            If author <> ""
              If *details\authors <> ""
                *details\authors + ", "
              EndIf
            *details\authors + author
            EndIf
          EndIf
        EndIf
        If *details\year      = ""  : *details\year       = ReadField(origtext, "Year:")      : EndIf
        If *details\isbn      = ""  : *details\isbn       = ReadField(origtext, "ISBN:")      : EndIf
        If *details\publisher = ""  : *details\publisher  = ReadField(origtext, "Publisher:") : EndIf
        If *details\price     = ""  : *details\price      = ReadField(origtext, "Price:")     : EndIf
        If *details\pages     = ""  : *details\pages      = ReadField(origtext, "Pages:")     : EndIf
        If *details\type      = ""  : *details\type       = ReadField(origtext, "Type:")      : EndIf
        
        If *details\picture   = ""
          *details\picture    = ReadPicture(origtext, "http://images.amazon.com/images/")
        EndIf
      EndIf
    Until Eof(#File)
    CloseFile(#File)
  Else
    Debug("Couldn't read file in GetBookDetails")
  EndIf
  ProcedureReturn found
EndProcedure

;============================================================================================================================
; main event handler
;============================================================================================================================

If Window_getbook()
  AddKeyboardShortcut(#Window_getbook, #PB_Shortcut_Return, #Shortcut_getbook_enter)
  quitgetbook = 0
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        If EventWindow() = #Window_getbook
          quitgetbook = 1
        EndIf
      Case #PB_Event_Menu
        Select EventMenu()
          Case #Shortcut_getbook_enter : Gosub CheckEnter
        EndSelect
     EndSelect
  Until quitgetbook
  CloseWindow(#Window_getbook)
EndIf
End

;============================================================================================================================
; Check if the ENTER key was pressed in the SQL query box
;============================================================================================================================

CheckEnter:

  FocusID = GetFocus_()
  Select FocusID
    Case GadgetID(#Gadget_getbook_stitle)
      Title.s  = GetGadgetText(#Gadget_getbook_stitle)
      Author.s = GetGadgetText(#Gadget_getbook_sauthor)
      If Title.s <> "" And Author.s <> ""
        StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Information: Fetching pages to parse..")
        TitleNumber.s = GetTitle(Author.s, Title.s)
        StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Information: Processing and parsing..")
        If TitleNumber.s <> ""
          Bookreference.s = GetTitlePage(TitleNumber.s, Title.s)
          If Bookreference.s <> ""
            If GetBookDetails(Bookreference.s, @info.bookdetails) <> 0
              SetGadgetText(#Gadget_getbook_author,     info\authors)
              SetGadgetText(#Gadget_getbook_title,      info\title)
              SetGadgetText(#Gadget_getbook_year,       info\year)
              SetGadgetText(#Gadget_getbook_isbn,       info\isbn)
              SetGadgetText(#Gadget_getbook_publisher,  info\publisher)
              SetGadgetText(#Gadget_getbook_price,      info\price)
              SetGadgetText(#Gadget_getbook_pages,      info\pages) 
              SetGadgetText(#Gadget_getbook_type,       info\type)
              SetGadgetText(#Gadget_getbook_picture,    info\picture)
              ;SetGadgetText(#Gadget_getbook_note,       info\note)
              StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Information: Found all details for the specified title..")
              SetGadgetText(#Gadget_getbook_stitle,  "")
              SetGadgetText(#Gadget_getbook_sauthor, "")
            Else
              StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: Could not get the specified books' details")
            EndIf
          Else
            StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: No book reference for the specified title")
          EndIf
        Else
          StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: No ifsdb book reference number for the specified title")
        EndIf
      Else
        StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: Fill in both author and title fields to proceed to the search")
      EndIf
  EndSelect
Return
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
dige
Addict
Addict
Posts: 1412
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Post by dige »

hmm, cant connect to isfdb.org
May be the problem is the Proxy. What do I have to change, to connect
trough a proxy?
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Works great here, I like it very much! Thanks for sharing it. :D
BERESHEIT
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Nice, Fangs!

Dige, http://www.isfdb.org/ (sf transposed in post but ok in code)
@}--`--,-- A rose by any other name ..
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

dige wrote:hmm, cant connect to isfdb.org
May be the problem is the Proxy. What do I have to change, to connect
trough a proxy?
No idea dige. I'm not using a proxy myself and tested the queries in the procedures manually by poasting them into firefox and they wored so I don't know.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

netmaestro wrote:Works great here, I like it very much! Thanks for sharing it. :D
Thanks. I had a lot of starter code from smarter people than me and it still has a loooooong way to go.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Dare2 wrote:Nice, Fangs!

Dige, http://www.isfdb.org/ (sf transposed in post but ok in code)
Can't take the credit for this. Wouldn't mind lots of help extending it to be smarter and more modularised so that it could be used with any web page. As it is, it's very ifsdb-centric.

I also need to add smarter cache management, picture retreival and wikipaedia comment retreival for the book. But I'm still learning.

Actually, someone mentioned using regexp but I don't know how. The wikipaedia page is a mess to parse and regexp would make a better job of it I think.

So much to do, so little brain cells.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Berikco
Administrator
Administrator
Posts: 1326
Joined: Wed Apr 23, 2003 7:57 pm
Location: Belgium
Contact:

Post by Berikco »

Very nice 8)
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Berikco wrote:Very nice 8)
Thank you sir wizard. Will add more as I learn more:)
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Brand new perversion of the above code!!

Post by Fangbeast »

Code updated for 5.20+

Loads of work, testing and additions have been done.

You give this program an author and a title and press enter and it will:

1. Parse the web page at ifsdb.org and return what information it finds.
2. If there is a picture, it downloads it and renames it to the supplied title.
3. If there is a picture, it loads it into the imagegadget for previewing.
4. It appends to a log file with the book information so you can build a quick database.
5. Creates local picture and database directories.
6. Has a progress window you can read to see what's going on.

Quite useful for me personally. It's going to be added to my library item manager. Now all I have to do is learn to do this with Amazon (groan).

Code: Select all

;----------------------------------------------------------------------------------------------------------------------------
; Original code from from:  El_Choni,  http://forums.purebasic.com/english/viewtopic.php?t=15891
; Adapted by:               F.Weil 20050719
; Bashed soundly by:        MrMat
; Stuffed up thoroughly:    Fang
; Forms and extra code:     Fang
; Bug testing and tuition for my brain cells by Traumatic
;
;============================================================================================================================
; 
;============================================================================================================================
 
UseJPEGImageDecoder()
 
;============================================================================================================================
; my constants
;============================================================================================================================
 
Enumeration 1
  #File
  #Booklog
EndEnumeration
 
;============================================================================================================================
; 
;============================================================================================================================
 
#INTERNET_FLAG_RELOAD       = $80000000
#INTERNET_DEFAULT_HTTP_PORT = 80
#INTERNET_SERVICE_HTTP      = 3
#HTTP_QUERY_FLAG_NUMBER     = $20000000
#HTTP_QUERY_CONTENT_LENGTH  = 5
#HTTP_QUERY_STATUS_CODE     = 19
#HTTP_STATUS_OK             = 200
#INTERNET_OPEN_TYPE_DIRECT  = 1
 
;============================================================================================================================
; Structures
;============================================================================================================================
 
Structure bookdetails
  title.s
  authors.s
  year.s
  isbn.s
  publisher.s
  price.s
  pages.s
  type.s
  picture.s
EndStructure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Structure programdata
  curdir.s
EndStructure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Global CacheFilename.s = "CacheFile.txt"
Global bookdetails
Global program.programdata
 
;==============================================================================================================================
; Get current directory and store it for later
;==============================================================================================================================
 
program\curdir = Space(512)                                          ; Give the variable enough space
 
If GetCurrentDirectory_(Len(program\curdir), @program\curdir) <> 0   ; Get the current directory
  If Right(program\curdir, 1) <> "\"                                 ; Each O/S does it differently so check for backspace
    program\curdir + "\"
  EndIf
EndIf
 
;============================================================================================================================
; 
;============================================================================================================================
 
Declare.s GetTitle(Author.s, Title.s)
Declare   GetFile(URL$, LocalFile$)
Declare   GetPicture(Picturefile.s, *details.bookdetails)
Declare   GetPage(URL.s)
Declare   CheckError(value, sMessage.s, terminate)
Declare.s GetTitlePage(TitleNumber.s, Title.s)
Declare.l GetBookDetails(Bookreference.s, *details.bookdetails)
Declare   SaveDetails(*details.bookdetails)
 
;============================================================================================================================
; prototypes
;============================================================================================================================
 
;============================================================================================================================
; constants
;============================================================================================================================
 
Enumeration 1
  #Window_getbook
EndEnumeration
 
#WindowIndex = #PB_Compiler_EnumerationValue
 
Enumeration 1
  #Gadget_getbook_progress
  #Gadget_getbook_pmain
  #Gadget_getbook_tdetails
  #Gadget_getbook_tpicture
  #Gadget_getbook_terrors
  #Gadget_getbook_fmain
  #Gadget_getbook_lsauthor
  #Gadget_getbook_sauthor
  #Gadget_getbook_lstitle
  #Gadget_getbook_stitle
  #Gadget_getbook_fdetails
  #Gadget_getbook_lauthor
  #Gadget_getbook_author
  #Gadget_getbook_ltitle
  #Gadget_getbook_title
  #Gadget_getbook_lyear
  #Gadget_getbook_year
  #Gadget_getbook_lisbn
  #Gadget_getbook_isbn
  #Gadget_getbook_lpublisher
  #Gadget_getbook_publisher
  #Gadget_getbook_lprice
  #Gadget_getbook_price
  #Gadget_getbook_lpages
  #Gadget_getbook_pages
  #Gadget_getbook_ltype
  #Gadget_getbook_type
  #Gadget_getbook_lpicture
  #Gadget_getbook_picture
  #Gadget_getbook_lnote
  #Gadget_getbook_note
  #Gadget_getbook_fphoto
  #Gadget_getbook_lphoto
  #Gadget_getbook_photo
  #Gadget_getbook_ferrors
  #Gadget_getbook_lerrors
  #Gadget_getbook_lprogress
  #Shortcut_getbook_enter
 
EndEnumeration
 
#GadgetIndex = #PB_Compiler_EnumerationValue
 
Enumeration 1
  #Picture_getbook_temp
EndEnumeration
 
#ImageIndex = #PB_Compiler_EnumerationValue
 
Enumeration 1
  #StatusBar_getbook
EndEnumeration
 
#StatusBarIndex =#PB_Compiler_EnumerationValue
 
#StatusBar_getbook_messages = 0
 
 
;============================================================================================================================
; windows
;============================================================================================================================
 
Procedure.l Window_getbook()
  If OpenWindow(#Window_getbook,63,81,503,392,"Get book details",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible)
    ProgressBarGadget(#Gadget_getbook_progress,105,352,396,20,0,100)
    PanelGadget(#Gadget_getbook_pmain,0,0,505,350)
    AddGadgetItem(#Gadget_getbook_pmain,-1,"Main book details")
    FrameGadget(#Gadget_getbook_fmain,0,0,500,65,"")
    TextGadget(#Gadget_getbook_lsauthor,5,15,100,20,"Author",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lsauthor,LoadFont(#Gadget_getbook_lsauthor,"Arial",12,0))
    StringGadget(#Gadget_getbook_sauthor,105,10,390,25,"")
      SetGadgetFont(#Gadget_getbook_sauthor,LoadFont(#Gadget_getbook_sauthor,"Arial",12,0))
    TextGadget(#Gadget_getbook_lstitle,5,40,100,20,"Title",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lstitle,LoadFont(#Gadget_getbook_lstitle,"Arial",12,0))
    StringGadget(#Gadget_getbook_stitle,105,35,390,25,"")
      SetGadgetFont(#Gadget_getbook_stitle,LoadFont(#Gadget_getbook_stitle,"Arial",12,0))
    FrameGadget(#Gadget_getbook_fdetails,0,60,500,265,"")
    TextGadget(#Gadget_getbook_lauthor,5,75,100,20,"Author",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lauthor,LoadFont(#Gadget_getbook_lauthor,"Arial",12,0))
    StringGadget(#Gadget_getbook_author,105,70,390,25,"")
      SetGadgetFont(#Gadget_getbook_author,LoadFont(#Gadget_getbook_author,"Arial",12,0))
    TextGadget(#Gadget_getbook_ltitle,5,100,100,20,"Title",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_ltitle,LoadFont(#Gadget_getbook_ltitle,"Arial",12,0))
    StringGadget(#Gadget_getbook_title,105,95,390,25,"")
      SetGadgetFont(#Gadget_getbook_title,LoadFont(#Gadget_getbook_title,"Arial",12,0))
    TextGadget(#Gadget_getbook_lyear,5,125,100,20,"Year",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lyear,LoadFont(#Gadget_getbook_lyear,"Arial",12,0))
    StringGadget(#Gadget_getbook_year,105,120,390,25,"")
      SetGadgetFont(#Gadget_getbook_year,LoadFont(#Gadget_getbook_year,"Arial",12,0))
    TextGadget(#Gadget_getbook_lisbn,5,150,100,20,"ISBN",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lisbn,LoadFont(#Gadget_getbook_lisbn,"Arial",12,0))
    StringGadget(#Gadget_getbook_isbn,105,145,390,25,"")
      SetGadgetFont(#Gadget_getbook_isbn,LoadFont(#Gadget_getbook_isbn,"Arial",12,0))
    TextGadget(#Gadget_getbook_lpublisher,5,175,100,20,"Publisher",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lpublisher,LoadFont(#Gadget_getbook_lpublisher,"Arial",12,0))
    StringGadget(#Gadget_getbook_publisher,105,170,390,25,"")
      SetGadgetFont(#Gadget_getbook_publisher,LoadFont(#Gadget_getbook_publisher,"Arial",12,0))
    TextGadget(#Gadget_getbook_lprice,5,200,100,20,"Price",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lprice,LoadFont(#Gadget_getbook_lprice,"Arial",12,0))
    StringGadget(#Gadget_getbook_price,105,195,390,25,"")
      SetGadgetFont(#Gadget_getbook_price,LoadFont(#Gadget_getbook_price,"Arial",12,0))
    TextGadget(#Gadget_getbook_lpages,5,225,100,20,"Pages",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lpages,LoadFont(#Gadget_getbook_lpages,"Arial",12,0))
    StringGadget(#Gadget_getbook_pages,105,220,390,25,"")
      SetGadgetFont(#Gadget_getbook_pages,LoadFont(#Gadget_getbook_pages,"Arial",12,0))
    TextGadget(#Gadget_getbook_ltype,5,250,100,20,"Type",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_ltype,LoadFont(#Gadget_getbook_ltype,"Arial",12,0))
    StringGadget(#Gadget_getbook_type,105,245,390,25,"")
      SetGadgetFont(#Gadget_getbook_type,LoadFont(#Gadget_getbook_type,"Arial",12,0))
    TextGadget(#Gadget_getbook_lpicture,5,275,100,20,"Picture",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lpicture,LoadFont(#Gadget_getbook_lpicture,"Arial",12,0))
    StringGadget(#Gadget_getbook_picture,105,270,390,25,"")
      SetGadgetFont(#Gadget_getbook_picture,LoadFont(#Gadget_getbook_picture,"Arial",12,0))
    TextGadget(#Gadget_getbook_lnote,5,300,100,20,"Note",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lnote,LoadFont(#Gadget_getbook_lnote,"Arial",12,0))
    StringGadget(#Gadget_getbook_note,105,295,390,25,"")
      SetGadgetFont(#Gadget_getbook_note,LoadFont(#Gadget_getbook_note,"Arial",12,0))
    AddGadgetItem(#Gadget_getbook_pmain,-1,"Cover page or photograph")
    FrameGadget(#Gadget_getbook_fphoto,0,0,500,325,"")
    TextGadget(#Gadget_getbook_lphoto,5,15,100,20,"Cover",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lphoto,LoadFont(#Gadget_getbook_lphoto,"Arial",12,0))
    ImageGadget(#Gadget_getbook_photo,105,10,390,310,0,#PB_Image_Border)
    AddGadgetItem(#Gadget_getbook_pmain,-1,"Program and retrieval errors")
    FrameGadget(#Gadget_getbook_ferrors,0,0,500,325,"")
    ListIconGadget(#Gadget_getbook_lerrors,5,10,490,310,"Error messages",490,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
    CloseGadgetList()
    TextGadget(#Gadget_getbook_lprogress,5,350,100,20,"Get Picture")
      SetGadgetFont(#Gadget_getbook_lprogress,LoadFont(#Gadget_getbook_lprogress,"Arial",12,0))
    CreateStatusBar(#StatusBar_getbook,WindowID(#Window_getbook))
      AddStatusBarField(750)
    HideWindow(#Window_getbook,0)
    ProcedureReturn WindowID(#Window_getbook)
  EndIf
EndProcedure
 
;============================================================================================================================
; my procedures
;============================================================================================================================
 
Procedure CheckError(value, sMessage.s, terminate)
  If value = 0
      If terminate
        ;Debug("Error: " + sMessage)
      End
    EndIf
  EndIf
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure GetFile(URL$, LocalFile$)
  Domain$ = RemoveString(Left(URL$, FindString(URL$, "/", 8)-1), "http://")
  dwordSize = 4
  hInet = InternetOpen_("Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.7.8) Gecko/20050511 Firefox/1.0.4", #INTERNET_OPEN_TYPE_DIRECT, #Null, #Null, 0)
  CheckError(hInet, "Internet connection not available.", #True)
  hURL = InternetOpenUrl_(hInet, URL$, #Null, 0, #INTERNET_FLAG_RELOAD, 0)
  CheckError(hURL, "InternetOpenUrl_() failed", #True)
  hInetCon = InternetConnect_(hInet, Domain$, #INTERNET_DEFAULT_HTTP_PORT, #Null, #Null, #INTERNET_SERVICE_HTTP, 0, 0)
  CheckError(hInetCon, "Unable to connect to "+Domain$, #True)
  hHttpOpenRequest = HttpOpenRequest_(hInetCon, "HEAD", RemoveString(URL$, "http://"+Domain$+"/"), "http/1.0", #Null, 0, #INTERNET_FLAG_RELOAD, 0)
  CheckError(hHttpOpenRequest, "Http open request to "+Domain$+" failed", #True)
  CheckError(HttpSendRequest_(hHttpOpenRequest, #Null, 0, 0, 0), "Http send request to "+Domain$+" failed.", #True)
  CheckError(HttpQueryInfo_(hHttpOpenRequest, #HTTP_QUERY_FLAG_NUMBER|#HTTP_QUERY_STATUS_CODE, @sCode, @dwordSize, @lpdwIndex), "Http query failed.", #False)
  CheckError(Bool(sCode=#HTTP_STATUS_OK), "Status code query failed.", #False)
  CheckError(HttpQueryInfo_(hHttpOpenRequest, #HTTP_QUERY_FLAG_NUMBER|#HTTP_QUERY_CONTENT_LENGTH, @sCode, @dwordSize, @lpdwIndex), "CONTENT_LENGTH query failed.", #False)
  If sCode
    DataBufferLength = sCode
  Else
    DataBufferLength = 4096
  EndIf
  *DataBuffer = AllocateMemory(DataBufferLength)
  CheckError(*DataBuffer, "Not enough memory.", #True)
  CheckError(CreateFile(0, LocalFile$), "Unable to create file.", #True)
  Repeat
    CheckError(InternetReadFile_(hURL, *DataBuffer, DataBufferLength, @Bytes), "Download failed.", #True)
    If Bytes
      WriteData(0,*DataBuffer, Bytes)
    EndIf
  Until Bytes=0
  CloseFile(0)
  FreeMemory(*DataBuffer)
  InternetCloseHandle_(hInetCon)
  InternetCloseHandle_(hURL)
  InternetCloseHandle_(hInet)
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure GetPage(URL.s)
  If FindString(URL, "/", 8) = 0
   Url.s = Url + "/"
  EndIf
  DeleteUrlCacheEntry_(URL)
  If URLDownloadToFile_(#Null, URL, CacheFilename, #Null, #Null) = 0
      Domain.s = RemoveString(Left(URL, FindString(URL, "/", 8) - 1), "http://")
      dwordSize = 4
      hInet = InternetOpen_("Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.7.8) Gecko/20050511 Firefox/1.0.4", #INTERNET_OPEN_TYPE_DIRECT, #Null, #Null, 0)
      CheckError(hInet, "Internet connection not available.", #True)
      hURL = InternetOpenUrl_(hInet, URL, #Null, 0, #INTERNET_FLAG_RELOAD, 0)
      CheckError(hURL, "InternetOpenUrl_() failed", #True)
      hInetCon = InternetConnect_(hInet, Domain, #INTERNET_DEFAULT_HTTP_PORT, #Null, #Null, #INTERNET_SERVICE_HTTP, 0, 0)
      CheckError(hInetCon, "Unable to connect to " + Domain, #True)
      hHttpOpenRequest = HttpOpenRequest_(hInetCon, "HEAD", RemoveString(URL, "http://" + Domain + "/"), "http/1.0", #Null, 0, #INTERNET_FLAG_RELOAD, 0)
      CheckError(hHttpOpenRequest, "Http open request to " + Domain + " failed", #True)
      CheckError(HttpSendRequest_(hHttpOpenRequest, #Null, 0, 0, 0), "Http send request to " + Domain + " failed.", #True)
      CheckError(HttpQueryInfo_(hHttpOpenRequest, #HTTP_QUERY_FLAG_NUMBER | #HTTP_QUERY_STATUS_CODE, @sCode, @dwordSize, @lpdwIndex), "Http query failed.", #False)
      CheckError(Bool(sCode = #HTTP_STATUS_OK), "Status code query failed.", #False)
      CheckError(HttpQueryInfo_(hHttpOpenRequest, #HTTP_QUERY_FLAG_NUMBER | #HTTP_QUERY_CONTENT_LENGTH, @sCode, @dwordSize, @lpdwIndex), "CONTENT_LENGTH query failed.", #False)
      If sCode
          DataBufferLength = sCode
        Else
          DataBufferLength = 4096
      EndIf
      *DataBuffer = AllocateMemory(DataBufferLength)
      CheckError(*DataBuffer, "Not enough memory.", #True)
      CheckError(CreateFile(#File, CacheFileName), "Unable to create file.", #True)
      Repeat
        CheckError(InternetReadFile_(hURL, *DataBuffer, DataBufferLength, @Bytes), "Download failed.", #True)
        If Bytes
            WriteData(#File, *DataBuffer, Bytes)
        EndIf
      Until Bytes = 0
      CloseFile(#File)
      FreeMemory(*DataBuffer)
      InternetCloseHandle_(hInetCon)
      InternetCloseHandle_(hURL)
      InternetCloseHandle_(hInet)
  EndIf
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure.s GetTitle(Author.s, Title.s)
  GetPage("http://www.isfdb.org/cgi-bin/ea.cgi?" + LCase(Author.s))
    foundtitle.s = ""
  If ReadFile(#File, CacheFileName)
    Repeat
      a$ = ReadString(#File)
      TitlePos.l     = FindString(LCase(a$), LCase(Title.s), 1)
      If TitlePos.l <> 0
        TitleNumPos.l = FindString(a$, "?", 1)
        foundtitle = Mid(a$, TitleNumPos + 1, TitlePos - TitleNumPos - 13)
      EndIf
    Until Eof(#File) Or foundtitle <> ""
    CloseFile(#File)
  Else
    ;Debug("Couldn't read file in GetTitle")
  EndIf
  DeleteFile(CacheFileName)
  ProcedureReturn foundtitle
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure.s GetTitlePage(TitleNumber.s, Title.s)
  GetPage("http://www.isfdb.org/cgi-bin/title.cgi?" + TitleNumber.s)
  CompoundTitle.s = ""
  If ReadFile(#File, CacheFileName)
    Repeat
      a$ = ReadString(#File)
      CompoundIndex.l     = FindString(a$, "http://www.isfdb.org/cgi-bin/pl.cgi", 1)
      If CompoundIndex.l <> 0
        CompoundIndexPos  = FindString(a$, "?", 1)
        TitlePos.l        = FindString(LCase(a$), LCase(Title.s), 1)
        CompoundTitle.s   = Mid(a$, CompoundIndexPos + 1, TitlePos - CompoundIndexPos - 13)
      EndIf
    Until Eof(#File) Or CompoundTitle <> ""
    CloseFile(#File)
  Else
    ;Debug("Couldn't read file in GetTitlePage")
  EndIf
  DeleteFile(CacheFileName)
  ProcedureReturn CompoundTitle
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure.s ReadField(origtext.s, search.s)
  found.s = ""
  findpos.l = FindString(LCase(origtext), LCase(search), 1)
  If findpos <> 0
    found = Trim(Right(origtext, Len(origtext) - (findpos + Len(search) + 3)))
  EndIf
  ProcedureReturn found
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure.s ReadPicture(origtext.s, search.s)
  found.s = ""
  findpos.l = FindString(LCase(origtext), LCase(search), 1)
  If findpos <> 0
    searchlen = Len(search)
    endpos  = FindString(LCase(origtext), LCase(".JPG"), 1)
    found = search.s + Mid(origtext, searchlen + findpos, endpos - searchlen - 6)
  EndIf
  ProcedureReturn found
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure.l GetBookDetails(Bookreference.s, *details.bookdetails)
  GetPage("http://www.isfdb.org/cgi-bin/pl.cgi?" + Bookreference.s)
  found.l = #False
  If ReadFile(#File, CacheFileName)
    authortext.s = "http://www.isfdb.org/cgi-bin/ea.cgi?"
    Repeat
      origtext.s = ReadString(#File)
      If found = #False
        If FindString(LCase(origtext), LCase("metadata"), 1) <> 0
          found = #True
        EndIf
      EndIf
      If found = #True
        If *details\title = "" : *details\title = ReadField(origtext, "Title:") : EndIf
        findpos.l = FindString(origtext, authortext, 1) ; Author search
        If findpos <> 0
          findpos2.l = FindString(origtext, Chr(34) + ">", findpos + Len(authortext))
          If findpos2 <> 0
            author.s = Trim(Mid(origtext, findpos2 + 2, Len(origtext) - (findpos2 + 1) - 4))
            If author <> ""
              If *details\authors <> ""
                *details\authors + ", "
              EndIf
            *details\authors + author
            EndIf
          EndIf
        EndIf
        If *details\year      = ""  : *details\year       = ReadField(origtext, "Year:")      : EndIf
        If *details\isbn      = ""  : *details\isbn       = ReadField(origtext, "ISBN:")      : EndIf
        If *details\publisher = ""  : *details\publisher  = ReadField(origtext, "Publisher:") : EndIf
        If *details\price     = ""  : *details\price      = ReadField(origtext, "Price:")     : EndIf
        If *details\pages     = ""  : *details\pages      = ReadField(origtext, "Pages:")     : EndIf
        If *details\type      = ""  : *details\type       = ReadField(origtext, "Type:")      : EndIf
        If *details\type      = "hc": *details\type       = "Hard Cover"                      : EndIf
        If *details\picture   = ""
          *details\picture    = ReadPicture(origtext, "http://images.amazon.com/images/")
        EndIf
      EndIf
    Until Eof(#File)
    CloseFile(#File)
  Else
    ;Debug("Couldn't read file in GetBookDetails")
  EndIf
  ProcedureReturn found
EndProcedure
 
;============================================================================================================================
;
;============================================================================================================================
 
Procedure GetPicture(Picturefile.s, *details.bookdetails)
  GetFile(Picturefile.s, "Pictures\" + *details\title + ".jpg")
  If FileSize("Pictures\" + *details\title + ".jpg") <> -1
    If LoadImage(#Picture_getbook_temp, program\curdir + "Pictures\" + *details\title + ".jpg") <> 0
      ResizeImage(#Picture_getbook_temp, 390, 310, #PB_Image_Smooth)
      SetGadgetState(#Gadget_getbook_photo, ImageID(#Picture_getbook_temp))
    Else
      StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: The specified picture could not be loaded..")      
    EndIf
  EndIf
EndProcedure
 
;============================================================================================================================
; Save all details to a file, download and rename the picture to the title name if you can
;============================================================================================================================
 
Procedure SaveDetails(*details.bookdetails)
  If OpenFile(#Booklog, program\curdir + "Booklog.txt") <> 0
    FileSeek(#Booklog, Lof(#Booklog))
    WriteString(#Booklog, *details\title        + "|") 
    WriteString(#Booklog, *details\authors      + "|")
    WriteString(#Booklog, *details\year         + "|")
    WriteString(#Booklog, *details\isbn         + "|")
    WriteString(#Booklog, *details\publisher    + "|")
    WriteString(#Booklog, *details\price        + "|")
    WriteString(#Booklog, *details\pages        + "|")
    WriteString(#Booklog, *details\type         + "|")
    WriteStringN(#Booklog, *details\picture)
  CloseFile(#Booklog)
  Else
    StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: The specified file could not be opened..")      
  EndIf
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
MakeSureDirectoryPathExists_("Database\")
MakeSureDirectoryPathExists_("Pictures\")
 
;============================================================================================================================
; main event handler
;============================================================================================================================
 
If Window_getbook()
  AddKeyboardShortcut(#Window_getbook, #PB_Shortcut_Return, #Shortcut_getbook_enter)
  quitgetbook = 0
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        If EventWindow() = #Window_getbook
          quitgetbook = 1
        EndIf
      Case #PB_Event_Menu
        Select EventMenu()
          Case #Shortcut_getbook_enter : Gosub CheckEnter
        EndSelect
     EndSelect
  Until quitgetbook
  CloseWindow(#Window_getbook)
EndIf
End
 
;============================================================================================================================
; Check if the ENTER key was pressed in the SQL query box
;============================================================================================================================
 
CheckEnter:
 
  FocusID = GetFocus_()
  Select FocusID
    Case GadgetID(#Gadget_getbook_stitle)
      Title.s  = GetGadgetText(#Gadget_getbook_stitle)
      Author.s = GetGadgetText(#Gadget_getbook_sauthor)
      If Title.s <> "" And Author.s <> ""
        StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Information: Fetching pages to parse..")
        TitleNumber.s = GetTitle(Author.s, Title.s)
        StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Information: Processing and parsing..")
        If TitleNumber.s <> ""
          Bookreference.s = GetTitlePage(TitleNumber.s, Title.s)
          If Bookreference.s <> ""
            If GetBookDetails(Bookreference.s, @info.bookdetails) <> 0
              ClearGadgetItems(#Gadget_getbook_lerrors)
              SetGadgetText(#Gadget_getbook_author,     info\authors)
              SetGadgetText(#Gadget_getbook_title,      info\title)
              SetGadgetText(#Gadget_getbook_year,       info\year)
              SetGadgetText(#Gadget_getbook_isbn,       info\isbn)
              SetGadgetText(#Gadget_getbook_publisher,  info\publisher)
              SetGadgetText(#Gadget_getbook_price,      info\price)
              SetGadgetText(#Gadget_getbook_pages,      info\pages) 
              SetGadgetText(#Gadget_getbook_type,       info\type)
              SetGadgetText(#Gadget_getbook_picture,    info\picture)
              ;SetGadgetText(#Gadget_getbook_note,       info\note)
              StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Information: Found all details for the specified title..")
              SetGadgetText(#Gadget_getbook_stitle,  "")
              SetGadgetText(#Gadget_getbook_sauthor, "")
              If info\picture <> ""
                GetPicture(info\picture, @info.bookdetails)
              EndIf
              SaveDetails(@info.bookdetails)
            Else
              SetGadgetText(#Gadget_getbook_stitle,  "")
              SetGadgetText(#Gadget_getbook_sauthor, "")
              StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: Could not get the specified books' details")
            EndIf
          Else
            StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: No book reference for the specified title")
          EndIf
        Else
          StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: No ifsdb book reference number for the specified title")
        EndIf
      Else
        StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: Fill in both author and title fields to proceed to the search")
      EndIf
  EndSelect
Return
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

New version. Adds synopsis

Post by Fangbeast »

Code updated for 5.20+

New version of the above code. This version has the forms re-ordered and also retrieves the sysnopsis notes as it's getting the title reference and also writes that to he book log along with the other data.

Code: Select all

;----------------------------------------------------------------------------------------------------------------------------
; Original code from from:  El_Choni,  http://forums.purebasic.com/english/viewtopic.php?t=15891
; Adapted by:               F.Weil 20050719
; Bashed soundly by:        MrMat
; Stuffed up thoroughly:    Fang
; Forms and extra code:     Fang
; Bug testing and tuition for my brain cells by Traumatic
;============================================================================================================================
; XIncludeFile "GetBook_Myprototypes.pb"
;============================================================================================================================

;============================================================================================================================
; XIncludeFile "GetBook_Constants.pb"
;============================================================================================================================

Enumeration 1
  #Window_getbook
EndEnumeration

#WindowIndex = #PB_Compiler_EnumerationValue

Enumeration 1
  #Gadget_getbook_progress
  #Gadget_getbook_pmain
  #Gadget_getbook_tdetails
  #Gadget_getbook_tpicture
  #Gadget_getbook_terrors
  #Gadget_getbook_fmain
  #Gadget_getbook_lsauthor
  #Gadget_getbook_sauthor
  #Gadget_getbook_lstitle
  #Gadget_getbook_stitle
  #Gadget_getbook_fdetails
  #Gadget_getbook_lauthor
  #Gadget_getbook_author
  #Gadget_getbook_ltitle
  #Gadget_getbook_title
  #Gadget_getbook_lyear
  #Gadget_getbook_year
  #Gadget_getbook_lisbn
  #Gadget_getbook_isbn
  #Gadget_getbook_lpublisher
  #Gadget_getbook_publisher
  #Gadget_getbook_lprice
  #Gadget_getbook_price
  #Gadget_getbook_lpages
  #Gadget_getbook_pages
  #Gadget_getbook_ltype
  #Gadget_getbook_type
  #Gadget_getbook_lpicture
  #Gadget_getbook_picture
  #Gadget_getbook_lnote
  #Gadget_getbook_fphoto
  #Gadget_getbook_lphoto
  #Gadget_getbook_photo
  #Gadget_getbook_ferrors
  #Gadget_getbook_lerrors
  #Gadget_getbook_lprogress
  #Gadget_getbook_note
EndEnumeration

#GadgetIndex = #PB_Compiler_EnumerationValue

Enumeration 1
  #StatusBar_getbook
EndEnumeration

#StatusBarIndex = #PB_Compiler_EnumerationValue

#StatusBar_getbook_messages = 0

;============================================================================================================================
;XIncludeFile "GetBook_Windows.pb"
;============================================================================================================================

Procedure.l Window_getbook()
  If OpenWindow(#Window_getbook,63,81,503,460,"Get book details",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible)
    ProgressBarGadget(#Gadget_getbook_progress,105,420,400,20,0,100)
    PanelGadget(#Gadget_getbook_pmain,0,0,505,420)
    AddGadgetItem(#Gadget_getbook_pmain,-1,"Main book details")
    FrameGadget(#Gadget_getbook_fmain,0,0,500,65,"")
    TextGadget(#Gadget_getbook_lsauthor,5,15,100,20,"Author",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lsauthor,LoadFont(#Gadget_getbook_lsauthor,"Arial",12,0))
    StringGadget(#Gadget_getbook_sauthor,105,10,390,25,"")
      SetGadgetFont(#Gadget_getbook_sauthor,LoadFont(#Gadget_getbook_sauthor,"Arial",12,0))
    TextGadget(#Gadget_getbook_lstitle,5,40,100,20,"Title",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lstitle,LoadFont(#Gadget_getbook_lstitle,"Arial",12,0))
    StringGadget(#Gadget_getbook_stitle,105,35,390,25,"")
      SetGadgetFont(#Gadget_getbook_stitle,LoadFont(#Gadget_getbook_stitle,"Arial",12,0))
    FrameGadget(#Gadget_getbook_fdetails,0,60,500,335,"")
    TextGadget(#Gadget_getbook_lauthor,5,75,100,20,"Author",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lauthor,LoadFont(#Gadget_getbook_lauthor,"Arial",12,0))
    StringGadget(#Gadget_getbook_author,105,70,390,25,"")
      SetGadgetFont(#Gadget_getbook_author,LoadFont(#Gadget_getbook_author,"Arial",12,0))
    TextGadget(#Gadget_getbook_ltitle,5,100,100,20,"Title",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_ltitle,LoadFont(#Gadget_getbook_ltitle,"Arial",12,0))
    StringGadget(#Gadget_getbook_title,105,95,390,25,"")
      SetGadgetFont(#Gadget_getbook_title,LoadFont(#Gadget_getbook_title,"Arial",12,0))
    TextGadget(#Gadget_getbook_lyear,5,125,100,20,"Year",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lyear,LoadFont(#Gadget_getbook_lyear,"Arial",12,0))
    StringGadget(#Gadget_getbook_year,105,120,105,25,"16/10/1958")
      SetGadgetFont(#Gadget_getbook_year,LoadFont(#Gadget_getbook_year,"Arial",12,0))
    TextGadget(#Gadget_getbook_lisbn,215,125,55,20,"ISBN",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lisbn,LoadFont(#Gadget_getbook_lisbn,"Arial",12,0))
    StringGadget(#Gadget_getbook_isbn,270,120,225,25,"")
      SetGadgetFont(#Gadget_getbook_isbn,LoadFont(#Gadget_getbook_isbn,"Arial",12,0))
    TextGadget(#Gadget_getbook_lpublisher,5,150,100,20,"Publisher",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lpublisher,LoadFont(#Gadget_getbook_lpublisher,"Arial",12,0))
    StringGadget(#Gadget_getbook_publisher,105,145,390,25,"")
      SetGadgetFont(#Gadget_getbook_publisher,LoadFont(#Gadget_getbook_publisher,"Arial",12,0))
    TextGadget(#Gadget_getbook_lprice,5,175,100,20,"Price",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lprice,LoadFont(#Gadget_getbook_lprice,"Arial",12,0))
    StringGadget(#Gadget_getbook_price,105,170,75,25,"")
      SetGadgetFont(#Gadget_getbook_price,LoadFont(#Gadget_getbook_price,"Arial",12,0))
    TextGadget(#Gadget_getbook_lpages,185,175,60,20,"Pages",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lpages,LoadFont(#Gadget_getbook_lpages,"Arial",12,0))
    StringGadget(#Gadget_getbook_pages,245,170,75,25,"")
      SetGadgetFont(#Gadget_getbook_pages,LoadFont(#Gadget_getbook_pages,"Arial",12,0))
    TextGadget(#Gadget_getbook_ltype,325,175,55,20,"Type",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_ltype,LoadFont(#Gadget_getbook_ltype,"Arial",12,0))
    StringGadget(#Gadget_getbook_type,380,170,115,25,"")
      SetGadgetFont(#Gadget_getbook_type,LoadFont(#Gadget_getbook_type,"Arial",12,0))
    TextGadget(#Gadget_getbook_lpicture,5,200,100,20,"Picture",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lpicture,LoadFont(#Gadget_getbook_lpicture,"Arial",12,0))
    StringGadget(#Gadget_getbook_picture,105,195,390,25,"")
      SetGadgetFont(#Gadget_getbook_picture,LoadFont(#Gadget_getbook_picture,"Arial",12,0))
    TextGadget(#Gadget_getbook_lnote,5,225,100,20,"Note",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lnote,LoadFont(#Gadget_getbook_lnote,"Arial",12,0))
    EditorGadget(#Gadget_getbook_note,105,220,390,170)
    AddGadgetItem(#Gadget_getbook_pmain,-1,"Cover page or photograph")
    FrameGadget(#Gadget_getbook_fphoto,0,0,500,395,"")
    TextGadget(#Gadget_getbook_lphoto,5,15,100,20,"Cover",#PB_Text_Center)
      SetGadgetFont(#Gadget_getbook_lphoto,LoadFont(#Gadget_getbook_lphoto,"Arial",12,0))
    ImageGadget(#Gadget_getbook_photo,105,10,390,380,0,#PB_Image_Border)
    AddGadgetItem(#Gadget_getbook_pmain,-1,"Program and retrieval errors")
    FrameGadget(#Gadget_getbook_ferrors,0,0,500,395,"")
    ListIconGadget(#Gadget_getbook_lerrors,5,10,490,380,"Error messages",490,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
    CloseGadgetList()
    TextGadget(#Gadget_getbook_lprogress,5,420,100,20,"Get Picture")
      SetGadgetFont(#Gadget_getbook_lprogress,LoadFont(#Gadget_getbook_lprogress,"Arial",12,0))
    CreateStatusBar(#StatusBar_getbook,WindowID(#Window_getbook))
      AddStatusBarField(750)
    HideWindow(#Window_getbook,0)
    ProcedureReturn WindowID(#Window_getbook)
  EndIf
EndProcedure

;============================================================================================================================
; XIncludeFile "GetBook_Myconstants.pb"
;============================================================================================================================

;============================================================================================================================
; my constants
;============================================================================================================================
 
Enumeration #GadgetIndex
  #File
  #Booklog
  #Shortcut_getbook_enter
  #Shortcut_getbook_escape
EndEnumeration

;============================================================================================================================
; 
;============================================================================================================================

Enumeration 1
  #Picture_getbook_temp
EndEnumeration

;============================================================================================================================
; 
;============================================================================================================================
 
#INTERNET_FLAG_RELOAD       = $80000000
#INTERNET_DEFAULT_HTTP_PORT = 80
#INTERNET_SERVICE_HTTP      = 3
#HTTP_QUERY_FLAG_NUMBER     = $20000000
#HTTP_QUERY_CONTENT_LENGTH  = 5
#HTTP_QUERY_STATUS_CODE     = 19
#HTTP_STATUS_OK             = 200
#INTERNET_OPEN_TYPE_DIRECT  = 1
 
;============================================================================================================================
; Structures
;============================================================================================================================
 
Structure bookdetails
  title.s
  author.s
  year.s
  isbn.s
  publisher.s
  price.s
  pages.s
  type.s
  picture.s
EndStructure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Structure programdata
  curdir.s
  cachefile.s
  logfile.s
  pictures.s
  quitvalue.l
EndStructure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Global bookdetails, program.programdata
 
;==============================================================================================================================
; Get current directory and store it for later
;==============================================================================================================================
 
program\curdir = Space(512)                                          ; Give the variable enough space
 
If GetCurrentDirectory_(Len(program\curdir), @program\curdir) <> 0   ; Get the current directory
  If Right(program\curdir, 1) <> "\"                                 ; Each O/S does it differently so check for backspace
    program\curdir + "\"
  EndIf
EndIf

;==============================================================================================================================
; Create local picture and icon directory variables
;==============================================================================================================================

program\logfile   = program\curdir + "Logfile\LogFile.txt"
program\cachefile = program\curdir + "Cachedir\CacheFile.txt"
program\pictures  = program\curdir + "Pictures\"

;============================================================================================================================
; XIncludeFile "GetBook_Mydeclarations.pb"
;============================================================================================================================

;============================================================================================================================
; 
;============================================================================================================================
 
Declare.s GetTitle(Author.s, Title.s)
Declare   GetFile(URL$, LocalFile$)
Declare   GetPage(URL.s)
Declare   CheckError(value, sMessage.s, terminate)
Declare.s GetTitlePage(TitleNumber.s, Title.s)
Declare.l GetBookDetails(Bookreference.s, *details.bookdetails)
Declare   SaveDetails(*details.bookdetails)
 
;============================================================================================================================
; XIncludeFile "GetBook_Myprocedures.pb"
;============================================================================================================================

;============================================================================================================================
; my procedures
;============================================================================================================================
 
Procedure CheckError(value, sMessage.s, terminate)
  If value = 0
      If terminate
        ;Debug("Error: " + sMessage)
      End
    EndIf
  EndIf
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure GetFile(URL$, LocalFile$)
  Domain$ = RemoveString(Left(URL$, FindString(URL$, "/", 8)-1), "http://")
  dwordSize = 4
  hInet = InternetOpen_("Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.7.8) Gecko/20050511 Firefox/1.0.4", #INTERNET_OPEN_TYPE_DIRECT, #Null, #Null, 0)
  CheckError(hInet, "Internet connection not available.", #True)
  hURL = InternetOpenUrl_(hInet, URL$, #Null, 0, #INTERNET_FLAG_RELOAD, 0)
  CheckError(hURL, "InternetOpenUrl_() failed", #True)
  hInetCon = InternetConnect_(hInet, Domain$, #INTERNET_DEFAULT_HTTP_PORT, #Null, #Null, #INTERNET_SERVICE_HTTP, 0, 0)
  CheckError(hInetCon, "Unable to connect to "+Domain$, #True)
  hHttpOpenRequest = HttpOpenRequest_(hInetCon, "HEAD", RemoveString(URL$, "http://"+Domain$+"/"), "http/1.0", #Null, 0, #INTERNET_FLAG_RELOAD, 0)
  CheckError(hHttpOpenRequest, "Http open request to "+Domain$+" failed", #True)
  CheckError(HttpSendRequest_(hHttpOpenRequest, #Null, 0, 0, 0), "Http send request to "+Domain$+" failed.", #True)
  CheckError(HttpQueryInfo_(hHttpOpenRequest, #HTTP_QUERY_FLAG_NUMBER|#HTTP_QUERY_STATUS_CODE, @sCode, @dwordSize, @lpdwIndex), "Http query failed.", #False)
  CheckError(Bool(sCode=#HTTP_STATUS_OK), "Status code query failed.", #False)
  CheckError(HttpQueryInfo_(hHttpOpenRequest, #HTTP_QUERY_FLAG_NUMBER|#HTTP_QUERY_CONTENT_LENGTH, @sCode, @dwordSize, @lpdwIndex), "CONTENT_LENGTH query failed.", #False)
  If sCode
    DataBufferLength = sCode
  Else
    DataBufferLength = 4096
  EndIf
  *DataBuffer = AllocateMemory(DataBufferLength)
  CheckError(*DataBuffer, "Not enough memory.", #True)
  CheckError(CreateFile(0, LocalFile$), "Unable to create file.", #True)
  Repeat
    CheckError(InternetReadFile_(hURL, *DataBuffer, DataBufferLength, @Bytes), "Download failed.", #True)
    If Bytes
      WriteData(0,*DataBuffer, Bytes)
    EndIf
  Until Bytes=0
  CloseFile(0)
  FreeMemory(*DataBuffer)
  InternetCloseHandle_(hInetCon)
  InternetCloseHandle_(hURL)
  InternetCloseHandle_(hInet)
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure GetPage(URL.s)
  If FindString(URL, "/", 8) = 0
   Url.s = Url + "/"
  EndIf
  DeleteUrlCacheEntry_(URL)
  If URLDownloadToFile_(#Null, URL, program\cachefile, #Null, #Null) = 0
      Domain.s = RemoveString(Left(URL, FindString(URL, "/", 8) - 1), "http://")
      dwordSize = 4
      hInet = InternetOpen_("Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.7.8) Gecko/20050511 Firefox/1.0.4", #INTERNET_OPEN_TYPE_DIRECT, #Null, #Null, 0)
      CheckError(hInet, "Internet connection not available.", #True)
      hURL = InternetOpenUrl_(hInet, URL, #Null, 0, #INTERNET_FLAG_RELOAD, 0)
      CheckError(hURL, "InternetOpenUrl_() failed", #True)
      hInetCon = InternetConnect_(hInet, Domain, #INTERNET_DEFAULT_HTTP_PORT, #Null, #Null, #INTERNET_SERVICE_HTTP, 0, 0)
      CheckError(hInetCon, "Unable to connect to " + Domain, #True)
      hHttpOpenRequest = HttpOpenRequest_(hInetCon, "HEAD", RemoveString(URL, "http://" + Domain + "/"), "http/1.0", #Null, 0, #INTERNET_FLAG_RELOAD, 0)
      CheckError(hHttpOpenRequest, "Http open request to " + Domain + " failed", #True)
      CheckError(HttpSendRequest_(hHttpOpenRequest, #Null, 0, 0, 0), "Http send request to " + Domain + " failed.", #True)
      CheckError(HttpQueryInfo_(hHttpOpenRequest, #HTTP_QUERY_FLAG_NUMBER | #HTTP_QUERY_STATUS_CODE, @sCode, @dwordSize, @lpdwIndex), "Http query failed.", #False)
      CheckError(Bool(sCode = #HTTP_STATUS_OK), "Status code query failed.", #False)
      CheckError(HttpQueryInfo_(hHttpOpenRequest, #HTTP_QUERY_FLAG_NUMBER | #HTTP_QUERY_CONTENT_LENGTH, @sCode, @dwordSize, @lpdwIndex), "CONTENT_LENGTH query failed.", #False)
      If sCode
          DataBufferLength = sCode
        Else
          DataBufferLength = 4096
      EndIf
      *DataBuffer = AllocateMemory(DataBufferLength)
      CheckError(*DataBuffer, "Not enough memory.", #True)
      CheckError(CreateFile(#File, program\cachefile), "Unable to create file.", #True)
      Repeat
        CheckError(InternetReadFile_(hURL, *DataBuffer, DataBufferLength, @Bytes), "Download failed.", #True)
        If Bytes
            WriteData(#File, *DataBuffer, Bytes)
        EndIf
      Until Bytes = 0
      CloseFile(#File)
      FreeMemory(*DataBuffer)
      InternetCloseHandle_(hInetCon)
      InternetCloseHandle_(hURL)
      InternetCloseHandle_(hInet)
  EndIf
EndProcedure
 
;============================================================================================================================
; Get the synopsis notes for the title
;============================================================================================================================
 
Procedure GetTitleNote()
  If ReadFile(#File, program\cachefile)
    Repeat
      a$ = ReadString(#File)
        Found  = FindString(a$, "Synopsis:", 1)
        If Found <> 0
          Debug Mid(a$, 18, Len(a$) - 18)
          SetGadgetText(#Gadget_getbook_note, Mid(a$, 18, Len(a$) - 18))
        EndIf
    Until Eof(#File)
  CloseFile(#File)
  EndIf
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================
 
Procedure.s GetTitle(Author.s, Title.s)
  GetPage("http://www.isfdb.org/cgi-bin/ea.cgi?" + LCase(Author.s))
    foundtitle.s = ""
  If ReadFile(#File, program\cachefile)
    Repeat
      a$ = ReadString(#File)
      TitlePos.l     = FindString(LCase(a$), LCase(Title.s), 1)
      If TitlePos.l <> 0
        TitleNumPos.l = FindString(a$, "?", 1)
        foundtitle = Mid(a$, TitleNumPos + 1, TitlePos - TitleNumPos - 13)
      EndIf
    Until Eof(#File) Or foundtitle <> ""
    CloseFile(#File)
  Else
    ;Debug("Couldn't read file in GetTitle")
  EndIf
  DeleteFile(program\cachefile)
  ProcedureReturn foundtitle
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure.s GetTitlePage(TitleNumber.s, Title.s)
  GetPage("http://www.isfdb.org/cgi-bin/title.cgi?" + TitleNumber.s)
  CompoundTitle.s = ""
  If ReadFile(#File, program\cachefile)
    Repeat
      a$ = ReadString(#File)
      CompoundIndex.l     = FindString(a$, "http://www.isfdb.org/cgi-bin/pl.cgi", 1)
      If CompoundIndex.l <> 0
        CompoundIndexPos  = FindString(a$, "?", 1)
        TitlePos.l        = FindString(LCase(a$), LCase(Title.s), 1)
        CompoundTitle.s   = Mid(a$, CompoundIndexPos + 1, TitlePos - CompoundIndexPos - 13)
      EndIf
    Until Eof(#File) Or CompoundTitle <> ""
    CloseFile(#File)
    GetTitleNote()
  Else
    ;Debug("Couldn't read file in GetTitlePage")
  EndIf
  DeleteFile(program\cachefile)
  ProcedureReturn CompoundTitle
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure.s ReadField(origtext.s, search.s)
  found.s = ""
  findpos.l = FindString(LCase(origtext), LCase(search), 1)
  If findpos <> 0
    found = Trim(Right(origtext, Len(origtext) - (findpos + Len(search) + 3)))
  EndIf
  ProcedureReturn found
EndProcedure
 
;============================================================================================================================
; 
;============================================================================================================================
 
Procedure.s ReadPicture(origtext.s, search.s)
  found.s = ""
  findpos.l = FindString(LCase(origtext), LCase(search), 1)
  If findpos <> 0
    searchlen = Len(search)
    endpos  = FindString(LCase(origtext), LCase(".JPG"), 1)
    found = search.s + Mid(origtext, searchlen + findpos, endpos - searchlen - 6)
  EndIf
  ProcedureReturn found
EndProcedure
 
;============================================================================================================================
; http://www.isfdb.org/cgi-bin/pl.cgi?THBRTHRNGL2000
;============================================================================================================================
 
Procedure.l GetBookDetails(Bookreference.s, *details.bookdetails)
  GetPage("http://www.isfdb.org/cgi-bin/pl.cgi?" + Bookreference.s)
  found.l = #False
  If ReadFile(#File, program\cachefile)
    authortext.s = "http://www.isfdb.org/cgi-bin/ea.cgi?"
    Repeat
      origtext.s = ReadString(#File)
      If found = #False
        If FindString(LCase(origtext), LCase("metadata"), 1) <> 0
          found = #True
        EndIf
      EndIf
      If found = #True
        If *details\title = "" : *details\title = ReadField(origtext, "Title:") : EndIf
        findpos.l = FindString(origtext, authortext, 1) ; Author search
        If findpos <> 0
          findpos2.l = FindString(origtext, Chr(34) + ">", findpos + Len(authortext))
          If findpos2 <> 0
            author.s = Trim(Mid(origtext, findpos2 + 2, Len(origtext) - (findpos2 + 1) - 4))
            If author <> ""
              If *details\author <> ""
                *details\author + ", "
              EndIf
            *details\author + author
            EndIf
          EndIf
        EndIf
        If *details\year      = ""  : *details\year       = ReadField(origtext, "Year:")      : EndIf
        If *details\isbn      = ""  : *details\isbn       = ReadField(origtext, "ISBN:")      : EndIf
        If *details\publisher = ""  : *details\publisher  = ReadField(origtext, "Publisher:") : EndIf
        If *details\price     = ""  : *details\price      = ReadField(origtext, "Price:")     : EndIf
        If *details\pages     = ""  : *details\pages      = ReadField(origtext, "Pages:")     : EndIf
        If *details\type      = ""  : *details\type       = ReadField(origtext, "Type:")      : EndIf
        If *details\type      = "hc": *details\type       = "Hard Cover"                      : EndIf
        If *details\picture   = ""
          *details\picture    = ReadPicture(origtext, "http://images.amazon.com/images/")
        EndIf
      EndIf
    Until Eof(#File)
    CloseFile(#File)
  Else
    ;Debug("Couldn't read file in GetBookDetails")
  EndIf
  ProcedureReturn found
EndProcedure
 
;============================================================================================================================
;
;============================================================================================================================
 
Procedure GetPicture(Picturefile.s, *details.bookdetails)
  GetFile(Picturefile.s, program\pictures + *details\title + ".jpg")
  If FileSize(program\pictures + *details\title + ".jpg") <> -1
    If LoadImage(#Picture_getbook_temp, program\pictures + *details\title + ".jpg") <> 0
      ResizeImage(#Picture_getbook_temp, 390, 380, #PB_Image_Smooth)
      SetGadgetState(#Gadget_getbook_photo, ImageID(#Picture_getbook_temp))
    Else
      StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: The specified picture could not be loaded..")      
    EndIf
  EndIf
EndProcedure
 
;============================================================================================================================
; Save all details to a file, download and rename the picture to the title name if you can
;============================================================================================================================
 
Procedure SaveDetails(*details.bookdetails)
  If OpenFile(#Booklog, program\logfile) <> 0
    FileSeek(#Booklog, Lof(#Booklog))
    WriteString(#Booklog, *details\title        + "|") 
    WriteString(#Booklog, *details\author       + "|")
    WriteString(#Booklog, *details\year         + "|")
    WriteString(#Booklog, *details\isbn         + "|")
    WriteString(#Booklog, *details\publisher    + "|")
    WriteString(#Booklog, *details\price        + "|")
    WriteString(#Booklog, *details\pages        + "|")
    WriteString(#Booklog, *details\type         + "|")
    WriteString(#Booklog, *details\picture      + "|")
    WriteStringN(#Booklog, GetGadgetText(#Gadget_getbook_note))
  CloseFile(#Booklog)
  Else
    StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: The specified file could not be opened..")      
  EndIf
EndProcedure

;============================================================================================================================
; 
;============================================================================================================================
 
UseJPEGImageDecoder()
 
;============================================================================================================================
; 
;============================================================================================================================
 
MakeSureDirectoryPathExists_("Logfile\")
MakeSureDirectoryPathExists_("Pictures\")
MakeSureDirectoryPathExists_("Cachedir\")
 
;============================================================================================================================
; main event handler
;============================================================================================================================
 
If Window_getbook()
  AddKeyboardShortcut(#Window_getbook, #PB_Shortcut_Return, #Shortcut_getbook_enter)
  AddKeyboardShortcut(#Window_getbook, #PB_Shortcut_Escape, #Shortcut_getbook_escape)
  SendMessage_(GadgetID(#Gadget_getbook_note), #EM_SETTARGETDEVICE, #Null, 0) ; Set right margin on note box
  SetActiveGadget(#Gadget_getbook_sauthor)
  program\quitvalue = 0
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        If EventWindow() = #Window_getbook
          program\quitvalue = 1
        EndIf
      Case #PB_Event_Menu
        Select EventMenu()
          Case #Shortcut_getbook_enter  : Gosub CheckEnter
          Case #Shortcut_getbook_escape : program\quitvalue = 1
        EndSelect
     EndSelect
  Until program\quitvalue
  CloseWindow(#Window_getbook)
EndIf
End
 
;============================================================================================================================
; Check if the ENTER key was pressed in the SQL query box
;============================================================================================================================
 
CheckEnter:
 
  FocusID = GetFocus_()
  
  Select FocusID
  
    Case GadgetID(#Gadget_getbook_stitle)
    
      Title.s  = GetGadgetText(#Gadget_getbook_stitle)
      Author.s = GetGadgetText(#Gadget_getbook_sauthor)
      
      If Title.s <> "" And Author.s <> ""
      
        StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Information: Fetching pages to parse..")
        
        TitleNumber.s = GetTitle(Author.s, Title.s)
        
        StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Information: Processing and parsing..")
        
        If TitleNumber.s <> ""
        
          Bookreference.s = GetTitlePage(TitleNumber.s, Title.s)
          
          If Bookreference.s <> ""
          
            If GetBookDetails(Bookreference.s, @info.bookdetails) <> 0
            
              ClearGadgetItems(#Gadget_getbook_lerrors)
              
              SetGadgetText(#Gadget_getbook_author,     info\author)
              SetGadgetText(#Gadget_getbook_title,      info\title)
              SetGadgetText(#Gadget_getbook_year,       info\year)
              SetGadgetText(#Gadget_getbook_isbn,       info\isbn)
              SetGadgetText(#Gadget_getbook_publisher,  info\publisher)
              SetGadgetText(#Gadget_getbook_price,      info\price)
              SetGadgetText(#Gadget_getbook_pages,      info\pages) 
              SetGadgetText(#Gadget_getbook_type,       info\type)
              SetGadgetText(#Gadget_getbook_picture,    info\picture)
              ;SetGadgetText(#Gadget_getbook_note,       info\note)     ; Set elsewhere
              
              StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Information: Found all details for the specified title..")
              
              SetGadgetText(#Gadget_getbook_stitle,  "")
              SetGadgetText(#Gadget_getbook_sauthor, "")
              
              If info\picture <> ""
                GetPicture(info\picture, @info.bookdetails)
              EndIf

              SaveDetails(@info.bookdetails)

              SetActiveGadget(#Gadget_getbook_sauthor)
              
              info\author     = ""
              info\title      = ""
              info\year       = ""
              info\isbn       = ""
              info\publisher  = ""
              info\price      = ""
              info\pages      = ""
              info\type       = ""
              info\picture    = ""
              
            Else

              SetGadgetText(#Gadget_getbook_stitle,  "")
              SetGadgetText(#Gadget_getbook_sauthor, "")

              StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: Could not get the specified books' details")

            EndIf

          Else

            StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: No book reference for the specified title")

          EndIf

        Else

          StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: No ifsdb book reference number for the specified title")

        EndIf

      Else

        StatusBarText(#StatusBar_getbook, #StatusBar_getbook_messages, "Error: Fill in both author and title fields to proceed to the search")

      EndIf

  EndSelect

Return
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Post Reply