Fullmental
Active member
Trying to figure out how to very quickly build a script via REST API or something similar that can generate a batch of XFMG albums and media items, and it looks like all that documentation is empty in the API endpoints guide. I don't see much on XFMG in general in the developer docs either.
If I had a list of locally hosted images, post IDs they belong to, and a replacement string for me to run against the post in the db after the fact, how do I structure the API call to populate a media album for that post, and insert each locally hosted image into that album? My assumption is I start by having an album category (either create or use existing), create an album for that post ID, attempt to upload the new media item to the album, get the view URL of the album, and use that in my string replacement query to place the album URL where I want it. But I can't even seem to get a media item to post via the API so far. I can get an album created, but I can't populate said album without a working media POST function.
Using a GET request for the media item by ID I see the following structure, but obviously that's a lot of info and I don't know what might be auto generated, what's optional, what's required, etc., when making a corresponding POST request.
My assumption is the following items are required to make a new media item:
EDIT 2: OK, I'm dumb. I wasn't returning the JSON data to the print statement I made for debugging. Of course.
I'm seeing the following response now:
I updated my code as follows to see if adding a file would help:
However, when updating the code to use a "file" element, the message stays the same, required input missing: embed_url, file.
Tried an "embed_URL" to a random image URL and it does work, so that's progress!
But why doesn't it recognize the file? I added a statement to confirm the test file can be opened from the same script, and attributes such as dimensions and image type can be read using PIL, so I know the file definition is valid. It just doesn't seem to like receiving the "file" element.[/img][/spoiler]
If I had a list of locally hosted images, post IDs they belong to, and a replacement string for me to run against the post in the db after the fact, how do I structure the API call to populate a media album for that post, and insert each locally hosted image into that album? My assumption is I start by having an album category (either create or use existing), create an album for that post ID, attempt to upload the new media item to the album, get the view URL of the album, and use that in my string replacement query to place the album URL where I want it. But I can't even seem to get a media item to post via the API so far. I can get an album created, but I can't populate said album without a working media POST function.
Using a GET request for the media item by ID I see the following structure, but obviously that's a lot of info and I don't know what might be auto generated, what's optional, what's required, etc., when making a corresponding POST request.
Media
-Album
--User
--add_privacy
--album_id
--album_state
--can_add
--can_edit
--can_hard_delete
--can_react
--can_soft_delete
--category_id
--comment_count
--create_date
--description
--is_reacted_to
--is_watching
--last_comment_date
--last_comment_id
--last_comment_user_id
--last_comment_username
--last_update_date
--media_count
--rating_avg
--rating_count
--rating_weighted
--reaction_score
--thumbnail_url
--title
--user_id
--username
--view_count
--view_privacy
--view_url
--warning_message
-User
-album_id
-can_edit
-can_edit_tags
-can_hard_delete
-can_react
-can_soft_delete
-category_id
-comment_count
-custom_fields
-description
-file_size
-height
-is_reacted_to
-is_watching
-last_comment_date
-last_comment_id
-last_comment_user_id
-last_comment_username
-last_edit_date
-media_date
-media_id
-media_state
-media_type
-media_url
-rating_avg
-rating_count
-rating_weighted
-reaction_score
-tags
-thumbnail_url
-title
-user_id
-username
-view_count
-view_url
-warning_message
-width
My assumption is the following items are required to make a new media item:
Code:
title
description
album_id
However, I have no idea what to assign the actual local file to. When I make a POST request with just this info I think I need and a generic "file" definition pointing to the local server path of a test image, all I get is a null response. No information on why it was null, no direction, nothing, so it won't even tell me if there's a missing required element. I even tried using the view_url field to point to a local file, even though I'm pretty sure that's not what it's meant for, and still nothing.
Here's an example of the python code I'm testing with to make the post request. API info such as the key and base URL are referenced in a private class elsewhere, but those are confirmed working as I can take the same structure and make the GET request by media ID. The album ID already exists and the user ID (as well as the API key account) has required permissions to manage the XF media gallery. Additionally, the user the key is associated with owns the album specified in the code so they should have add permissions whichever way you slice it:
When I run a get on the album I'm trying to post to, I can confirm the user the API key is associated with can view, add, and edit:
EDIT: I found the mediaitem.php script in the XFMG API folder, trying to see what the construct is for the post parameter. It seems to only check permission, check for spam, and then send it along to a MediaItem entity. Followed that, found the setupApiResultData function which seems to be the only thing that looks remotely related to what I'm looking for. There's a switch statement inside that checks if the media type is an embed or not, and it uses a "media_url" string for the evaluation. Tried that on the API to point to the server file, still nothing. Kind of at a loss here? I would expect this bit of code would handle the attachment process based on the media_url, yes?
Here's an example of the python code I'm testing with to make the post request. API info such as the key and base URL are referenced in a private class elsewhere, but those are confirmed working as I can take the same structure and make the GET request by media ID. The album ID already exists and the user ID (as well as the API key account) has required permissions to manage the XF media gallery. Additionally, the user the key is associated with owns the album specified in the code so they should have add permissions whichever way you slice it:
Code:
def post_media_item(apiKey, baseURL, contentURL):
headers = {"XF-Api-Key": apiKey}
# construct dummy media item
media_item_data = {
"title": "APITEST",
"description": "Attempted API call to POST a new media item to an album.",
"view_url": contentURL,
"album_id": "339",
"user_id": "1"
}
reponse = r = requests.post(url = URL+"media", headers = HEADER, data=media_item_data)
When I run a get on the album I'm trying to post to, I can confirm the user the API key is associated with can view, add, and edit:
"album_state": "visible",
"can_add": true,
"can_edit": true,
EDIT: I found the mediaitem.php script in the XFMG API folder, trying to see what the construct is for the post parameter. It seems to only check permission, check for spam, and then send it along to a MediaItem entity. Followed that, found the setupApiResultData function which seems to be the only thing that looks remotely related to what I'm looking for. There's a switch statement inside that checks if the media type is an embed or not, and it uses a "media_url" string for the evaluation. Tried that on the API to point to the server file, still nothing. Kind of at a loss here? I would expect this bit of code would handle the attachment process based on the media_url, yes?
if ($this->media_type == 'embed')
{
$result->media_embed_url = $this->media_embed_url;
}
else
{
switch ($this->media_type)
{
case 'audio':
$result->media_url = $this->getAudioUrl(true);
break;
case 'video':
$result->media_url = $this->getVideoUrl(true);
break;
default:
$result->media_url = $this->app()->router('api')->buildLink('canonical:media/data', $this);
}
$attachment = $this->Attachment;
$result->file_size = $attachment->file_size;
$result->height = $attachment->Data->height;
$result->width = $attachment->Data->width;
}
EDIT 2: OK, I'm dumb. I wasn't returning the JSON data to the print statement I made for debugging. Of course.
I'm seeing the following response now:
Code:
{
"errors": [
{
"code": "required_input_missing",
"message": "Required input missing: embed_url, file",
"params": {
"missing": [
"embed_url",
"file"
]
}
}
]
}
I updated my code as follows to see if adding a file would help:
Code:
def post_media_item(apiKey, baseURL, contentURL):
# construct dummy media item
media_item_data = {
"title": "APITEST",
"description": "Attempted API call to POST a new media item to an album.",
"file": contentURL,
"album_id": "339",
"user_id": "1"
}
reponse = r = requests.post(url = URL+"media", headers = HEADER, data=media_item_data)
However, when updating the code to use a "file" element, the message stays the same, required input missing: embed_url, file.
Tried an "embed_URL" to a random image URL and it does work, so that's progress!
But why doesn't it recognize the file? I added a statement to confirm the test file can be opened from the same script, and attributes such as dimensions and image type can be read using PIL, so I know the file definition is valid. It just doesn't seem to like receiving the "file" element.[/img][/spoiler]
Last edited: