Page 1 of 1

Using the TMDB API and the Wikipedia API

Posted: Sat Apr 29, 2023 4:52 pm
by RamRat
Ok I have just spent 3 days with ChatGPT trying to learn
how write a set of simple procedures that would...

- create a database
- scan through directories adding filenames & file paths
to the database (filename is name of movie/tv series)
- using TMDB API to get all data related to each filename
and adding it to the database inc posters etc
- using WIKIPEDIA API to get info about each filename
(& would be Wikipedia webpage related to filename)
and adding to the database
- Show all contents in a nice simple GUI

What I got from ChatGPT was sorta usable looking code
that was actually written by some AI that's as dumb as me, It was causing me to tear my hair out and yelling at the screen.
So I tried to RTFM and got nowhere fast and had to get
some real help from a knowledgeable person on the forum :D

All I want is to write a PB version of Plex, don't tell me to use plex cos I tried and I hated it. :evil:

Anyone know how to write the API and SQL parts of the code, I have the rest figured out.

Or point me towards how to use various API's in purebssic?

If anyone is crazy enough to throw some code my way can you ; Comment it extensively for a slow retard like
me to learn what's going on :mrgreen:

If you got this far reading my ramblings... THANK YOU!

Re: Using the TMDB API and the Wikipedia API

Posted: Sat Apr 29, 2023 7:16 pm
by jassing
You can't use an AI to write code.
You can use an AI to get an idea of what to do; but it will almost always fail you in someway, beyond a "hello world" example.

I doubt you'll get anyone to write you a replacement for Plex.
You can play videos & music in PureBasic. The help file is pretty good (yes, I have had some hiccups in RTFM) but ...
I came from an OOP database (fox) and (real) C background, and found PB easy to pick up and now prefer it.
You can't learn coding by osmosis. You have to put the effort into it.
Start small. Don't try to re-write a mature application.

If you want help, ask for small bits not "write me a program" Many of the people here have years of experience & are willing to help, but I doubt many are willing to just "do my homework for me" sort of thing.

SQL is it's own language, so on top of learning PB, you'll have to learn SQL.
Results from https://api.themoviedb.org/3/movie/550?api_key=...
are in JSON format, so you'll have to become familiar with that as well.

You'll get better results if you show what you've tried or explain what isn't working the way you expect it.

The documentation at themoviedb.org is pretty darn good. This has sample queries

Code: Select all

#TMDBKey="YOUR-API-KEY"
Procedure RequestTMDB( queryString.s )
  Protected.s api
  If FindString(queryString,"?") : api = "&api_key="+#TMDBKey : Else : api = "?api_key="+#TMDBKey : EndIf 
  Protected HttpRequest = HTTPRequestMemory(#PB_HTTP_Get, "https://api.themoviedb.org/3/"+queryString+api)
  Protected httpResult.s, json
  If HttpRequest
    httpResult = HTTPInfo(HTTPRequest, #PB_HTTP_Response)
    json = ParseJSON(#PB_Any, httpResult)
    Debug ComposeJSON(json,#PB_JSON_PrettyPrint)
    FinishHTTP(HTTPRequest)
  Else
    Debug "Request creation failed"
  EndIf
  ProcedureReturn json 
EndProcedure

j = RequestTMDB( "search/movie?query=Jack+Reacher" )
; do stuff with your json data... 
FreeJSON(j)

j = RequestTMDB("movie/343611")                           : FreeJSON(j)
j = RequestTMDB("movie/343611?append_to_response=videos") : FreeJSON(j)

Re: Using the TMDB API and the Wikipedia API

Posted: Sun Apr 30, 2023 5:19 am
by RamRat
Hi thanks for the quick and informative response,

I have now consigned ChatGPT to the not there yet bin.

The TMDB Procedure you gave was an excellent first
step in learning how to send a query and get a response
and I have spent the last 4 hours playing around with query's and referencing the GET /configuration in the
TMDB docs.

My next step is learning how to use JSON and my next question is where are the best demonstrations in
purebasic for JSON? I have also started reading through
the forum for ideas and watching YouTube about JSON

Cheers :D

Re: Using the TMDB API and the Wikipedia API

Posted: Sun Apr 30, 2023 5:48 am
by jassing
Basic json handling is pretty simple, it's when the structure gets complicated (objects/arrays,etc vs just a simple list)

Here's some code I wrote when I started working with json; it just traverses a string displaying all elements.
I have a module that I'm working on that might be your speed...it allows grabbing json values more directly
ie: debug json::getString(j, "images/backdrops/filepath","")

Code: Select all

Declare TraverseJSON( jsonObjectValue, indent=0 )
j = RequestTMDB("movie/343611?append_to_response=videos,images") 
TraverseJSON( JSONValue(j) )
FreeJSON(j)

 Procedure TraverseJSON( jsonObjectValue, indent = 0 )
    If ExamineJSONMembers(jsonObjectValue)
      While NextJSONMember(jsonObjectValue)
        If JSONType(JSONMemberValue(jsonObjectValue)) = #PB_JSON_Object
          Debug Space(indent)+"-- "+JSONMemberKey(jsonObjectValue)
          indent + 4
        EndIf 
        Select JSONType(JSONMemberValue(jsonObjectValue)) 
          Case #PB_JSON_String
            Debug Space(indent) + JSONMemberKey(jsonObjectValue) + " = " + 
                  #DQUOTE$+ GetJSONString(JSONMemberValue(jsonObjectValue)) + #DQUOTE$
          Case #PB_JSON_Number
            Debug Space(indent) + JSONMemberKey(jsonObjectValue) + " = #" + 
                  GetJSONInteger(JSONMemberValue(jsonObjectValue))
          Case #PB_JSON_Boolean
            If GetJSONBoolean(JSONMemberValue(jsonObjectValue))
              Debug Space(indent) + JSONMemberKey(jsonObjectValue) + " = (true)"
            Else
              Debug Space(indent) + JSONMemberKey(jsonObjectValue) + " = (false)"
            EndIf 
            
          Case #PB_JSON_Array
            Protected i,jsonArrayElement,jArraySize = JSONArraySize(JSONMemberValue(jsonObjectValue))
            
            Debug Space(indent) +"-- "+ JSONMemberKey(jsonObjectValue) + 
                  ", array size " + Str(jArraySize)  
            
            jArraySize-1
            For i = 0 To jArraySize 
              ; extract the iterating element from the array
              jsonArrayElement = GetJSONElement(JSONMemberValue(jsonObjectValue), i)
              ; display only elements with values of string types
              Select JSONType(jsonArrayElement) 
                Case #PB_JSON_String
                  Debug Space(indent+4) + Str(i) + " = " + #DQUOTE$ + GetJSONString(jsonArrayElement) + #DQUOTE$
                Case #PB_JSON_Number
                  Debug Space(indent+4) + Str(i) + " = #" + GetJSONInteger(jsonArrayElement)
                Case #PB_JSON_Object
                  TraverseJSON(jsonArrayElement,indent+4)
              EndSelect
            Next i 
          Case #PB_JSON_Object
            TraverseJSON( GetJSONMember(jsonObjectValue,JSONMemberKey(jsonObjectValue)), indent+4)
        EndSelect
        If JSONType(JSONMemberValue(jsonObjectValue)) = #PB_JSON_Object
          indent-4
        EndIf 
      Wend
    EndIf  
  EndProcedure  
 

Re: Using the TMDB API and the Wikipedia API

Posted: Sun Apr 30, 2023 6:05 am
by RamRat
Thankyou for the TransverseJSON Procedure, I will
spend the rest of Sunday afternoon playing around with it
and attempt to get a better understanding of how JSON
works.

The module you are working on looks very appealing but
before I utilise someone's hard work I want to get more perspective on JSON by playing around with the example code you posted.

Also you call it a Module, is that similar to .pbi or library,
.dll? yes I am still a noob

Cheers

Re: Using the TMDB API and the Wikipedia API

Posted: Sun Apr 30, 2023 6:11 am
by jassing
A module is a purebasic construct. I use it to keep things "together" and keep variables protected.
See help...

Code: Select all

DeclareModule something
  Declare myAdd(a)
  global myValue.l 
EndDeclareModule
Module something
  Global somethingelse ; not available outside module
  Procedure myAdd(a)
    ProcedureReturn a+myValue
  EndProcedure
EndModule
something::myValue=3
Debug something::myAdd(2)

Re: Using the TMDB API and the Wikipedia API

Posted: Sun Apr 30, 2023 6:16 am
by RamRat
Aha, thanks for clearing that up for me, I will add it to my growing list of stuff to get to know :!:

Re: Using the TMDB API and the Wikipedia API

Posted: Sun Apr 30, 2023 9:42 am
by HeX0R
I know, I know, you didn't want to have some finished code, but I was in need of the tmdb api also a while ago, that here might come in handy:

Code: Select all

EnableExplicit

Structure _TMDB_RESULTS_
	vote_average.l
	overview.s
	release_date.s
	original_language.s
	original_title.s
	backdrop_path.s
	popularity.f
	poster_path.s
	title.s
	vote_count.l
	adult.s
	video.s
	id.q
	List genre_ids.l()
EndStructure

Structure _TMDB_
	total_results.l
	total_pages.l
	page.l
	List results._TMDB_RESULTS_()
EndStructure

Procedure GetTMDBData(Movie$, TMDB_APIKey$, Language$, *TMDB._TMDB_)
	Protected *Buffer, Year$, Movie2$, Result$
	Protected *C.CHARACTER, Pos, Picture$, JSON
	
	;remove year info, e.g. "Terminator (1984)"
	*C = @Movie$ + StringByteLength(Movie$) - SizeOf(character)
	Pos = Len(Movie$)
	While *C <> @Movie$
		Select *C\c
			Case ')'

			Case '0' To '9'
				Year$ = Chr(*C\c) + Year$
			Case '('
				If Len(Year$) = 4 And Str(Val(Year$)) = Year$
					;found!
					Break
				Else
					Year$ = ""
				EndIf
			Default
				If Len(Year$) = 4 And Str(Val(Year$)) = Year$
					;found!
					Break
				Else
					Year$ = ""
				EndIf
		EndSelect
		*C - SizeOf(CHARACTER)
		Pos - 1
	Wend
	
	If Pos < 1
		Year$   = ""
		Movie2$ = Movie$
	EndIf
	
	Movie2$ = Trim(Left(Movie$, Pos - 1))
	If Right(Movie2$, 1) = "-"
		Movie2$ = Trim(Left(Movie2$, Len(Movie2$) - 1))
	EndIf

	Movie2$ = URLEncoder(Movie2$)
	Movie2$ = ReplaceString(Movie2$, "#", "%23")
	Movie2$ = ReplaceString(Movie2$, " ", "+")
	
	*Buffer = ReceiveHTTPMemory("https://api.themoviedb.org/3/search/movie?api_key=" + TMDB_APIKey$ + "&query=" + Movie2$ + "&language=" + Language$)
	If *Buffer
		JSON = CatchJSON(#PB_Any, *Buffer, MemorySize(*Buffer))
		If JSON
			ExtractJSONStructure(JSONValue(JSON), *TMDB, _TMDB_)
			FreeJSON(JSON)
		EndIf
		FreeMemory(*Buffer)
	EndIf
EndProcedure

;----------------------
Global TMDB_APIKEY$ ; = "blablabla"





Procedure main()
	Protected MYRESULT._TMDB_, i
	
	If TMDB_APIKEY$ = ""
		TMDB_APIKEY$ = InputRequester("TMDB API Key", "please enter the tmdb API key", "")
	EndIf
	GetTMDBData("Ant-Man and the Wasp - 2018", TMDB_APIKEY$, "en", @MYRESULT)
	Debug "Movies Found: " + MYRESULT\total_results
	
	ForEach MYRESULT\results()
		Debug "Title: " + MYRESULT\results()\title
		Debug "Desc: " + MYRESULT\results()\overview
		Debug "----"
	Next
EndProcedure

main()

Re: Using the TMDB API and the Wikipedia API

Posted: Sun Apr 30, 2023 10:12 am
by RamRat
G'day and thanks for the code HeX0R,

I will have to spend the rest of next week every day after work going through all everyones code and figure
out how it works,so far I have jassing's code up and running which let me play around and spend most of today
wrapping my head around API and JSON it looks a bit slow and painful but I will get there lol

Also I have figured out how to get an Image and see it in a browser ->

https://image.tmdb.org/t/p/w500//7iptNJ ... sLmt1Z.jpg

but next I have to learn how purebasic gets it and saves to disk.

Im sure I will be asking more questions next week :!:

Cheers :D

Re: Using the TMDB API and the Wikipedia API

Posted: Sun Apr 30, 2023 1:23 pm
by jassing
RamRat wrote: Sun Apr 30, 2023 10:12 am but next I have to learn how purebasic gets it and saves to disk.
You can do one of two things:
One, use ReceiveHTTPMemory() along with CreateFile()/WriteData()
Or ReceiveHTTPFile()

Re: Using the TMDB API and the Wikipedia API

Posted: Mon May 01, 2023 11:22 am
by RamRat
Hi jassing,

So far I havn't done much, spend too much time reading how to to stuff, anyway - I am doing the following and it works, kinda, so far,
am having fun re-learning how this all works :D the little I have done Is all quite kludgy so far but that's ok _FOR NOW_ lol , Let me know where I'm
being a tad to retarded with any code I actually do write

Code: Select all

#TMDBKey="put the key here"

Declare TraverseJSON( jsonObjectValue, indent=0 )
Declare RequestTMDB( queryString.s )

Global image.i
Global temp1.i
Global temp2.i

Enumeration
	#Window
	#Image1
	#Image2
EndEnumeration

Procedure RequestTMDB( queryString.s )
  Protected.s api
  If FindString(queryString,"?") : api = "&api_key="+#TMDBKey : Else : api = "?api_key="+#TMDBKey : EndIf 
  Protected HttpRequest = HTTPRequestMemory(#PB_HTTP_Get, "https://api.themoviedb.org/3/"+queryString+api)
  Protected httpResult.s, json
  If HttpRequest
    httpResult = HTTPInfo(HTTPRequest, #PB_HTTP_Response)
    json = ParseJSON(#PB_Any, httpResult)
    ;Debug ComposeJSON(json,#PB_JSON_PrettyPrint)
    FinishHTTP(HTTPRequest)
  Else
    Debug "Request creation failed"
  EndIf
  ProcedureReturn json 
EndProcedure

Procedure TraverseJSON( jsonObjectValue, indent = 0 )
  If ExamineJSONMembers(jsonObjectValue)
    While NextJSONMember(jsonObjectValue)
      If JSONType(JSONMemberValue(jsonObjectValue)) = #PB_JSON_Object
        Debug Space(indent)+"-- "+JSONMemberKey(jsonObjectValue)
        indent + 4
      EndIf 
      Select JSONType(JSONMemberValue(jsonObjectValue)) 
        Case #PB_JSON_String
          
          search.s=JSONMemberKey(jsonObjectValue) + " = " + #DQUOTE$+ GetJSONString(JSONMemberValue(jsonObjectValue)) + #DQUOTE$
          
          If FindString(search,"file_path") 
            If image.i=1     
              CatchImage(#Image1, ReceiveHTTPMemory("https://image.tmdb.org/t/p/w200/"+GetJSONString(JSONMemberValue(jsonObjectValue))))    ; Load an Image
              ImageGadget(#PB_Any,temp1,temp1, 1920 , 1280, ImageID(#Image1))                                                                ; show image
              temp1+10
            EndIf
            If image.i=2
              CatchImage(#Image2, ReceiveHTTPMemory("https://image.tmdb.org/t/p/w200/"+GetJSONString(JSONMemberValue(jsonObjectValue))))    ; Load an Image
              ImageGadget(#PB_Any,temp1,temp1, 100 , 100, ImageID(#Image2))                                                                 ; show image
              temp2+10
            EndIf
          EndIf
          
          Debug Space(indent) + JSONMemberKey(jsonObjectValue) + " = " + #DQUOTE$+ GetJSONString(JSONMemberValue(jsonObjectValue)) + #DQUOTE$
        Case #PB_JSON_Number
          Debug Space(indent) + JSONMemberKey(jsonObjectValue) + " = #" + GetJSONInteger(JSONMemberValue(jsonObjectValue))
        Case #PB_JSON_Boolean
          If GetJSONBoolean(JSONMemberValue(jsonObjectValue))
            Debug Space(indent) + JSONMemberKey(jsonObjectValue) + " = (true)"
          Else
            Debug Space(indent) + JSONMemberKey(jsonObjectValue) + " = (false)"
          EndIf 
          
        Case #PB_JSON_Array
          Protected i,jsonArrayElement,jArraySize = JSONArraySize(JSONMemberValue(jsonObjectValue))
          search2.s="-- "+ JSONMemberKey(jsonObjectValue) + ", array size "
          If FindString(search2,"backdrops") : image.i=1 : EndIf
          If FindString(search2,"posters")   : image.i=2 : EndIf
          Debug Space(indent) +"-- "+ JSONMemberKey(jsonObjectValue) + ", array size " + Str(jArraySize)  
          
          jArraySize-1
          For i = 0 To jArraySize 
            ; extract the iterating element from the array
            jsonArrayElement = GetJSONElement(JSONMemberValue(jsonObjectValue), i)
            ; display only elements with values of string types
            Select JSONType(jsonArrayElement) 
              Case #PB_JSON_String
                Debug Space(indent+4) + Str(i) + " = " + #DQUOTE$ + GetJSONString(jsonArrayElement) + #DQUOTE$
              Case #PB_JSON_Number
                Debug Space(indent+4) + Str(i) + " = #" + GetJSONInteger(jsonArrayElement)
              Case #PB_JSON_Object
                TraverseJSON(jsonArrayElement,indent+4)
            EndSelect
          Next i 
        Case #PB_JSON_Object
          TraverseJSON( GetJSONMember(jsonObjectValue,JSONMemberKey(jsonObjectValue)), indent+4)
      EndSelect
      If JSONType(JSONMemberValue(jsonObjectValue)) = #PB_JSON_Object
        indent-4
      EndIf 
    Wend
  EndIf  
EndProcedure  

;j = RequestTMDB("search/movie?query=Die+Is+Hard?")             : TraverseJSON( JSONValue(j) ) : FreeJSON(j)
;j = RequestTMDB("movie/555235")                                : FreeJSON(j)
;j = RequestTMDB("movie/555235?append_to_response=videos")      : FreeJSON(j) 
;j = RequestTMDB("movie/555235") : TraverseJSON( JSONValue(j) ) : FreeJSON(j)
;j = RequestTMDB("movie/555235?append_to_response=videos")      : TraverseJSON( JSONValue(j) ) : FreeJSON(j)
;j = RequestTMDB("movie/555235?append_to_response=images")      : TraverseJSON( JSONValue(j) ) : FreeJSON(j)
;j = RequestTMDB("movie/555235?append_to_response=poster_path") : TraverseJSON( JSONValue(j) ) : FreeJSON(j)

UseJPEGImageDecoder()

ExamineDesktops()

If OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "Crash Test Dummy", #PB_Window_BorderLess | #PB_Window_Invisible)
  
  SetWindowColor(0,$000000)
  
  HideWindow(0, #False) 
  
  j = RequestTMDB("movie/343611?append_to_response=images")      : TraverseJSON( JSONValue(j) ) : FreeJSON(j)
  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_RightClick
      End  
    EndIf  
    
  Until Event = #PB_Event_RightClick 
  
EndIf


Ok, I have 2 Questions

1. What is the most straightforward way to handle data in PB just use the Purebasic Database?
2. I am looking at adding saving of images and text data soon and want to know what different options I have? Save the images seperatley to the
main file or in it?

Cheers

Re: Using the TMDB API and the Wikipedia API

Posted: Mon May 01, 2023 11:32 am
by Caronte3D
RamRat wrote: Mon May 01, 2023 11:22 am 1. What is the most straightford way to handle data in PB just use the Pirebasi Database?
2. I am looking at adding saving of images and text data soon and want to know what different options I have? Save the images seperatley to the
main file or in it?
1. I think the native PureBasic SQLite
2. Save the images on a folder and use the DataBase only to store the filename

Re: Using the TMDB API and the Wikipedia API

Posted: Mon May 01, 2023 12:40 pm
by RamRat
Caronte3D wrote: Mon May 01, 2023 11:32 am

1. I think the native PureBasic SQLite
2. Save the images on a folder and use the DataBase only to store the filename
Hi, So when using Purebasic SQLite is there a
recommended way to use it or things not to do that
might cause issues, program slowdown etc...

Is there a set limit of data I can load into it or is that just the pc's available memory that can cause issues?

Cheers :D

Re: Using the TMDB API and the Wikipedia API

Posted: Mon May 01, 2023 1:11 pm
by jassing
RamRat wrote: Mon May 01, 2023 12:40 pm Hi, So when using Purebasic SQLite is there a recommended way to use it or things not to do that might cause issues, program slowdown etc...
"recommended" way? the help file will be of use. This is where you'll also need to pick up the SQL language/syntax.
*ANYTHING* you do in a program, technically, will 'slow it down' - if it's doing something, that will take time, nothing is instant/free. SQLite is very fast.
RamRat wrote:
Is there a set limit of data I can load into it or is that just the pc's available memory that can cause issues?
Disk space & memory are always limiting factors. SQLite's limits are posted on their website. You most likely won't run into them.

Depending on how many images you plan to store, plan your directory structure out - most file system will slow down if you put too many files in one directory.

You'll want to think about what you want to store, how you want to look things up, etc. take the time to plan out your database's tables & indexes.
The sqlite website shows the syntax very nicely, but the explanations can be a bit curt.