Author Topic: reading remote text file  (Read 5360 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
reading remote text file
« on: May 15, 2021, 11:24:26 am »
I thought I saw a thread here awhile ago regarding this, might have been a different language.

can qb64 read a remote txtfile?

example mycoolsite.com/textfile.txt

was trying (of course unsuccessfully) the open command.

thanks guys

ps
Its the weekend, working on another goofy project.

I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline 191Brian

  • Newbie
  • Posts: 91
    • View Profile
    • My Itch page
Re: reading remote text file
« Reply #1 on: May 15, 2021, 03:36:28 pm »
Pretty sure the answer is no, open only works on files local to you either on your PC or network share.
Brian ...

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: reading remote text file
« Reply #2 on: May 15, 2021, 03:55:06 pm »
You can look at the QB64 wiki download program I have here, as an example, if you’re just transfering over http and not https: https://www.qb64.org/forum/index.php?topic=756.msg6455#msg6455

Basically, use _OPENCLIENT and GET to do the work:

SUB DownloadRSS (url$, file$, timelimit)
    link$ = url$
    DIM l AS _INTEGER64, lod AS _INTEGER64
 
    url2$ = RTRIM$(LTRIM$(link$))
    url4$ = RTRIM$(LTRIM$(link$))
    IF LEFT$(UCASE$(url2$), 7) = "HTTP://" THEN url4$ = MID$(url2$, 8)
    x = INSTR(url4$, "/")
    IF x THEN url2$ = LEFT$(url4$, x - 1)
    NewsClient = _OPENCLIENT("TCP/IP:80:" + url2$)
    IF NewsClient = 0 THEN EXIT FUNCTION
    e$ = CHR$(13) + CHR$(10) ' end of line characters
    url3$ = RIGHT$(url4$, LEN(url4$) - x + 1)
    x$ = "GET " + url3$ + " HTTP/1.1" + e$
    x$ = x$ + "Host: " + url2$ + e$ + e$
    PUT #NewsClient, , x$
 
    OPEN file$ FOR OUTPUT AS #1: CLOSE #1
    OPEN file$ FOR BINARY AS #1
 
    t! = TIMER ' start time
    head$ = ""
    cont_type$ = ""
    DO
        _LIMIT 20
        GET #NewsClient, , a$
        IF LTRIM$(a$) > "" THEN PUT #1, , a$
    LOOP UNTIL TIMER > t! + timelimit AND timelimit > 0 ' (in seconds)
    CLOSE #NewsClient
    CLOSE #1
END SUB
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: reading remote text file
« Reply #3 on: May 15, 2021, 04:41:17 pm »
I checked the wiki with no luck, but only because I had no direction - "open" was all I knew.

This is good, I will part it out and see how it ticks!!

what I am doing is pulling a simple text file from one of my sites, I could just turn off the SSL and from what you said it should work.

Out of necessity, I wrote a "chocolatey" alternative (qb64), but much more simpler, been using it for last few years - I wanted something simple without complexity. works great. however I want a centralized DB instead of locally. So trying the old fashion text method - it works, and does not need something advanced as SQL(programing sql for remote access is an overkill for what I want). I basically just keep track of appname and link to it directly.



thanks!

I'll let you know if this works... and post a code here.
« Last Edit: May 15, 2021, 04:50:17 pm by xra7en »
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline zaadstra

  • Newbie
  • Posts: 78
    • View Profile
Re: reading remote text file
« Reply #4 on: May 15, 2021, 05:00:00 pm »
I use(d) to do this with a shell and wget command, then open the downloaded file.
But the example from SMcNeill looks very cool! Especially the timeout will be helpful too.
Looking forward to more examples here! :-)

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: reading remote text file
« Reply #5 on: May 15, 2021, 05:02:43 pm »
I would just use the WinAPI function sets. The easiest one is URLDownloadToFile
Shuwatch!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: reading remote text file
« Reply #6 on: May 15, 2021, 05:18:13 pm »
actually I ended up using curl like the rest of my app does. der!!!
 wget I get all kinds of security errors when I use it. Curl works good with the following command:

Code: QB64: [Select]
  1. curl -LO -k [url]

I like what McNiel has, but I cannot get it to work. returns a 0 every time. I'll have to tinker with that later. I like it better than curl or wget as it is part of qb64.
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Marked as best answer by xra7en on May 16, 2021, 03:34:39 am

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: reading remote text file
« Reply #7 on: May 15, 2021, 06:29:25 pm »
This doesn't require curl or any other external shell program.

Code: QB64: [Select]
  1.     Function URLDownloadToFileA%& (ByVal pCaller As Long, szURL As String, szFileName As String, Byval dwReserved As Long, Byval lpfnCB As Long)
  2.  
  3. Function FileDownload%& (URL As String, File As String)
  4.     FileDownload = URLDownloadToFileA(0, URL + Chr$(0), File + Chr$(0), 0, 0)
Shuwatch!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: reading remote text file
« Reply #8 on: May 16, 2021, 07:40:35 am »
well that worked amazing simple!! Wish I knew more about API's and how to use them in qb64

I started a progress bar question here: https://www.qb64.org/forum/index.php?topic=3913.0
obviously on larger files I would like to display something... so I know it is not locked up
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: reading remote text file
« Reply #9 on: May 16, 2021, 10:44:47 am »
hmmm doesn't work all the time

example
using

Code: QB64: [Select]
  1. fn$="Git-2.31.1-64-bit.exe"
  2. url$ = "https://github.com/git-for-windows/git/releases/download/v2.31.1.windows.1/Git-2.31.1-64-bit.exe"
  3. filedownload(url$,fn$)

does nothing. no download

but works flawlessly when downloading a text file.
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: reading remote text file
« Reply #10 on: May 16, 2021, 10:59:54 am »
If that's the case then you probably need to use a more complex API function set. I have code for this but I'm currently on my phone. I have code that tracks progress as well as downloads any file. It will be a few hours before I can get it to you, though.
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: reading remote text file
« Reply #11 on: May 16, 2021, 03:39:03 pm »
@xra7en

This code allows for downloading of any file type and will track the progress of the download as long as it can query the webpage for the file size. You can edit it however you like for your own needs.

Code: QB64: [Select]
  1.  
  2. Const INTERNET_OPEN_TYPE_DIRECT = 1
  3.  
  4. Const INTERNET_DEFAULT_HTTP_PORT = 80
  5. Const INTERNET_DEFAULT_HTTPS_PORT = 443
  6.  
  7. Const INTERNET_SERVICE_HTTP = 3
  8.  
  9. 'Flags
  10. Const INTERNET_FLAG_SECURE = &H00800000
  11. Const INTERNET_FLAG_RELOAD = &H80000000
  12.  
  13. Const HTTP_QUERY_CONTENT_LENGTH = 5
  14.  
  15. Const TRUE = 1
  16. 'CONST FALSE = 0
  17.  
  18.     Function InternetOpen%& Alias "InternetOpenA" (ByVal lpszAgent As _Offset, Byval dwAccessType As Long, Byval lpszProxy As _Offset, Byval lpszProxyBypass As _Offset, Byval dwFlags As Long)
  19.     Function InternetConnect%& Alias "InternetConnectA" (ByVal hInternet As _Offset, Byval lpszServerName As _Offset, Byval nServerPort As Integer, Byval lpszUserName As _Offset, Byval lpszPassword As _Offset, Byval dwService As Long, Byval dwFlags As Long, Byval dwContext As _Offset)
  20.     Function HTTPOpenRequest%& Alias "HttpOpenRequestA" (ByVal hConnect As _Offset, Byval lpszVerb As _Offset, Byval lpszObjectName As _Offset, Byval lpszVersion As _Offset, Byval lpszReferrer As _Offset, Byval lpszAcceptTypes As _Offset, Byval dwFlags As Long, Byval dwContext As _Offset)
  21.     Function HTTPSendRequest%% Alias "HttpSendRequestA" (ByVal hRequest As _Offset, Byval lpszHeaders As _Offset, Byval dwHeadersLength As Long, Byval lpOptional As _Offset, Byval dwOptionalLength As Long)
  22.     Sub InternetCloseHandle (ByVal hInternet As _Offset)
  23.     Function InternetReadFile%% (ByVal hFile As _Offset, Byval lpBuffer As _Offset, Byval dwNumberOfBytesToRead As Long, Byval lpdwNumberOfBytesRead As _Offset)
  24.     Function HTTPQueryInfo%% Alias "HttpQueryInfoA" (ByVal hRequest As _Offset, Byval dwInfoLevel As Long, Byval lpBuffer As _Offset, Byval lpdwBufferLength As _Offset, Byval lpdwIndex As _Offset)
  25.  
  26.     Function GetLastError& ()
  27.     Sub SetLastError (ByVal dwErrCode As Long)
  28.     Function FormatMessage& Alias "FormatMessageA" (ByVal dwFlags As Long, Byval lpSource As Long, Byval dwMessageId As Long, Byval dwLanguageId As Long, Byval lpBuffer As _Offset, Byval nSize As Long, Byval Arguments As _Offset)
  29.  
  30. Declare CustomType Library ".\offsettostring"
  31.     Function offset_to_string$ Alias "offset_to_offset" (ByVal offset As _Offset)
  32.  
  33.     Function MAKELANGID& (ByVal p As Long, Byval s As Long)
  34.  
  35.  
  36. Screen _NewImage(480, 80, 32)
  37.  
  38. _Title "URL Downloader"
  39. _ConsoleTitle "Enter Link"
  40. Dim filename As String
  41.  
  42.     Cls
  43.     Line Input "Link: ", link
  44.     Line Input "File Name : ", filename
  45. Loop Until link <> "" And filename <> ""
  46. _Title _Title$ + " - " + Mid$(filename, _InStrRev(filename, "\") + 1)
  47.  
  48.  
  49. DownloadLink link, filename
  50.  
  51. Sub DownloadLink (URL As String, File As String)
  52.     Dim As String URLFile
  53.     URLFile = URL
  54.     Dim As _Offset hsession
  55.     hsession = InternetOpen(0, INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0)
  56.     If hsession = 0 Then
  57.         Cls
  58.         Print "Error : InternetOpen", ErrorMessage(GetLastError)
  59.         InternetCloseHandle hsession
  60.         Exit Sub
  61.     End If
  62.  
  63.     Dim As _Offset httpsession
  64.     URL = Mid$(URL, InStr(URL, "/") + 2)
  65.     URL = Mid$(URL, 1, InStr(URL, "/") - 1)
  66.  
  67.     httpsession = InternetConnect(hsession, _Offset(URL), INTERNET_DEFAULT_HTTPS_PORT, 0, 0, INTERNET_SERVICE_HTTP, 0, 0)
  68.     If httpsession = 0 Then
  69.         Cls
  70.         Print "Error : Internet Connect", ErrorMessage(GetLastError)
  71.         InternetCloseHandle hsession
  72.         Exit Sub
  73.     End If
  74.  
  75.     Dim As _Offset httpRequest
  76.     Dim As String sessiontype, location, accepttypes
  77.     sessiontype = "GET" + Chr$(0)
  78.     location = Mid$(URLFile, InStr(URLFile, URL) + Len(URL)) + Chr$(0)
  79.     accepttypes = "*/*" + Chr$(0)
  80.     httpRequest = HTTPOpenRequest(httpsession, _Offset(sessiontype), _Offset(location), 0, 0, _Offset(accepttypes), INTERNET_FLAG_RELOAD Or INTERNET_FLAG_SECURE, 0)
  81.     If httpRequest = 0 Then
  82.         Cls
  83.         Print "Error : HTTPOpenRequest", ErrorMessage(GetLastError)
  84.         InternetCloseHandle hsession
  85.         Exit Sub
  86.     End If
  87.  
  88.     Dim As Long sendrequest
  89.     Dim As String headers
  90.     headers = ""
  91.     sendrequest = HTTPSendRequest(httpRequest, 0, 0, 0, 0)
  92.     If sendrequest <> TRUE Then
  93.         Cls
  94.         Print "Error : HTTPSendRequest", ErrorMessage(GetLastError)
  95.         InternetCloseHandle hsession
  96.         Exit Sub
  97.     End If
  98.  
  99.  
  100.     Dim As _Byte query
  101.     Dim As String queryinfo
  102.     queryinfo = Space$(1024)
  103.     Dim As Long querylen
  104.     querylen = Len(queryinfo) - 1
  105.  
  106.     query = HTTPQueryInfo(httpRequest, HTTP_QUERY_CONTENT_LENGTH, _Offset(queryinfo), _Offset(querylen), 0)
  107.     If query <> TRUE Then
  108.         Cls
  109.         Print "Error : HTTPQueryInfo", ErrorMessage(GetLastError)
  110.         InternetCloseHandle hsession
  111.     End If
  112.  
  113.     Dim As Long bytesToRead
  114.     bytesToRead = Val(queryinfo)
  115.  
  116.     Dim As String szBuffer
  117.     szBuffer = Space$(4097)
  118.     Dim As _Unsigned Long dwRead, bytesRead
  119.     If _FileExists(File) Then
  120.         Kill File
  121.     End If
  122.     Open File For Binary As #1
  123.     Dim As _Byte a
  124.     Dim As String filedownload
  125.     Dim As Long errr, bytesForRate
  126.     Dim x!
  127.     Dim y!
  128.     Dim Rate!
  129.     Dim As Single ratetime
  130.     Do
  131.         x! = Timer
  132.         a = InternetReadFile(httpRequest, _Offset(szBuffer), Len(szBuffer) - 1, _Offset(dwRead))
  133.         errr = GetLastError
  134.         If dwRead > 0 Then
  135.             filedownload = Mid$(szBuffer, 1, dwRead)
  136.             Put #1, , filedownload
  137.             bytesRead = bytesRead + dwRead
  138.             bytesForRate = bytesForRate + dwRead
  139.             ratetime = timeElapsedSince(x!)
  140.             If _Round(ratetime) >= 1 Then
  141.                 Rate! = (bytesForRate / ratetime) / 1024
  142.                 bytesForRate = 0
  143.             End If
  144.             Cls
  145.             Print "Downloading to " + File
  146.             If bytesToRead <> 0 Then
  147.                 Print bytesRead; "bytes downloaded of"; bytesToRead
  148.                 Print Using "###.##%"; bytesRead / bytesToRead * 100
  149.             Else
  150.                 Select Case bytesRead
  151.                     Case Is < 1024
  152.                         Print Using "   ####  B downloaded"; bytesRead
  153.                     Case Is < (1024 ^ 2) And bytesRead >= 1024
  154.                         Print Using "####.## KB downloaded"; (bytesRead / 1024)
  155.                     Case Is < (1024 ^ 3) And bytesRead >= (1024 ^ 2)
  156.                         Print Using "####.## MB downloaded"; (bytesRead / (1024 ^ 2))
  157.                     Case Is < (1024 ^ 4) And bytesRead >= (1024 ^ 3)
  158.                         Print Using "####.## GB downloaded"; (bytesRead / (1024 ^ 3))
  159.                 End Select
  160.             End If
  161.             Print "Rate="; _Round(Rate!); "KBps"
  162.             _Display
  163.         End If
  164.     Loop Until bytesRead = bytesToRead Or errr <> 0
  165.     If errr Then
  166.         Print "Error downloading file:"; errr
  167.         Close #1
  168.         InternetCloseHandle hsession
  169.         Kill File
  170.         Exit Sub
  171.     Else
  172.     End If
  173.     Close #1
  174.     InternetCloseHandle hsession
  175.     Cls
  176.     Print bytesRead; "bytes downloaded of"; bytesToRead
  177.     Print Using "###.##%"; bytesRead / bytesToRead * 100
  178.     Print "Downloaded to " + File
  179.  
  180. Function timeElapsedSince! (startTime!)
  181.     If startTime! > Timer Then startTime! = startTime! - 86400
  182.     timeElapsedSince! = Timer - startTime!
  183.  
  184. Function ErrorMessage$ (errCode As Long)
  185.     Const FORMAT_MESSAGE_ALLOCATE_BUFFER = &H00000100
  186.     Const FORMAT_MESSAGE_FROM_SYSTEM = &H00001000
  187.     Const FORMAT_MESSAGE_IGNORE_INSERTS = &H00000200
  188.  
  189.     Const LANG_NEUTRAL = &H00
  190.     Const SUBLANG_DEFAULT = &H01
  191.  
  192.     Dim As _Offset lpMsgBuf
  193.     Dim As Long msg
  194.  
  195. msg = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER Or _
  196.                     FORMAT_MESSAGE_FROM_SYSTEM Or _
  197.                     FORMAT_MESSAGE_IGNORE_INSERTS, _
  198.                    0, _
  199.                     errCode, _
  200.                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), _
  201.                     _Offset(lpMsgBuf), _
  202.                    0, 0)
  203.  
  204.  
  205.     ErrorMessage = offset_to_string(lpMsgBuf)

Code: C++: [Select]
  1.  //save as offsettostring.h
  2. void *offset_to_offset(void* offset){
  3.    return offset;
  4. }
« Last Edit: May 16, 2021, 03:44:30 pm by SpriggsySpriggs »
Shuwatch!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: reading remote text file
« Reply #12 on: May 16, 2021, 08:32:12 pm »
YOU KNOW you are giving a new meaning to "BASIC" LOL
Im starting to feel like I am programming in c++



thanks I'll tinker with that next week - stuck on call this week grrrrr
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: reading remote text file
« Reply #13 on: May 16, 2021, 08:49:08 pm »
@xra7en Hahaha yeah it's basic to me but not everyone :)

It is very similar to programming in C++ because all of those functions are from C DLLs and that header file is a C++ file.
Shuwatch!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: reading remote text file
« Reply #14 on: May 22, 2021, 04:15:43 pm »
ok. been playing around with this api, fun.

keep getting this error o.O
Code: QB64: [Select]
  1. Error: HTTPOpenRequest  The data area passed to a system  call is too small


Quote
filename: npp.7.9.5.Installer.x64.exe
link: https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v7.9.5/npp.7.9.5.Installer.x64.exe

Now this is all greek to me, however like the internal ability. so learning
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!