duck7000 / imdbGraphQLPHP

5 stars 0 forks source link

Getting series imdbid by episode id #37

Closed paxter closed 5 months ago

paxter commented 5 months ago

Is there an elegant way to get the imdbid by only knowing the id of a specific episode? In the old project I used the get_episode_details() method but this method is broken for a while and doesn't rely on graphQL queries.

For example I only have tt28289436 (episode) and wants tt0436992 (series).

I searched in this project but couldn't find a fitting graphQL query so far.

duck7000 commented 5 months ago

Mm i don't think that is possible, the GraphQL API query only is possible on Title and Name not on Episode

In other words a query on episode is not possible AFAIK

What might be possible is to use the search on the series name (if you know that) to get the series id

GraphQL API also has a advanced search maybe you can use that? I didn't include this in this version as nobody uses this here https://developer.imdb.com/documentation/api-documentation/sample-queries/search/?ref_=side_nav

paxter commented 5 months ago

Got it. Following works fine if the queried content is TV Episode.

series {
  episodeNumber {
    episodeNumber
    seasonNumber
  }
  series {
    id
  }
}
paxter commented 5 months ago

Full PHP code (may be not fitting 100% into this project but for documentation purposes may be helpful). Still work in progress.

public function getBaseData() {
        $query = "query TitleYear(\$id: ID!)
            {
              title(id: \$id) {
                countriesOfOrigin {
                  countries {
                    id
                    text
                  }
                }
                ratingsSummary {
                  aggregateRating
                  voteCount
                }
                titleGenres {
                  genres {
                    genre {
                      text
                    }
                  }
                }
                plot {
                  plotText {
                    plainText
                  }
                }
                titleText {
                  text
                }
                originalTitleText {
                  text
                }
                titleType {
                  text
                }
                releaseYear {
                  year
                  endYear
                }
                series {
                  episodeNumber {
                    episodeNumber
                    seasonNumber
                  }
                  series {
                    id
                  }
                }
              }
            }";

        $data = $this->sendRequest($query, "TitleYear", ["id" => $this->imdbId]);
[...]
duck7000 commented 5 months ago

Mm you query this all with a imdbid, so yes that works. $this->imdbid is used in this case But you asked to get the series id with only a episode id, that can't be queried directly?

Or did you use that epidsode id to query above function? As a matter of fact such episode is also an title id of course so yes that might be working. Never thought of it this way before

I don't see any language or country related in your code?

paxter commented 5 months ago

Or did you use that epidsode id to query above function? As a matter of fact such episode is also an title id of course so yes that might be working. Never thought of it this way before

Exactly. I used the episode id for that query and it works fine.

Reply is (used tt28289436 as episode id):

{
  "data": {
    "title": {
      "countriesOfOrigin": null,
      "ratingsSummary": {
        "aggregateRating": null,
        "voteCount": 0
      },
      "titleGenres": {
        "genres": [
          {
            "genre": {
              "text": "Adventure"
            }
          },
          {
            "genre": {
              "text": "Drama"
            }
          },
          {
            "genre": {
              "text": "Sci-Fi"
            }
          }
        ]
      },
      "plot": {
        "plotText": {
          "plainText": "The 2005 series of Doctor Who ended in 2021 series 13. The new Doctor Who is Doctor Who 2023 - Series 1, with the first 4 episodes in 2023 and returning in May 2024"
        }
      },
      "titleText": {
        "text": "Folge #14.1"
      },
      "originalTitleText": {
        "text": "Episode #14.1"
      },
      "titleType": {
        "text": "TV Episode",
        "id": "tvEpisode"
      },
      "releaseYear": {
        "year": 2024,
        "endYear": null
      },
      "series": {
        "episodeNumber": {
          "episodeNumber": 1,
          "seasonNumber": 14
        },
        "series": {
          "id": "tt0436992"
        }
      }
    }
  },
  "extensions": {
    "disclaimer": "Public, commercial, and/or non-private use of the IMDb data provided by this API is not allowed. For limited non-commercial use of IMDb data and the associated requirements see https://help.imdb.com/article/imdb/general-information/can-i-use-imdb-data-in-my-software/G5JTRESSHJBBHTGX#",
    "experimentalFields": {
      "janet": [],
      "markdown": [],
      "ratings": []
    }
  }
}

I don't see any language or country related in your code?

I'm handling the http request curl stuff upstream in another function. As I said, I started to writting my own lib so everything fits best. Furthermore I'm trying to simplify some things.

Curl is initialized like that (with the language headers).

private function initCurl() {
    $this->ch = curl_init();
    curl_setopt($this->ch, CURLOPT_URL, $this->baseurl);
    curl_setopt($this->ch, CURLOPT_POST, true);
    curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($this->ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0");

    $headers = [
        "Content-Type: application/json",
        "X-Imdb-User-Language: de-DE",
        "X-Imdb-User-Country: DE"
    ];

    curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers);
}
duck7000 commented 5 months ago

oh i see, you add the language and country to the headers array of course.. Do you have an array with country codes by any chance? or did you use a config option to set the language and country?

Did you check which fields are affected by those headers? Like i said before some fields are affected some are not so it is unclear when it does or not. Sometimes imdb states that it is affected but the results are the same.

I can implant those headers in my version but i doubt that anyone is going to use it (at least not the current users that i know of)

paxter commented 5 months ago

Supported languages can be extracted by language picker on the website easily.

Full supported

<ul class="ipc-list nav-fully-supported-languages ipc-list--baseAlt" role="menu" aria-orientation="vertical">
    <li role="menuitem" class="ipc-list__item sc-kLokBR bFfgZc disabled" tabindex="0" aria-disabled="false"><span class="ipc-list-item__text" role="presentation">Vollständig unterstützt</span></li>
    <li role="separator" class="ipc-list-divider"></li>
    <li role="menuitem" class="ipc-list__item sc-cxNGUP foSxdq language-option" id="language-option-en-US" aria-label="English (United States)" tabindex="0" aria-disabled="false">
        <span role="presentation" class="language-menu-item-span ipc-list-item__icon ipc-list-item__icon--pre">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="ipc-icon ipc-icon--radio-button-unchecked language-menu-item-icon" viewBox="0 0 24 24" fill="currentColor" role="presentation">
                <path fill="none" d="M0 0h24v24H0V0z"></path>
                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path>
            </svg>
        </span>
        <span class="ipc-list-item__text" role="presentation">English (United States)</span>
    </li>
    <li role="separator" class="ipc-list-divider"></li>
</ul>

Partial supported

<ul class="ipc-list nav-partially-supported-languages ipc-list--baseAlt" role="menu" aria-orientation="vertical">
    <a
        role="menuitem"
        class="ipc-list__item sc-kLokBR bFfgZc"
        href="https://help.imdb.com/article/issues/G65Q25A2AJ27GDTB?ref_=loc_nav_sel_hlp"
        target="_blank"
        aria-label="Weitere Informationen über teilweise unterstützte Sprachen."
        tabindex="0"
        aria-disabled="false"
    >
        <span class="ipc-list-item__text" role="presentation">Teilweise unterstützt</span>
        <span class="ipc-list-item__icon ipc-list-item__icon--post" role="presentation">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="ipc-icon ipc-icon--help-outline" viewBox="0 0 24 24" fill="currentColor" role="presentation">
                <path fill="none" d="M0 0h24v24H0V0z"></path>
                <path
                    d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-4h2v2h-2zm1.61-9.96c-2.06-.3-3.88.97-4.43 2.79-.18.58.26 1.17.87 1.17h.2c.41 0 .74-.29.88-.67.32-.89 1.27-1.5 2.3-1.28.95.2 1.65 1.13 1.57 2.1-.1 1.34-1.62 1.63-2.45 2.88 0 .01-.01.01-.01.02-.01.02-.02.03-.03.05-.09.15-.18.32-.25.5-.01.03-.03.05-.04.08-.01.02-.01.04-.02.07-.12.34-.2.75-.2 1.25h2c0-.42.11-.77.28-1.07.02-.03.03-.06.05-.09.08-.14.18-.27.28-.39.01-.01.02-.03.03-.04.1-.12.21-.23.33-.34.96-.91 2.26-1.65 1.99-3.56-.24-1.74-1.61-3.21-3.35-3.47z"
                ></path>
            </svg>
        </span>
    </a>
    <li role="separator" class="ipc-list-divider"></li>
    <li role="menuitem" class="ipc-list__item sc-cxNGUP foSxdq language-option" id="language-option-fr-CA" aria-label="Français (Canada)" tabindex="0" aria-disabled="false">
        <span role="presentation" class="language-menu-item-span ipc-list-item__icon ipc-list-item__icon--pre">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="ipc-icon ipc-icon--radio-button-unchecked language-menu-item-icon" viewBox="0 0 24 24" fill="currentColor" role="presentation">
                <path fill="none" d="M0 0h24v24H0V0z"></path>
                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path>
            </svg>
        </span>
        <span class="ipc-list-item__text" role="presentation">Français (Canada)</span>
    </li>
    <li role="menuitem" class="ipc-list__item sc-cxNGUP foSxdq language-option" id="language-option-fr-FR" aria-label="Français (France)" tabindex="0" aria-disabled="false">
        <span role="presentation" class="language-menu-item-span ipc-list-item__icon ipc-list-item__icon--pre">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="ipc-icon ipc-icon--radio-button-unchecked language-menu-item-icon" viewBox="0 0 24 24" fill="currentColor" role="presentation">
                <path fill="none" d="M0 0h24v24H0V0z"></path>
                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path>
            </svg>
        </span>
        <span class="ipc-list-item__text" role="presentation">Français (France)</span>
    </li>
    <li role="menuitem" class="ipc-list__item sc-cxNGUP foSxdq language-option selected" id="language-option-de-DE" aria-label="Deutsch (Deutschland)" tabindex="0" aria-disabled="false">
        <span role="presentation" class="language-menu-item-span ipc-list-item__icon ipc-list-item__icon--pre">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="ipc-icon ipc-icon--radio-button-checked language-menu-item-icon selected-language-icon" viewBox="0 0 24 24" fill="currentColor" role="presentation">
                <path fill="none" d="M0 0h24v24H0V0z"></path>
                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path>
                <circle cx="12" cy="12" r="5"></circle>
            </svg>
        </span>
        <span class="ipc-list-item__text" role="presentation">Deutsch (Deutschland)</span>
    </li>
    <li role="menuitem" class="ipc-list__item sc-cxNGUP foSxdq language-option" id="language-option-hi-IN" aria-label="हिंदी (भारत)" tabindex="0" aria-disabled="false">
        <span role="presentation" class="language-menu-item-span ipc-list-item__icon ipc-list-item__icon--pre">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="ipc-icon ipc-icon--radio-button-unchecked language-menu-item-icon" viewBox="0 0 24 24" fill="currentColor" role="presentation">
                <path fill="none" d="M0 0h24v24H0V0z"></path>
                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path>
            </svg>
        </span>
        <span class="ipc-list-item__text" role="presentation">हिंदी (भारत)</span>
    </li>
    <li role="menuitem" class="ipc-list__item sc-cxNGUP foSxdq language-option" id="language-option-it-IT" aria-label="Italiano (Italia)" tabindex="0" aria-disabled="false">
        <span role="presentation" class="language-menu-item-span ipc-list-item__icon ipc-list-item__icon--pre">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="ipc-icon ipc-icon--radio-button-unchecked language-menu-item-icon" viewBox="0 0 24 24" fill="currentColor" role="presentation">
                <path fill="none" d="M0 0h24v24H0V0z"></path>
                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path>
            </svg>
        </span>
        <span class="ipc-list-item__text" role="presentation">Italiano (Italia)</span>
    </li>
    <li role="menuitem" class="ipc-list__item sc-cxNGUP foSxdq language-option" id="language-option-pt-BR" aria-label="Português (Brasil)" tabindex="0" aria-disabled="false">
        <span role="presentation" class="language-menu-item-span ipc-list-item__icon ipc-list-item__icon--pre">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="ipc-icon ipc-icon--radio-button-unchecked language-menu-item-icon" viewBox="0 0 24 24" fill="currentColor" role="presentation">
                <path fill="none" d="M0 0h24v24H0V0z"></path>
                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path>
            </svg>
        </span>
        <span class="ipc-list-item__text" role="presentation">Português (Brasil)</span>
    </li>
    <li role="menuitem" class="ipc-list__item sc-cxNGUP foSxdq language-option" id="language-option-es-ES" aria-label="Español (España)" tabindex="0" aria-disabled="false">
        <span role="presentation" class="language-menu-item-span ipc-list-item__icon ipc-list-item__icon--pre">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="ipc-icon ipc-icon--radio-button-unchecked language-menu-item-icon" viewBox="0 0 24 24" fill="currentColor" role="presentation">
                <path fill="none" d="M0 0h24v24H0V0z"></path>
                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path>
            </svg>
        </span>
        <span class="ipc-list-item__text" role="presentation">Español (España)</span>
    </li>
    <li role="menuitem" class="ipc-list__item sc-cxNGUP foSxdq language-option" id="language-option-es-MX" aria-label="Español (México)" tabindex="0" aria-disabled="false">
        <span role="presentation" class="language-menu-item-span ipc-list-item__icon ipc-list-item__icon--pre">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="ipc-icon ipc-icon--radio-button-unchecked language-menu-item-icon" viewBox="0 0 24 24" fill="currentColor" role="presentation">
                <path fill="none" d="M0 0h24v24H0V0z"></path>
                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path>
            </svg>
        </span>
        <span class="ipc-list-item__text" role="presentation">Español (México)</span>
    </li>
</ul>

This gives us following valid language codes.

Did you check which fields are affected by those headers?

As far I've seen it affects only plots (plotText) and titles (titleText).

I'm a bit unsure about genres because the website translates them (I'm not interested into translated genres). But looks like they are still in original language and are not affected by the language headers.

For the following response the es-ES header was used.

{
  "data": {
    "title": {
      "countriesOfOrigin": {
        "countries": [
          {
            "id": "US",
            "text": "United States"
          }
        ]
      },
      "ratingsSummary": {
        "aggregateRating": 9,
        "voteCount": 852345
      },
      "titleGenres": {
        "genres": [
          {
            "genre": {
              "text": "Crime"
            }
          },
          {
            "genre": {
              "text": "Drama"
            }
          }
        ]
      },
      "plot": {
        "plotText": {
          "plainText": "Un miembro del jurado trata de evitar un error judicial obligando al resto del jurado a reconsiderar las pruebas."
        }
      },
      "titleText": {
        "text": "12 hombres sin piedad"
      },
      "originalTitleText": {
        "text": "12 Angry Men"
      },
      "titleType": {
        "text": "Movie",
        "id": "movie"
      },
      "releaseYear": {
        "year": 1957,
        "endYear": null
      },
      "series": null
    }
  },
  "extensions": {
    "disclaimer": "Public, commercial, and/or non-private use of the IMDb data provided by this API is not allowed. For limited non-commercial use of IMDb data and the associated requirements see https://help.imdb.com/article/imdb/general-information/can-i-use-imdb-data-in-my-software/G5JTRESSHJBBHTGX#",
    "experimentalFields": {
      "janet": [],
      "markdown": [],
      "ratings": []
    }
  }
}
paxter commented 5 months ago

I added language to some fields in the GraphQL query. It's easier to see which content is affected by the language headers.

Request with de-DE header sent.

{
   "data":{
      "title":{
         "countriesOfOrigin":{
            "countries":[
               {
                  "id":"US",
                  "text":"United States"
               },
               {
                  "id":"CN",
                  "text":"China"
               }
            ]
         },
         "ratingsSummary":{
            "aggregateRating":7.3,
            "voteCount":693894
         },
         "titleGenres":{
            "genres":[
               {
                  "genre":{
                     "text":"Action",
                     "language":{
                        "id":"en-US"
                     }
                  }
               },
               {
                  "genre":{
                     "text":"Adventure",
                     "language":{
                        "id":"en-US"
                     }
                  }
               },
               {
                  "genre":{
                     "text":"Fantasy",
                     "language":{
                        "id":"en-US"
                     }
                  }
               },
               {
                  "genre":{
                     "text":"Sci-Fi",
                     "language":{
                        "id":"en-US"
                     }
                  }
               },
               {
                  "genre":{
                     "text":"War",
                     "language":{
                        "id":"en-US"
                     }
                  }
               }
            ]
         },
         "plot":{
            "plotText":{
               "plainText":"Eine Amazonenprinzessin verlässt ihre Insel, um die Welt zu erkunden, und wird zur Superheldin."
            },
            "language":{
               "id":"de-DE"
            }
         },
         "titleText":{
            "text":"Wonder Woman"
         },
         "originalTitleText":{
            "text":"Wonder Woman"
         },
         "titleType":{
            "text":"Movie",
            "id":"movie"
         },
         "releaseYear":{
            "year":2017,
            "endYear":null
         },
         "series":null
      }
   },
   "extensions":{
      "disclaimer":"Public, commercial, and/or non-private use of the IMDb data provided by this API is not allowed. For limited non-commercial use of IMDb data and the associated requirements see https://help.imdb.com/article/imdb/general-information/can-i-use-imdb-data-in-my-software/G5JTRESSHJBBHTGX#",
      "experimentalFields":{
         "janet":[

         ],
         "ratings":[

         ],
         "markdown":[

         ]
      }
   }
}

As you can see genres are still in en-US but plotText is delivered as de-DE.

duck7000 commented 5 months ago

Ah i see, thanks!

I did get the impression that all languages are supported but as far as i can see now there are only a few languages, i didn't know that.

So even if you add a language that is supported there is still no guarantee that you will get it translated as it might not be available.

I'm already implanting this in my version (I'm not sure it ever will be used by a user, but just in case) so i will add the short list of languages and a warning about not being translated.

paxter commented 5 months ago

Checking the language id in response should help for reliable results. As far I remember fallback language is always en-US in case of missing content in the requested language.

duck7000 commented 5 months ago

Did you use both country and language in headers?

if both can i have the country codes you find as well?

paxter commented 5 months ago

Just to be sure I'm always use both language headers.

X-Imdb-User-Language: de-DE
X-Imdb-User-Country: DE

The value for the second header should be the second part of the language code always. For de-DE it's DE, for es-MX it's MX and so on.

I'm wondering GraphQL API will deliver translated genres in the future. If yes, it can be easily checked by genre's language id.

duck7000 commented 5 months ago

Ah i didn't think it would be that easy about the country codes though

I don't think genres will be translated as everybody knows them by their English name i guess

paxter commented 5 months ago

I don't think genres will be translated as everybody knows them by their English name i guess

Thought the same until IMDb website started to translate them as well which looks very akward...

duck7000 commented 5 months ago

I tested my language and country implantation and it only seems to work on title, plotoutline and more like this (only titles) All other fields are in English, so only useful if you use those 3 fields

You might be using this version now this hurtle is out of the way, but i aspect that you are rather using your own version

Well thanks again for your support! And don't hesitate to ask any further questions

paxter commented 5 months ago

I tested my language and country implantation and it only seems to work on title, plotoutline and more like this (only titles) All other fields are in English, so only useful if you use those 3 fields

Maybe more fields in the future. I think IMDb tries going more international and covering localized content (like TheTBDB). We will see.

You might be using this version now this hurtle is out of the way, but i aspect that you are rather using your own version

Yep, it's better for me to use my own code. I always try to use as less dependencies as possible.

Well thanks again for your support! And don't hesitate to ask any further questions

You're welcome.

Thank you too for the support and all the provided information. Your project is very helpful for my own stuff and saved me a lot of time.

Just ping me if I can help with something else here. :)

duck7000 commented 5 months ago

Sure will do