jjjake / internetarchive

A Python and Command-Line Interface to Archive.org
GNU Affero General Public License v3.0
1.63k stars 220 forks source link

modify_metadata Error 403 "Item not available" #666

Open PunchEnergyFTW opened 2 days ago

PunchEnergyFTW commented 2 days ago

Environment Details

Python

Python 3.10.12

Internetarchive package

internetarchive 5.0.4

OS

PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

Issue Description

Hi!

I was trying to bulk edit some metadata from archived YT Videos. However, i cannot get the part to work, where i modify the description (grabbed from youtube) of my item. Whenever i try to use the youtube video's description as metadata, i get an error 403 that the Item is not available.

Here's my code:

import internetarchive
from yt_dlp import YoutubeDL

LINK = "https://www.youtube.com/watch?v=dkkk-aqhcxo"
ARCHIVE_ID = "xxx"

with YoutubeDL() as ydl:
  info_dict = ydl.extract_info(f'{LINK}', download=False)
  video_desc = info_dict.get('description', None)
  print(video_desc)
  md = dict(description=video_desc)
  moditem = internetarchive.get_item(ARCHIVE_ID)
  rt = moditem.modify_metadata(md)
  print("RT: " + rt.text)

I've tried to modify the video_desc in many different ways and invested too much time into this than i would like to admit. Is this some kind of bug where the metadata is not being processed correctly?

When editing the description to a simple text like "test123" it works like a charm.

import internetarchive
from yt_dlp import YoutubeDL

LINK = "https://www.youtube.com/watch?v=dkkk-aqhcxo"
ARCHIVE_ID = "xxx"

with YoutubeDL() as ydl:
  info_dict = ydl.extract_info(f'{LINK}', download=False)
  video_desc = info_dict.get('description', None)
  print(video_desc)
  md = dict(description='test123')
  moditem = internetarchive.get_item(ARCHIVE_ID)
  rt = moditem.modify_metadata(md)
  print("RT: " + rt.text)
PunchEnergyFTW commented 1 day ago

I think i found the issue. It seems like the german umlauts are being encoded in https://github.com/jjjake/internetarchive/blob/master/internetarchive/iarequest.py#L294

I found out by enabling debug mode and printing the output. I then went through all functions that are being called when executing modify_metadata

import internetarchive
from yt_dlp import YoutubeDL

LINK = "https://www.youtube.com/watch?v=dkkk-aqhcxo"
ARCHIVE_ID = "xxx"

with YoutubeDL() as ydl:
    info_dict = ydl.extract_info(f'{LINK}', download=False)
    pure_video_desc = info_dict.get('description', None)
    md = dict(description=pure_video_desc)
    moditem = internetarchive.get_item(ARCHIVE_ID)
    rt = moditem.modify_metadata(md, debug=True)
    print(rt.data)

It then prints the german umlauts with their respective encodings:

$> python3 test.py
[youtube] Extracting URL: https://www.youtube.com/watch?v=dkkk-aqhcxo
[youtube] dkkk-aqhcxo: Downloading webpage
[youtube] dkkk-aqhcxo: Downloading ios player API JSON
[youtube] dkkk-aqhcxo: Downloading mweb player API JSON
[youtube] dkkk-aqhcxo: Downloading m3u8 information
{'-patch': '[{"op": "replace", "path": "/description", "value": "Staats- und Parteichef Xi Jinping\\u00a0verspricht seit einigen Jahren \\u201eWohlstand\\u00a0f\\u00fcr alle\\u201c\\u00a0und\\u00a0f\\u00fcr China die \\u201eglobale F\\u00fchrung\\u201c.\\u00a0Nun stagniert die Wirtschaft, die Immobilienpreise fallen ins Bodenlose und die\\u00a0Jugendarbeitslosigkeit\\u00a0lag zeitweise bei \\u00fcber 20 Prozent.\\r\\n\\r\\nXi Jinping aber l\\u00e4sst lieber die Statistiken zensieren und die Berichterstattung \\u00fcber die Krise unterdr\\u00fccken. Die Jugend solle jetzt eben lernen, Bitterkeit zu ertragen, so wie der Staatschef selbst, der w\\u00e4hrend der Kulturrevolution unter Mao gegen Ende der sechziger bis Anfang der siebziger Jahre auf dem Land schuften und hungern musste.\\u00a0\\nUnd was machen die jungen Leute, wenn sie nach einem teuren Studium an einer Eliteuni keinen Job finden? Manche praktizieren \\u201etang ping\\u201c (sich flach hinlegen) und \\u201ebai lan\\u201c (es einfach laufen lassen) als eine stille Form des Protests gegen den st\\u00e4ndigen Leistungsdruck und die Erwartungen der Gesellschaft. Viele junge Menschen ziehen sich aus der urbanen Leistungsgesellschaft zur\\u00fcck und suchen nach alternativen Lebenswegen auf dem Land oder als sogenannte \\u201ebezahlte Kinder\\u201c bei ihren Eltern.\\u00a0\\nUnser Reporter gewann das Vertrauen von drei jungen Leuten, dem 24-j\\u00e4hrigen Uni-Absolventen Tianqing, der 30-j\\u00e4hrigen Marketing-Managerin Qianqian und dem 28-j\\u00e4hrigen Lieferfahrer Erchui. Die ersten beiden suchen schon l\\u00e4nger verzweifelt nach einem neuen gut bezahlten Job und der dritte hofft auf bessere Zeiten, irgendwann\\u2026\\r\\n\\r\\n\\n#china #xijinping #wirtschaftskrise \\nVideo verf\\u00fcgbar bis zum 04/11/2027 \\n\\nLink zur Mediathek: https://www.arte.tv/de/videos/121076-000-A/china-jugend-unter-xi-jinping/\\n\\r\\nAbonniert den Youtube-Kanal von ARTE: \\u00a0http://www.youtube.com/user/ARTEde\\n\\nFolgt uns in den sozialen Netzwerken: \\nFacebook: http://www.facebook.com/ARTE.tv\\nTwitter: https://twitter.com/ARTEde\\nInstagram: https://www.instagram.com/arte.tv/"}]', '-target': 'metadata', 'priority': -5}

Workaround

By editing the json.dumps command as follows in iarequest.py :

...
            self.data = {
                '-patch': json.dumps(patch, ensure_ascii=False),
                '-target': target,
                'priority': priority,
            }
...

The same script as above will print the dictionary without encoding the german umlauts. The request against the IA API will then work properly. I believe the API does not know how to handle encoded german umlauts.

Tests with workaround

Debug Output

$> python3 test.py
[youtube] Extracting URL: https://www.youtube.com/watch?v=dkkk-aqhcxo
[youtube] dkkk-aqhcxo: Downloading webpage
[youtube] dkkk-aqhcxo: Downloading ios player API JSON
[youtube] dkkk-aqhcxo: Downloading mweb player API JSON
[youtube] dkkk-aqhcxo: Downloading m3u8 information
{'-patch': '[{"op": "replace", "path": "/description", "value": "Staats- und Parteichef Xi Jinping\xa0verspricht seit einigen Jahren „Wohlstand\xa0für alle“\xa0und\xa0für China die „globale Führung“.\xa0Nun stagniert die Wirtschaft, die Immobilienpreise fallen ins Bodenlose und die\xa0Jugendarbeitslosigkeit\xa0lag zeitweise bei über 20 Prozent.\\r\\n\\r\\nXi Jinping aber lässt lieber die Statistiken zensieren und die Berichterstattung über die Krise unterdrücken. Die Jugend solle jetzt eben lernen, Bitterkeit zu ertragen, so wie der Staatschef selbst, der während der Kulturrevolution unter Mao gegen Ende der sechziger bis Anfang der siebziger Jahre auf dem Land schuften und hungern musste.\xa0\\nUnd was machen die jungen Leute, wenn sie nach einem teuren Studium an einer Eliteuni keinen Job finden? Manche praktizieren „tang ping“ (sich flach hinlegen) und „bai lan“ (es einfach laufen lassen) als eine stille Form des Protests gegen den ständigen Leistungsdruck und die Erwartungen der Gesellschaft. Viele junge Menschen ziehen sich aus der urbanen Leistungsgesellschaft zurück und suchen nach alternativen Lebenswegen auf dem Land oder als sogenannte „bezahlte Kinder“ bei ihren Eltern.\xa0\\nUnser Reporter gewann das Vertrauen von drei jungen Leuten, dem 24-jährigen Uni-Absolventen Tianqing, der 30-jährigen Marketing-Managerin Qianqian und dem 28-jährigen Lieferfahrer Erchui. Die ersten beiden suchen schon länger verzweifelt nach einem neuen gut bezahlten Job und der dritte hofft auf bessere Zeiten, irgendwann…\\r\\n\\r\\n\\n#china #xijinping #wirtschaftskrise \\nVideo verfügbar bis zum 04/11/2027 \\n\\nLink zur Mediathek: https://www.arte.tv/de/videos/121076-000-A/china-jugend-unter-xi-jinping/\\n\\r\\nAbonniert den Youtube-Kanal von ARTE: \xa0http://www.youtube.com/user/ARTEde\\n\\nFolgt uns in den sozialen Netzwerken: \\nFacebook: http://www.facebook.com/ARTE.tv\\nTwitter: https://twitter.com/ARTEde\\nInstagram: https://www.instagram.com/arte.tv/"}]', '-target': 'metadata', 'priority': -5}

Actual API request working

$> python3 test.py
[youtube] Extracting URL: https://www.youtube.com/watch?v=dkkk-aqhcxo
[youtube] dkkk-aqhcxo: Downloading webpage
[youtube] dkkk-aqhcxo: Downloading ios player API JSON
[youtube] dkkk-aqhcxo: Downloading mweb player API JSON
[youtube] dkkk-aqhcxo: Downloading m3u8 information
{"success":true,"task_id":4603755105,"log":"https://catalogd.archive.org/log/[...]"}

And just for completeness, here the script to push the changes to the API.

import internetarchive
from yt_dlp import YoutubeDL

LINK = "https://www.youtube.com/watch?v=dkkk-aqhcxo"
ARCHIVE_ID = "xxx"

with YoutubeDL() as ydl:
    info_dict = ydl.extract_info(f'{LINK}', download=False)
    pure_video_desc = info_dict.get('description', None)
    md = dict(description=pure_video_desc)
    moditem = internetarchive.get_item(ARCHIVE_ID)
    rt = moditem.modify_metadata(md)
    print(rt.text)

I don't know if this change would break anything else though. Maybe somebody else with more experience can evaluate if this is a worthwhile change to make or not.