How can I get the first image of a thread using nextcord api? - discord

I want to be able to get the first/last image of a thread in discord using nextcord.
I think I have to go through the channel/thread history but then how do I get the image out of the message? is an URL that I have to request.get?
if message.flags.has_thread:
async for m in message.thread.history(limit=100, oldest_first=True):

You can do like this as per your code:
if message.flags.has_thread:
async for m in message.thread.history(limit=100, oldest_first=True):
if m.attachments:
return m.attachments[0].url
first_image_url = await first_image_from_thread(channel_id, thread_id)
if first_image_url:
response = requests.get(first_image_url)
with open('first_image.jpg', 'wb') as f:
f.write(response.content)
print("Downloaded first image from thread...")
else:
print("No image found in thread...")
In this, first_image_from_thread will be your function where you will pass parameter of channel_id & thread_id.
You can also iterate through the attachments and check if it's image with it's file type like attachment.file_type.endswith(".jpeg"). If it's image you seeing then use "url" property to get image url and use "requests" module to download the image.

Related

Avoiding using save() function twice

I want to use external API for my django application, which sends image to the server and receives back some LaTeX.
My model looks like this:
class Snip(models.Model):
snip = models.FileField(upload_to="snips/") #stored image
latex = models.TextField(default = '') #received text from API
The image has to be stored/saved so URL might be included in JSON sent to the API. But that implies newly uploaded image has to be saved in newly created Snip object and after receiving the requested text back saved again.
My view looks like this:
if file:
temp_snip = Snip() #creating newe object
temp_snip.snip = file
temp_snip.save() #saving image to the database (required for getting image URL)
temp_snip.setLatex() #some magic :)
temp_snip.save() #saving the magic (second field in the model).
My question is:
Is there any simple solution to avoid using save() function twice?

Is it possible to directly upload images captured by camera to Firebase Storage?

I'm using React.js to create an application that would take a photo and upload it to Firebase Storage. I am using the react-webcam library, which uses this command to take a photo:
const ImageSrc = webcamRef.current.getScreenshot();
This is how I tried uploading the photo to Storage:
storage.ref(`/images`).put(imageSrc)
.on("state_changed" , alert("success") , alert)
However, the file that is uploaded is undefined (no photo).
I tried to construct an URL of the photo using blob:
const imageUrl = window.URL.createObjectURL(new Blob(webcamRef.current.getScreenshot()))
But I get this error: >Failed to construct 'Blob': The provided value cannot be converted to a sequence.
In the library it is stated that getScreenshot - Returns a base64 encoded string of the current webcam image. So, I tried to use the atob command, but I get the error: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
Does anyone know how I could upload the image to Firebase Storage? Any help would be appreciated!
Instead of blob, try using putString() command like this:
const task = firebase.storage().ref(`/images`).putString(imageSrc, 'data_url')
As explained in the doc, if you want to upload from a Base64url formatted string, you need to call the putString() method as follows (example from the doc):
var message = '5b6p5Y-344GX44G-44GX44Gf77yB44GK44KB44Gn44Go44GG77yB';
ref.putString(message, 'base64url').then((snapshot) => {
console.log('Uploaded a base64url string!');
});
In your case, since getScreenshot() returns a base64 encoded string, it would be something like:
const imageSrc = webcamRef.current.getScreenshot();
storage.ref(`/images`).putString(imageSrc, 'imgBase64')
.on("state_changed" , alert("success") , alert)

Converting the response of Python get request(jpg content) in Numpy Array

The workflow of my function is the following:
retrieve a jpg through python get request
save image as png (even though is downloaded as jpg) on disk
use imageio to read from disk image and transform it into numpy array
work with the array
This is what I do to save:
response = requests.get(urlstring, params=params)
if response.status_code == 200:
with open('PATH%d.png' % imagenumber, 'wb') as output:
output.write(response.content)
This is what I do to load and transform png into np.array
imagearray = im.imread('PATH%d.png' % imagenumber)
Since I don't need to store permanently what I download I tried to modify my function in order to transform the response.content in a Numpy array directly. Unfortunately every imageio like library works in the same way reading a uri from the disk and converting it to a np.array.
I tried this but obviously it didn't work since it need a uri in input
response = requests.get(urlstring, params=params)
imagearray = im.imread(response.content))
Is there any way to overcome this issue? How can I transform my response.content in a np.array?
imageio.imread is able to read from urls:
import imageio
url = "https://example_url.com/image.jpg"
# image is going to be type <class 'imageio.core.util.Image'>
# that's just an extension of np.ndarray with a meta attribute
image = imageio.imread(url)
You can look for more information in the documentation, they also have examples: https://imageio.readthedocs.io/en/stable/examples.html
You can use BytesIO as file to skip writing to an actual file.
bites = BytesIO(base64.b64decode(response.content))
Now you have it as BytesIO, so you can use it just like a file:
img = Image.open(bites)
img_np = np.array(im)

React / Rails API Image Uploading

I've built a React frontend along with a Rails API only backend. I want to allow the user to create a task and enter a title, description and upload an image.
So I've attempted to use DropZone to get access to the image and then send the image info along with the title and description to my Rails API via a post request using Axios.
I set up Carrierwave on my Rails API in hopes of uploading to an AWS S3 bucket once my Task has been added to the database per the post request.
None of this is working so my question is, should I take care of the image uploading to AWS on the react side and if so, how do I associate that image with the additional information I'm saving to my Rails database (title and description).
Thanks!
First, on React side, there should be no proble with title and description, but for image, you need to encode the image to Base64 string. It is something like this.
getBase64 = (callback) => {
const fileReader = new FileReader();
fileReader.onload = () => {
console.log(fileReader.result);
};
fileReader.readAsDataURL(fileToLoad);
fileReader.onerror = (error) => {
console.log('Error :', error);
};
}
Then, on Axios, send those 3 parameters alltogether with one POST request.
For Rails, you need to set up code that can read the Base64 string. Usually, you can use Paperclip or CarrierWavegem to add image attachment. It will look like this.
property_image = listing.property_images.new(param_image)
if param_image[:file_data]
image_file = Paperclip.io_adapters.for(param_image[:file_data])
image_file.original_filename = param_image[:image_file_name]
image_file.content_type = "image/png"
property_image.image = image_file
end
private
def param_image
params.permit(:image, :image_file_name, :file_data)
end

ReactJS image/pdf file download not working

I want to download file that can be in any format viz. pdf, jpeg, png, xlsx, csv etc. The download API on backend using pyramid framework is sending FileResponse as below:
def delivery_item_download_view(request, *args, **kw):
context = request.context
item_row = context.item_row
if item_row and item_row["deleted_at"] is None:
print(request.upload_dir+'/'+item_row["file_name"]+'.'+item_row["file_extension"])
response = FileResponse(
request.upload_dir+'/'+item_row["file_name"]+'.'+item_row["file_extension"],
request=request,
)
response.headers["attachment"] = item_row["name"];
return response
This, when executed using POSTMAN works as expected giving file as output. However,when tried implementing same using ReactJS, it's not working as expected. My client-code is as below:
onDownloadItem= (item) => {
console.log("item id is:", item.item_id)
var apiBaseUrl = "https://dev.incodax.com/api/deliveries_items/"+ item.item_id+ "/download";
fetch(apiBaseUrl, {
method: "GET",
}).then((res) => {
fileDownload(res,item.file_name)
console.log(res)
})
}
This fileDownload function simply downloading file but with no content inside. In downloaded file I could see something like:
[object Response]
I am getting 200 response from server. So I dont't think there is any issue with server side code. How can I handle it on client?
Thanks in advance
Will it suit you if you just redirected user to link to file? Browser will automatically handle it and download it.
The issue is in your fileDownload function which you do not post here. It's not clear what the first parameter is supposed to be but likely it is not the response object. Likely you at least need to pull the body out of the response and save that! The response body can be converted to a buffer object which could work (again it depends on what fileDownload is expecting):
res.arrayBuffer().then(buffer => {
fileDownload(buffer, item.file_name);
});

Resources