File "AliExpress Orders.bas"

Path: /aliexpress/AliExpress Orders.bas
File size: 32.82 KB
MIME-type:
Charset: utf-8


#COMPILE EXE "AliExpress Orders.exe"
#DIM ALL
#RESOURCE "res\aliexpress.pbr"
#INCLUDE ONCE "..\..\WinApi\Win32Api.inc"
#INCLUDE ONCE ".\SendInput.inc"

'---------------------------------------------------------------------------------------
GLOBAL nitem, UPD AS LONG
'---------------------------------------------------------------------------------------
MACRO TMPFILE(i) = "tmp\AE_orders_" + FORMAT$(i, "00") + ".html"
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
FUNCTION PBMAIN()
    MKDIR "tmp"
    KILL  "tmp\*.html"
    ShowMainDlg()
END FUNCTION
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO START_NEW
    CONTROL SET TEXT CB.HNDL, 991, _
          "This program allows you to make an offline, searchable, responsive web table " _
        + "of your AliExpress purchases." _
        + $CRLF _
        + $CRLF _
        + "To proceed, open AliExpress in your PC browser (IE Edge Chrome Firefox...) " _
        + "and connect to your AliExpress account then go to 'My Orders'." _
        + $CRLF _
        + $CRLF _
        + "When you are ready click on 'Next'."
    CONTROL ADD BUTTON, CB.HNDL, 1001, "Next", 320-8-80, 200-8-24, 80, 24
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO START_UPDATE
    UPD = -1
    CONTROL SET TEXT CB.HNDL, 991, _
          "This program allows you to make an offline, searchable, responsive, web table " _
        + "of your AliExpress purchases." _
        + $CRLF _
        + $CRLF _
        + "We detected an existing 'AliExpress Orders.html', " _
        + "would you like to update it with recent purchases ? "
    CONTROL ADD BUTTON, CB.HNDL, 2001, "YES", 320-8-80, 200-8-24, 80, 24
    CONTROL ADD BUTTON, CB.HNDL, 2002,  "No", 320-8-160-8, 200-8-24, 80, 24
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO SHOW_ANIM
    CONTROL SET SIZE CB.HNDL, 991, 320-16, 60
    CONTROL ADD IMAGE, CB.HNDL, 9001, "CPY", 36, 96, 50, 56
    CONTROL ADD IMAGE, CB.HNDL, 9002, "PST", 233, 98, 46, 53
    FOR i = 1 TO 4 ' 9003 to 9006
        CONTROL ADD IMAGE, CB.HNDL, 9002+i, "PG0", 107+29*(i-1), 119, 17, 17
    NEXT
    CONTROL ADD GRAPHIC, CB.HNDL, 9007, "", 107, 87, 110, 24
    idEvent = SetTimer(CB.HNDL, %WM_USER, 250, 0)
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO HIDE_ANIM
    MACROTEMP k
    DIM k AS LONG
    FOR k = 9001 TO 9007
        CONTROL KILL CB.HNDL, k     ' Destroy all animation elements
        DIALOG DOEVENTS
    NEXT
    CONTROL KILL CB.HNDL, 1003      ' and Cancel button
    CONTROL SET SIZE CB.HNDL, 991, 320-16, 200-16-24
    DIALOG DOEVENTS
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO ANIM_PRINT(txt, col)
    GRAPHIC ATTACH CB.HNDL, 9007
    GRAPHIC CLEAR
    GRAPHIC COLOR col
    GRAPHIC PRINT txt
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO LIGHTS_ON
    MACROTEMP k
    DIM k AS LONG
    FOR k = 1 TO 4
        CONTROL SET IMAGE CB.HNDL, 9002+k, "PG1"
        DIALOG DOEVENTS
    NEXT
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO LIGHTS_OFF
    MACROTEMP k
    DIM k AS LONG
    FOR k = 1 TO 4
        CONTROL SET IMAGE CB.HNDL, 9002+k, "PG0"
        DIALOG DOEVENTS
    NEXT
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO ANIM_FLASH
    MACROTEMP k
    DIM k AS LONG
    FOR k = 1 TO 3
        LIGHTS_ON()
        SLEEP 500
        LIGHTS_OFF()
        SLEEP 500
    NEXT
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO SHOW_FINAL_ANIM
    CONTROL KILL CB.HNDL, 9001 ' Left image
    DIALOG DOEVENTS
    CONTROL KILL CB.HNDL, 9002 ' Right image
    DIALOG DOEVENTS
    CONTROL DISABLE CB.HNDL, 1003 ' Cancel button
    n = 0 ' Re-start the WIP animation
    idEvent = SetTimer(CB.HNDL, %WM_USER, 250, 0)
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO FINAL_SCREEN
    HIDE_ANIM()

    IF UPD THEN                             ' UPDATE MODE FINISHED
        IF nitem = 0 THEN
            CONTROL SET TEXT CB.HNDL, 991, _
                  " No new order found :)" _
                + $CRLF _
                + $CRLF _
                + "Your offline, searchable, responsive, web table of " _
                + "AliExpress purchases is already up-to-date !" _
                + $CRLF _
                + $CRLF _
                + "Do you want to view the table now ?"
        ELSE
            CONTROL SET TEXT CB.HNDL, 991, _
                  "Your offline, searchable, responsive, web table of " _
                + "AliExpress purchases has successfully been updated !" _
                + $CRLF _
                + $CRLF _
                + FORMAT$(nitem)+" new item(s) were added." _
                + $CRLF _
                + $CRLF _
                + "The rating for the new orders are still randomized. " _
                + "If you want to give them a correct rating, open the Html file " _
                + "in an editor such as Notepad, and change the numbers after " _
                + "each occurence of: <span class='stars'>" _
                + $CRLF _
                + $CRLF _
                + "Do you want to view your AliExpress Orders table now ?"
        END IF
    ELSE                                    ' NEW TABLE MODE FINISHED
        CONTROL SET TEXT CB.HNDL, 991, _
              "The offline, searchable, responsive, web table of your " _
            + "AliExpress purchases has successfully been generated !" _
            + $CRLF _
            + $CRLF _
            + FORMAT$(nitem)+" items were found across " + FORMAT$(pgIdx)+" pages." _
            + $CRLF _
            + $CRLF _
            + "By default the rating for each order has been randomized. " _
            + "If you want to give a correct rating, open the Html file " _
            + "in an editor such as Notepad, and change the numbers after " _
            + "each occurence of: <span class='stars'>" _
            + $CRLF _
            + $CRLF _
            + "Do you want to view your AliExpress Orders table now ?"
    END IF
    CONTROL ADD BUTTON, CB.HNDL, 3001, "VIEW", 320-8-80, 200-8-24, 80, 24
    CONTROL ADD BUTTON, CB.HNDL, 3002,  "Locate", 320-8-160-8, 200-8-24, 80, 24

END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
CALLBACK FUNCTION ProcMainDlg
    LOCAL e, s AS STRING
    LOCAL i, j AS LONG
    STATIC hThread AS DWORD
    STATIC idEvent AS LONG
    STATIC n AS LONG
    STATIC pgIdx, pgTot AS LONG

    IF CB.MSG = %WM_INITDIALOG THEN                     ' Are we in UPDATE mode or in FIRST-USE mode ?
        e = DIR$("AliExpress Orders.html") : DIR$ CLOSE

        IF e = "" THEN                                  ' FIRST-USE mode
            START_NEW()
        ELSE                                            ' UPDATE mode
            START_UPDATE()
        END IF

    ELSEIF CB.MSG = %WM_COMMAND THEN
        SELECT CASE AS LONG CB.CTL

            '===========================================================================================
            CASE 1001, 2001                             ' START NEW / UPDATE > INSTRUCTIONS
                CONTROL KILL CB.HNDL, 1001
                CONTROL KILL CB.HNDL, 2001
                CONTROL KILL CB.HNDL, 2002
                CONTROL SET TEXT CB.HNDL, 991, _
                      "If you have a lot of orders, we suggest that you display " _
                    + "them ""30/page"" from the drop-down control near the top of the list." _
                    + $CRLF _
                    + $CRLF _
                    + "When you are ready click on 'Next'."
                CONTROL ADD BUTTON, CB.HNDL, 1002,  "Next", 320-8-80, 200-8-24, 80, 24

            '===========================================================================================
            CASE 1002                                   ' START NEW / UPDATE > WIP
                CONTROL KILL CB.HNDL, 1002
                CONTROL SET TEXT CB.HNDL, 991, _
                      "- Hit [ Ctrl + U ] in the Orders page to view its source code" _
                    + $CRLF _
                    + "- Hit [ Ctrl + A ] to select all the code (after it is displayed 100%)" _
                    + $CRLF _
                    + "- Hit [ Ctrl + C ] to copy the source code to the clipboard"
                CONTROL ADD BUTTON, CB.HNDL, 1003,  "Cancel", 320-8-80, 200-8-24, 80, 24
                SHOW_ANIM()
                ANIM_PRINT("Expected: page 1/??", %BLUE)

            '===========================================================================================
            CASE 1003                                   ' START NEW / UPDATE > CANCEL
                CONTROL KILL CB.HNDL, 1003
                IF idEvent THEN KillTimer CB.HNDL, idEvent
                HIDE_ANIM()
                pgIdx = 0
                pgTot = 0
                IF UPD THEN
                    START_UPDATE()
                ELSE
                    START_NEW()
                END IF

            '===========================================================================================
            CASE 2002                                   ' UPDATE EXISTING WITH NEW PURCHASES ? > 'NO'
                CONTROL KILL CB.HNDL, 2001
                CONTROL KILL CB.HNDL, 2002
                CONTROL SET TEXT CB.HNDL, 991, _
                      "Are you sure you want to start from new and erase (overwrite) " _
                    + "your existing table of purchases ?"
                CONTROL ADD BUTTON, CB.HNDL, 2003, "ERASE", 320-8-80, 200-8-24, 80, 24
                CONTROL ADD BUTTON, CB.HNDL, 2004,  "Prev.", 320-8-160-8, 200-8-24, 80, 24

            '===========================================================================================
            CASE 2003                                   ' OVERWRITE EXISTING TABLE
                CONTROL KILL CB.HNDL, 2003
                CONTROL KILL CB.HNDL, 2004
                KILL "AliExpress Orders.html"
                UPD = 0
                START_NEW()

            '===========================================================================================
            CASE 2004                                   ' DO NOT OVERWRITE EXISTING TABLE
                CONTROL KILL CB.HNDL, 2003
                CONTROL KILL CB.HNDL, 2004
                START_UPDATE()

            '===========================================================================================
            CASE 3001                                   ' VIEW ORDERS TABLE
                ShellExecute %NULL, "open", "AliExpress Orders.html", $NUL, $NUL, %SW_SHOW

            '===========================================================================================
            CASE 3002                                   ' LOCATE ORDERS TABLE
                ShellExecute %NULL, "open", "explorer.exe" + $NUL, _
                    "/select,""AliExpress Orders.html""", $NUL, %SW_SHOW

            '===========================================================================================
            CASE %IDCANCEL                              ' USER PRESSED 'ESC' > EXIT
                DIALOG END CB.HNDL
                EXITPROCESS 12345 ' terminate ourself
                EXIT FUNCTION

        END SELECT

    '===========================================================================================
    ELSEIF CB.MSG = %WM_TIMER THEN
                                                        ' DO THE ANIMATION
        IF n > 0 THEN CONTROL SET IMAGE CB.HNDL, 9002+n, "PG0"
        n = (n MOD 4) + 1
        CONTROL SET IMAGE CB.HNDL, 9002+n, "PG1"

        IF hThread <> 0 THEN
            THREAD STATUS hThread TO i                  ' CHECK ON 'MAKE_AE' THREAD
            IF i <> &H103 AND i <> 0 THEN
                KillTimer CB.HNDL, idEvent
                THREAD CLOSE hThread TO i
                hThread = 0
                FINAL_SCREEN()
                EXIT FUNCTION
            END IF
        END IF

        CLIPBOARD GET TEXT TO e                         ' WAIT FOR SOURCE CODE IN CLIPBOARD
        IF INSTR(e, "<html>") > 0 AND _
           INSTR(e, "Alibaba Manufacturer Directory") > 0 AND _
           INSTR(e, "<label class=""ui-label") > 0 AND _
           INSTR(e, "</html>") > 0 THEN
           KillTimer   CB.HNDL, idEvent                 ' Pause the timer event in order to do treatment...
           DIALOG SEND CB.HNDL, %WM_USER, 0, 0
        END IF

    '===========================================================================================
    ELSEIF CB.MSG = %WM_USER THEN                       ' TREAT CONTENT IN CLIPBOARD

        ANIM_PRINT("TREATING ORDERS", RGB(30,198,0))
        LIGHTS_OFF()

        SendString "{CTRL_D}w{CTRL_U}"                  ' Close source code page
        ShowWindow CB.HNDL, 6 : ShowWindow CB.HNDL, 1   ' and show AE dialog on top
        DIALOG DOEVENTS                                 ' Force dialog redraw
        DIALOG REDRAW CB.HNDL
        DIALOG DOEVENTS

        CLIPBOARD GET TEXT TO e : e = UnixToWinEOL(e)   ' Get clipboard content then clear it
        CLIPBOARD RESET

        i = INSTR(e, "<label class=""ui-label")         ' Check if we have the correct page
        i = INSTR(i+1, e, ">") + 1
        j = INSTR(i+1, e, "<")
        s = MID$(e, i, j-i)
        IF pgTot = 0 THEN pgTot = VAL(MID$(s, INSTR(s, "/")+1))
        j = VAL(LEFT$(s, INSTR(s, "/")-1))

        FOR i = 1 TO pgTot                              ' Special hack for fast re-build of orders table
            s = DIR$(TMPFILE(i)) : DIR$ CLOSE
            IF s = "" THEN EXIT FOR
        NEXT
        IF s <> "" AND INSTR(TMPFILE(pgTot), s) > 0 THEN
            IF MSGBOX( "Do a fast re-build of the table " _
                     + "from " + FORMAT$(pgTot) + " pages ?" _
                     , %MB_ICONQUESTION OR %MB_YESNO _
                     , EXE.NAME$) = %IDYES THEN
                pgIdx = pgTot - 1
                j = pgIdx + 1
                OPEN TMPFILE(pgTot) FOR BINARY ACCESS READ AS #i
                GET$ #i, LOF(#i), e
                CLOSE #i
            END IF
        END IF

        IF j <> pgIdx + 1 THEN                          ' Wrong page: show error message & wait for user to try again
            ANIM_PRINT("Error: wrong page", %RED)
            ANIM_FLASH()                                ' 3s flashing animation
            ANIM_PRINT("Expected: page "+FORMAT$(pgIdx+1) _
                  +"/"+FORMAT$(pgTot), %BLUE)
            n = 0
            idEvent = SetTimer(CB.HNDL, %WM_USER, 250, 0)
            EXIT FUNCTION
        END IF

        INCR pgIdx                                      ' Correct page: create the temporary page on disk
        i = FREEFILE
        KILL TMPFILE(pgIdx)
        OPEN TMPFILE(pgIdx) FOR BINARY ACCESS WRITE AS #i
        PUT$ #i, e
        CLOSE #i
        ANIM_FLASH()                                    ' Do a nice 3s animation and move on

        IF UPD THEN                                     ' UPDATE mode > look if we've reached a known order reference
            IF ISTRUE ReachedExistingRef(pgIdx) THEN
                ANIM_PRINT("UPDATING TABLE", RGB(30,198,0))
                SHOW_FINAL_ANIM()
                THREAD CREATE MAKE_AE(CB.HNDL) TO hThread
                EXIT FUNCTION
            END IF
        END IF

        IF pgIdx = pgTot THEN                           ' We have reached the last page > make the orders table
            ANIM_PRINT("GENERATING TABLE", RGB(30,198,0))
            SHOW_FINAL_ANIM()
            THREAD CREATE MAKE_AE(CB.HNDL) TO hThread
            EXIT FUNCTION

        ELSEIF pgIdx = 1 THEN                           ' Slightly modify the instructions for page 2 and onward
            CONTROL SET TEXT CB.HNDL, 991, _
                  "Use the right arrow to go to the next page of your orders, then" _
                + $CRLF _
                + "- Hit [ Ctrl + U ] in the Orders page to view its source code" _
                + $CRLF _
                + "- Hit [ Ctrl + A ] to select all the code (after it is displayed 100%)" _
                + $CRLF _
                + "- Hit [ Ctrl + C ] to copy the source code to the clipboard"
        END IF

        ANIM_PRINT("Expected: page "+FORMAT$(pgIdx+1) _ ' Display the next page number to be imported
                  +"/"+FORMAT$(pgTot), %BLUE)

        n = 0 ' Re-start the WIP animation
        idEvent = SetTimer(CB.HNDL, %WM_USER, 250, 0)

    END IF
END FUNCTION
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
FUNCTION ShowMainDlg() AS LONG
    LOCAL hD AS DWORD

    DIALOG NEW PIXELS, 0, EXE.NAME$,,, 320, 200, _
      %DS_MODALFRAME OR %WS_CAPTION OR %WS_POPUP OR _
      %WS_SYSMENU OR %WS_MINIMIZEBOX, TO hD
    DIALOG SET ICON hD, "ICO1"

    CONTROL ADD LABEL,   hD, 991, "", 8, 8, 320-16, 200-16-24
    CONTROL ADD BUTTON,  hD, %IDCANCEL, "Cancel", -10, -10, 0, 0

    DIALOG SHOW MODAL    hD, CALL ProcMainDlg

END FUNCTION
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO FIND_STR(what)
    DO
        LINE INPUT #ff, e
    LOOP UNTIL EOF(#ff) OR INSTR(LCASE$(e), LCASE$(what)) <> 0
    IF EOF(#ff) THEN DECR nitem : GOTO NextHtml
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO REDIM_AR()
    INCR nitem
    REDIM PRESERVE oid(nitem)
    REDIM PRESERVE dat(nitem)
    REDIM PRESERVE eur(nitem)
    REDIM PRESERVE sta(nitem)
    REDIM PRESERVE img(nitem)
    REDIM PRESERVE des(nitem)
    REDIM PRESERVE opn(nitem)
    REDIM PRESERVE sto(nitem)
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO RMV_AR(i)
    MACROTEMP k
    DIM k AS LONG
    FOR k = UBOUND(oid) - 1 TO i STEP -1
        oid(k) = oid(k+1)
        dat(k) = dat(k+1)
        eur(k) = eur(k+1)
        sta(k) = sta(k+1)
        img(k) = img(k+1)
        des(k) = des(k+1)
        opn(k) = opn(k+1)
        sto(k) = sto(k+1)
    NEXT
    DECR nitem
    REDIM PRESERVE oid(nitem)
    REDIM PRESERVE dat(nitem)
    REDIM PRESERVE eur(nitem)
    REDIM PRESERVE sta(nitem)
    REDIM PRESERVE img(nitem)
    REDIM PRESERVE des(nitem)
    REDIM PRESERVE opn(nitem)
    REDIM PRESERVE sto(nitem)
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
MACRO READ_LIN(n)
    FOR k = 1 TO n
        LINE INPUT #ff, e
    NEXT
END MACRO
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
FUNCTION TranslateDate(BYVAL e AS STRING) AS STRING
    LOCAL r AS STRING
    LOCAL i, j AS LONG

    i = INSTR(-1, LCASE$(e), "</span>")
    IF i = 0 THEN EXIT FUNCTION
    r = MID$(e, i-4, 4) + "-"               ' Year

    IF INSTR(e, "Jan.") > 0 THEN r += "01"  ' Month
    IF INSTR(e, "Feb.") > 0 THEN r += "02"
    IF INSTR(e, "Mar.") > 0 THEN r += "03"
    IF INSTR(e, "Apr.") > 0 THEN r += "04"
    IF INSTR(e, "May.") > 0 THEN r += "05"
    IF INSTR(e, "Jun.") > 0 THEN r += "06"
    IF INSTR(e, "Jul.") > 0 THEN r += "07"
    IF INSTR(e, "Aug.") > 0 THEN r += "08"
    IF INSTR(e, "Sep.") > 0 THEN r += "09"
    IF INSTR(e, "Oct.") > 0 THEN r += "10"
    IF INSTR(e, "Nov.") > 0 THEN r += "11"
    IF INSTR(e, "Dec.") > 0 THEN r += "12"

    i = INSTR(e, ".")
    IF i = 0 THEN EXIT FUNCTION
    i += 2
    j = INSTR(i, e, " ")
    IF j = 0 THEN EXIT FUNCTION
    r += "-" + MID$(e, i, j-i)              ' Day

    FUNCTION = r
END FUNCTION
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
FUNCTION InBetween(BYVAL e AS STRING, BYVAL delim1 AS STRING, BYVAL delim2 AS STRING) AS STRING
    LOCAL i, j AS LONG
    i = INSTR(e, delim1)
    IF i = 0 THEN EXIT FUNCTION ELSE i += LEN(delim1)
    j = INSTR(i, e, delim2)
    IF j = 0 THEN EXIT FUNCTION
    FUNCTION = MID$(e, i, j-i)
END FUNCTION
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
FUNCTION UnixToWinEOL(BYVAL e AS STRING) AS STRING
    IF TALLY(e, $CRLF) < TALLY(e, $LF) THEN
        REPLACE $CR WITH $CRLF IN e
        REPLACE $LF WITH $CRLF IN e
        REPLACE $LF+$LF WITH $LF IN e
        REPLACE $CR+$CR WITH $CR IN e
    END IF
    WHILE INSTR(e, $CRLF+$TAB) > 0          ' Remove leading Tabs
        REPLACE $CRLF+$TAB WITH $CRLF IN e
    WEND
    WHILE INSTR(e, $CRLF+$SPC) > 0          ' Remove leading Spaces
        REPLACE $CRLF+$SPC WITH $CRLF IN e
    WEND                                    ' Replace Tabs with Spaces
    REPLACE $TAB WITH $SPC IN e
    WHILE INSTR(e, $CRLF+$CRLF) > 0         ' Remove empty lines
        REPLACE $CRLF+$CRLF WITH $CRLF IN e
    WEND
    FUNCTION = e
END FUNCTION
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
FUNCTION ReachedExistingRef(BYVAL nn AS LONG) AS LONG
' Have we reached an order ref. ID in "tmp\AE_orders_nn.html"
' that already exists in "AliExpress Orders.html" ?

    LOCAL ff AS LONG
    LOCAL aeo AS STRING
    LOCAL e, oid AS STRING

    ' Get existing AE orders
    ff = FREEFILE
    OPEN "AliExpress Orders.html" FOR BINARY AS #ff
    GET$ #ff, LOF(#ff), aeo
    CLOSE #ff

    ' Analyze temp file #nn
    ff = FREEFILE
    OPEN TMPFILE(nn) FOR INPUT AS #ff

AnaRer:
    DO
        LINE INPUT #ff, e
    LOOP UNTIL EOF(#ff) OR INSTR(LCASE$(e), "order-info") > 0
    IF EOF(#ff) THEN GOTO EndReR
    DO
        LINE INPUT #ff, e
    LOOP UNTIL EOF(#ff) OR INSTR(LCASE$(e), "info-body") > 0
    IF EOF(#ff) THEN GOTO EndReR
    oid = InBetween(e, ">", "<")

    IF INSTR(aeo, "<!--" + oid + "-->") > 0 THEN
        FUNCTION = -1
        GOTO EndReR
    END IF
    GOTO AnaRer ' loop for next order

EndReR:
    CLOSE #ff
    EXIT FUNCTION

END FUNCTION
'---------------------------------------------------------------------------------------

'---------------------------------------------------------------------------------------
THREAD FUNCTION MAKE_AE (BYVAL hDlg AS LONG) AS LONG

    LOCAL oid() AS STRING
    LOCAL dat() AS STRING
    LOCAL eur() AS STRING
    LOCAL sta() AS STRING
    LOCAL img() AS STRING
    LOCAL des() AS STRING
    LOCAL opn() AS STRING
    LOCAL sto() AS STRING

    LOCAL ff, nhtml, i, j, k AS LONG
    LOCAL e, old, aeo AS STRING

    ' Count html files
    DO
        INCR i
        e = DIR$(TMPFILE(i))
        DIR$ CLOSE
    LOOP UNTIL e = ""
    nhtml = i - 1

    ' No html files
    IF nhtml = 0 THEN FUNCTION = 2 : EXIT FUNCTION

    ' Initialize arrays
    DIM oid(0)  :   DIM dat(0)  :   DIM sto(0)  :   DIM eur(0)
    DIM img(0)  :   DIM des(0)  :   DIM opn(0)  :   DIM sta(0)
    nitem = 0

    ' Parse each html file
    FOR i = 1 TO nhtml
        ff = FREEFILE
        OPEN TMPFILE(i) FOR INPUT AS #ff
        FIND_STR("<table")

NewItem:
        REDIM_AR() ' redimension all arrays

        ' Extract Order Id
        FIND_STR("first-row")
        READ_LIN(2)
        oid(nitem) = InBetween(e, ">", "<")

        ' Extract Date in format YYYY-MM-DD
        FIND_STR("second-row")
        READ_LIN(2) ' "00:05 May. 18 2020"
        dat(nitem) = TranslateDate(e)

        ' Extract Store Name and Link
        FIND_STR("store-info")
        READ_LIN(3)
        sto(nitem) = InBetween(e, ">", "<")
        FIND_STR("second-row")
        READ_LIN(1)
        sto(nitem) = "<a target='_blank' href='https://" + InBetween(e, "//", $DQ) + "'>" + sto(nitem) + "</a>"

        ' Extract item amount
        FIND_STR("amount-num")
        READ_LIN(1)
        eur(nitem) = TRIM$(e)

        ' Extract image
        FIND_STR("<img")
        e = InBetween(e, $DQ, $DQ)
        img(nitem) = "<img src='" + e + "'>"
        e = REMOVE$(e, "_50x50.jpg")
        e = REMOVE$(e, "_50x50.png")
        img(nitem) = "<a target='_blank' href='" + e + "'>" + img(nitem) + "</a>"


        ' Extract Item Description and Link
        FIND_STR("product-title")
        READ_LIN(1)
        des(nitem) = "<a target='_blank' href='https://" + InBetween(e, "//", $DQ) + "'>" + InBetween(e, ">", "<") + "</a>"
        REPLACE $DQ WITH "'" IN des(nitem)

        ' Extract Item Options
        FIND_STR("product-property")
        READ_LIN(3)
        e = TRIM$(e)
        IF LEFT$(e, 1) <> "<" THEN opn(nitem) = e

        ' Extract Order Status
        FIND_STR("order-status")
        READ_LIN(3)
        sta(nitem) = TRIM$(e)

        GOTO NewItem

NextHtml:
        CLOSE #ff
    NEXT

    IF UPD THEN GOTO UpdateAE       ' Redirect to specific treatment if we just update

    ff = FREEFILE                   ' Else we build the orders table from scratch here:
    OPEN "AliExpress Orders.html" FOR OUTPUT AS #ff
    PRINT #ff, "<!DOCTYPE html>"
    PRINT #ff, "<html lang='en'>"
    PRINT #ff, "<head>"
    PRINT #ff, "<meta charset='UTF-8'>"
    PRINT #ff, "<meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'>"
    PRINT #ff, "<meta http-equiv='x-ua-compatible' content='ie=edge'>"
    PRINT #ff, "<title>My AliExpress Orders</title>"
    PRINT #ff, "<link rel='icon' href='https://ae01.alicdn.com/images/eng/wholesale/icon/aliexpress.ico' type='image/x-icon'>"
    PRINT #ff, "<link rel='stylesheet' href='https://use.fontawesome.com/releases/v5.11.2/css/all.css'>"
    PRINT #ff, "<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap'>"
    PRINT #ff, "<link rel='stylesheet' href='http://mougino.free.fr/ae/css/bootstrap.min.css'>"
    PRINT #ff, "<link rel='stylesheet' href='http://mougino.free.fr/ae/css/mdb.min.css'>"
    PRINT #ff, "<link rel='stylesheet' href='http://mougino.free.fr/ae/css/style.css'>"
    PRINT #ff, "<link href='http://mougino.free.fr/ae/css/addons/datatables.min.css' rel='stylesheet'>"
    PRINT #ff, "<style>.centered{margin:auto; width: 90%}</style>"
    PRINT #ff, "<style>span.stars,span.stars span{font-size:0;display:block;background:url(http://mougino.free.fr/ae/stars.png) " _
             + "0 -16px repeat-x;width:80px;height:16px}span.stars span{background-position:0 0}</style>"
    PRINT #ff, "</head><body>"

    PRINT #ff, "<br>"
    PRINT #ff, "<div class='centered'>"
    PRINT #ff, "<h2>My AliExpress Orders</h2>"
    PRINT #ff, "<table id='ae' class='table'>"
    PRINT #ff, "<thead><tr>"
    PRINT #ff, "<th class='th-sm'>#</th>"
    PRINT #ff, "<th class='th-sm'>Date</th>"
    PRINT #ff, "<th class='th-sm'>Price</th>"
    PRINT #ff, "<th class='th-sm'>Status</th>"
    PRINT #ff, "<th class='th-sm'>Image</th>"
    PRINT #ff, "<th class='th-sm'>Description</th>"
    PRINT #ff, "<th class='th-sm'>Options</th>"
    PRINT #ff, "<th class='th-sm'>Store</th>"
    PRINT #ff, "<th class='th-sm'>Rating</th>"
    PRINT #ff, "</tr></thead><tbody>"

    FOR i = 1 TO nitem
        PRINT #ff, "<!--" + oid(i) + "-->"
        PRINT #ff, "<tr>"
        PRINT #ff, "<td>" + FORMAT$(nitem - i + 1) + "</th>"
        PRINT #ff, "<td>" + dat(i) + "</td>"
        PRINT #ff, "<td>" + eur(i) + "</td>"
        PRINT #ff, "<td>" + sta(i) + "</td>"
        PRINT #ff, "<td>" + img(i) + "</td>"
        PRINT #ff, "<td>" + des(i) + "</td>"
        PRINT #ff, "<td>" + opn(i) + "</td>"
        PRINT #ff, "<td>" + sto(i) + "</td>"
        PRINT #ff, "<td><span class='stars'>" _
                 +  FORMAT$(INT(5*RND()*100)/100) _
                 + "</span></td>"
        PRINT #ff, "</tr>"
    NEXT

    PRINT #ff, "<tfoot><tr>"
    PRINT #ff, "<th>#</th>"
    PRINT #ff, "<th>Date</th>"
    PRINT #ff, "<th>Price</th>"
    PRINT #ff, "<th>Status</th>"
    PRINT #ff, "<th>Image</th>"
    PRINT #ff, "<th>Description</th>"
    PRINT #ff, "<th>Options</th>"
    PRINT #ff, "<th>Store</th>"
    PRINT #ff, "<th>Rating</th>"
    PRINT #ff, "</tr></tfoot></table></div>"

    PRINT #ff, "<script type='text/javascript' src='http://mougino.free.fr/ae/js/jquery.min.js'></script>"
    PRINT #ff, "<script type='text/javascript' src='http://mougino.free.fr/ae/js/popper.min.js'></script>"
    PRINT #ff, "<script type='text/javascript' src='http://mougino.free.fr/ae/js/bootstrap.min.js'></script>"
    PRINT #ff, "<script type='text/javascript' src='http://mougino.free.fr/ae/js/mdb.min.js'></script>"
    PRINT #ff, "<script type='text/javascript' src='http://mougino.free.fr/ae/js/addons/datatables.min.js'></script>"
    PRINT #ff, "<script>$.fn.stars=function(){return $(this).each(function(){var t=parseFloat($(this).html())," _
             + "a=16*Math.max(0,Math.min(5,t)),h=$('<span />').width(a).text(parseInt(t*100));$(this).html(h)})};</script>"
    PRINT #ff, "<script>$(document).ready(function(){$('span.stars').stars();" _
             + "$('#ae').DataTable();$('.dataTables_length').addClass('bs-select');});</script>"
    PRINT #ff, "</body></html>"
    CLOSE#ff

    FUNCTION = 1
    EXIT FUNCTION


UpdateAE:
    '---------------------------------------------------------------------------------------
    KILL "AliExpress Orders.bkp"
    NAME "AliExpress Orders.html" AS "AliExpress Orders.bkp"

    ' Get existing AE orders
    ff = FREEFILE
    OPEN "AliExpress Orders.bkp" FOR BINARY AS #ff
    GET$ #ff, LOF(#ff), aeo
    CLOSE #ff

    ' Remove existing orders from the list
    FOR i = nitem TO 1 STEP -1
        IF INSTR(aeo, "<!--" + oid(i) + "-->") > 0 THEN
            RMV_AR(i)
        END IF
    NEXT
    IF nitem = 1 AND INSTR(aeo, "<!--" + oid(1) + "-->") > 0 THEN
        DECR nitem
        FUNCTION = 1
        EXIT FUNCTION
    END IF

    ' Now update the orders table!
    e = ""
    FOR i = 1 TO nitem
        e += "<!--" + oid(i) + "-->" + $CRLF
        e += "<tr>" + $CRLF
        e += "<td>" + FORMAT$(nitem - i + 1) + "</th>" + $CRLF
        e += "<td>" + dat(i) + "</td>" + $CRLF
        e += "<td>" + eur(i) + "</td>" + $CRLF
        e += "<td>" + sta(i) + "</td>" + $CRLF
        e += "<td>" + img(i) + "</td>" + $CRLF
        e += "<td>" + des(i) + "</td>" + $CRLF
        e += "<td>" + opn(i) + "</td>" + $CRLF
        e += "<td>" + sto(i) + "</td>" + $CRLF
        e += "<td><span class='stars'>" _
                 +  FORMAT$(INT(5*RND()*100)/100) _
                 + "</span></td>" + $CRLF
        e += "</tr>" + $CRLF
    NEXT
    k = INSTR(aeo, "<!--")
    aeo = LEFT$(aeo, k-1) + e + MID$(aeo, k)

    ' And write it to disk
    KILL "AliExpress Orders.html"
    ff = FREEFILE
    OPEN "AliExpress Orders.html" FOR BINARY AS #ff
    PUT$ #ff, aeo
    CLOSE #ff

    FUNCTION = 1
    EXIT FUNCTION

END FUNCTION
'---------------------------------------------------------------------------------------