Python-pptx: issue with insert_picture() function - 'sha1' AttributeError - python

I am trying to write a basic script to update a PowerPoint (2016) presentation, template.pptx, which contains predefined place holders for images. I am running into issues with the insert_picture() function.
As an example, the 4th slide of template.pptx contains a Picture Placeholder:
from pptx import Presentation
prs = Presentation('template.pptx')
slide4 = prs.slides[3]
for shape in slide4.placeholders:
print('%d %s' % (shape.placeholder_format.idx, shape.name))
which gives the following output
>>>
0 Title 3
10 Picture Placeholder 7
I proceed with
placeholder = slide4.placeholders[10] # idx key, not position
picture = placeholder.insert_picture('test.jpg')
Which throws the following error(s):
File "C:\Python273\lib\site-packages\pptx\shapes\placeholder.py", line 323, in insert_picture
pic = self._new_placeholder_pic(image_file)
File "C:\Python273\lib\site-packages\pptx\shapes\placeholder.py", line 334, in _new_placeholder_pic
rId, desc, image_size = self._get_or_add_image(image_file)
File "C:\Python273\lib\site-packages\pptx\shapes\placeholder.py", line 345, in _get_or_add_image
image_part, rId = self.part.get_or_add_image_part(image_file)
File "C:\Python273\lib\site-packages\pptx\parts\slide.py", line 42, in get_or_add_image_part
image_part = self._package.get_or_add_image_part(image_file)
File "C:\Python273\lib\site-packages\pptx\package.py", line 50, in get_or_add_image_part
return self._image_parts.get_or_add_image_part(image_file)
File "C:\Python273\lib\site-packages\pptx\package.py", line 159, in get_or_add_image_part
image_part = self._find_by_sha1(image.sha1)
File "C:\Python273\lib\site-packages\pptx\package.py", line 171, in _find_by_sha1
if image_part.sha1 == sha1:
AttributeError: 'Part' object has no attribute 'sha1'
I have seen this 'sha1' error mentioned in these forums but don't fully understand it (I am a bit of a novice).
Interestingly (frustratingly), I don't run into this issue when creating a PowerPoint from scratch (as per the example in the python-pptx 0.6.7 docs):
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[8])
placeholder = slide.placeholders[1] # idx key, not position
picture = placeholder.insert_picture('test.jpg')
prs.save('new.pptx')
This runs fine, hence I am left very confused. Any help would be much appreciated. Thanks!
(Windows 7, Python 2.7.3)

I have found a possible cause for this problem! For me the problem was that the presentation contained images that were not in either jpg, png or gif. It was a tif file. For these files, theres is no sha1 and therefore the script throws an exception. Converting/deleting these files made the problem disappear!
Please tell me if that fixes it for you too.

Related

AttributeError when using googletrans module

I am writing code to make a translator using GUI. My program runs but when I try to translate text it throws the error AttributeError: 'NoneType' object has no attribute 'group'
My code
from tkinter import*
from tkinter import ttk
from googletrans import Translator,LANGUAGES
def change(text="type",src="English",dest="Hindi"):
text1=text
src1=src
dest1=dest
trans = Translator()
trans1 = trans.translate(text,src=src1,dest=dest1)
return trans1.text
def data():
s =comb_sor.get()
d =comb_dest.get()
msg = Sor_txt.get(1.0,END)
textget = change(text=msg,src=s,dest=d)
dest_txt.delete(1.0,END)
dest_txt.insert(END,textget)
root = Tk()
root.title("Translater")
root.geometry("500x800")
root.config(bg="#FFE1F3")
lab_txt=Label(root,text="Translator", font=("Time New Roman",40,"bold"),fg="#478C5C")
lab_txt.place(x=100,y=40,height=50,width=300)
frame=Frame(root).pack(side=BOTTOM)
lab_txt=Label(root,text="Source Text", font=("Time New Roman",20,"bold"),fg="#FFFF8A",bg="#FDA172")
lab_txt.place(x=100,y=100,height=20,width=300)
Sor_txt =Text(frame,font=("Time New Roman",20,"bold"),wrap=WORD)
Sor_txt.place(x=10,y=130,height=150,width=480)
list_text = list(LANGUAGES.values())
comb_sor = ttk.Combobox(frame,value=list_text)
comb_sor.place(x=10,y=300,height=20,width=100)
comb_sor.set("English")
button_change = Button(frame,text="Translate",relief=RAISED,command=data)
button_change.place(x=120,y=300,height=40,width=100)
comb_dest = ttk.Combobox(frame,value=list_text)
comb_dest.place(x=230,y=300,height=20,width=100)
comb_dest.set("English")
lab_txt=Label(root,text="Dest Text", font=("Time New Roman",20,"bold"),fg="#2E2EFF")
lab_txt.place(x=100,y=360,height=50,width=300)
dest_txt=Text(frame,font=("Time New Roman",20,"bold"),wrap=WORD)
dest_txt.place(x=10,y=400,height=150,width=480)
root.mainloop()
The error and stack trace
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\praful pawar\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\praful pawar\AppData\Local\Temp\ipykernel_9920\1422625581.py", line 19, in data
textget = change(text=msg,src=s,dest=d)
File "C:\Users\praful pawar\AppData\Local\Temp\ipykernel_9920\1422625581.py", line 10, in change
trans1 = trans.translate(text,src=src1,dest=dest1)
File "C:\Users\praful pawar\AppData\Local\Programs\Python\Python310\lib\site-packages\googletrans\client.py", line 182, in translate
data = self._translate(text, dest, src, kwargs)
File "C:\Users\praful pawar\AppData\Local\Programs\Python\Python310\lib\site-packages\googletrans\client.py", line 78, in _translate
token = self.token_acquirer.do(text)
File "C:\Users\praful pawar\AppData\Local\Programs\Python\Python310\lib\site-packages\googletrans\gtoken.py", line 194, in do
self._update()
File "C:\Users\praful pawar\AppData\Local\Programs\Python\Python310\lib\site-packages\googletrans\gtoken.py", line 62, in _update
code = self.RE_TKK.search(r.text).group(1).replace('var ', '')
AttributeError: 'NoneType' object has no attribute 'group'
What it looks like
This image shows that my application is running but something is wrong:
This library's own documentation says (bold added by me):
I eventually figure out a way to generate a ticket by reverse engineering on the obfuscated and minified code used by Google to generate such token, and implemented on the top of Python. However, this could be blocked at any time.
It is designed to work around limitations that Google deliberately installed in Google Translate to make sure you use their official API (and presumably pay) to connect to their service programmatically.
I believe that what you are seeing today is that, as the author warned could happen at any time, it got blocked. The last release was two years ago, so Google has had plenty of time to patch the hole this library exploited.
PS: there's a ticket about this...
Well, I still think this library could get blocked at any time, but it turns out the library is still actively maintained, and they have a ticket open about this issue: https://github.com/ssut/py-googletrans/issues/354 I suggest you watch that ticket, maybe they will fix it.
I just tested the release candidate one reply mentions in the ticket, and it fixed the problem for me:
pip install googletrans==4.0.0rc1
might make your code work.

Approach to get currently playing media's thumbnail on Windows only works once per Python instance

I'm trying to get the thumbnail of the currently playing media on windows, and thanks to this answer (https://stackoverflow.com/a/66037406/15491505) i got quite far, however I'm facing a strange issue where in get_thumbnail() the variable byte_buffer always ends up being 0 in length after the first run... as in the first time I call it I get back the thumbnail perfectly, but all further calls end up failing...
This is what I have so far:
from winrt.windows.media.control import GlobalSystemMediaTransportControlsSessionManager as MediaManager
from winrt.windows.storage.streams import DataReader, Buffer, InputStreamOptions
from io import BytesIO
from PIL import Image
import asyncio
async def get_thumbnail():
sessions = await MediaManager.request_async()
current_session = sessions.get_current_session()
if current_session:
properties = await current_session.try_get_media_properties_async()
media_info = {song_attr: properties.__getattribute__(song_attr) for song_attr in dir(properties) if song_attr[0] != '_'}
if media_info.get('thumbnail'):
thumb_stream_ref = media_info['thumbnail']
thumb_read_buffer = Buffer(5000000)
readable_stream = await thumb_stream_ref.open_read_async()
readable_stream.read_async(thumb_read_buffer, thumb_read_buffer.capacity, InputStreamOptions.READ_AHEAD)
buffer_reader = DataReader.from_buffer(thumb_read_buffer)
byte_buffer = buffer_reader.read_bytes(thumb_read_buffer.length)
binary = BytesIO()
binary.write(bytearray(byte_buffer))
binary.seek(0)
print(len(bytearray(byte_buffer)))
img = Image.open(binary)
return img
thumbnail = asyncio.run(get_thumbnail())
thumbnail.show()
# This will work
thumbnail2 = asyncio.run(get_thumbnail())
thumbnail2.show()
# This will not
Example output:
C:\Users\willy\Desktop>test.py
117672
0
Traceback (most recent call last):
File "C:\Users\willy\Desktop\test.py", line 39, in <module>
thumbnail2 = asyncio.run(get_thumbnail())
File "C:\Python38\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Python38\lib\asyncio\base_events.py", line 616, in run_until_complete
return future.result()
File "C:\Users\willy\Desktop\test.py", line 31, in get_thumbnail
img = Image.open(binary)
File "C:\Python38\lib\site-packages\PIL\Image.py", line 2930, in open
raise UnidentifiedImageError(
PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x00000278D2FB3B30>
Solution
Simply await the result of the readable_stream.read_async(...) call:
...
readable_stream = await thumb_stream_ref.open_read_async()
await readable_stream.read_async(thumb_read_buffer, thumb_read_buffer.capacity, InputStreamOptions.READ_AHEAD)
buffer_reader = DataReader.from_buffer(thumb_read_buffer)
...
The thumbnail should now be successfully displayed each time.
Debugging process
(for anyone interested and for similar bugs in the future)
After break-pointing your code, it appeared that, on the second call of get_thumbnail(), byte_buffer was left empty. This indicated that the thumb_read_buffer was not being populated correctly from the stream.
Interestingly, when single-stepping the code instead, the image displayed both times. This suggested to me that maybe an asynchronous function call wasn't being awaited.
Turns out .read_async() (as the function name suggests) is an asynchronous operation in winrt (see IInputStream.ReadAsync on learn.microsoft.com). Hence, awaiting its execution fixed the problem of the empty thumb_read_buffer.

Failed to display Chinese texts in manim animation even after trying to change the value of TEX_USE_CTEX

Basically it is the same issue as in https://github.com/3b1b/manim/issues/570, however it was not clear how the person solved the issue, for he stated that he didn't know how he managed to solve it. I am using Windows 10 and MiKTeX.
I tried to edit constants.py,TEX_USE_CTEX = False was changed to True and it returns the error:
File "D:\Programs\manim\manim\manimlib\extract_scene.py", line 153, in main
scene = SceneClass(**scene_kwargs)
File "D:\Programs\manim\manim\manimlib\scene\scene.py", line 54, in __init__
self.construct()
File "tutorial/1_text_format.py", line 5, in construct
text = TextMobject("你好")
File "D:\Programs\manim\manim\manimlib\mobject\svg\tex_mobject.py", line 144, in __init__
self, self.arg_separator.join(tex_strings), **kwargs
File "D:\Programs\manim\manim\manimlib\mobject\svg\tex_mobject.py", line 45, in __init__
self.template_tex_file_body
File "D:\Programs\manim\manim\manimlib\utils\tex_file_writing.py", line 19, in tex_to_svg_file
dvi_file = tex_to_dvi(tex_file)
File "D:\Programs\manim\manim\manimlib\utils\tex_file_writing.py", line 67, in tex_to_dvi
"See log output above or the log file: %s" % log_file)
Exception: Xelatex error converting to xdv. See log output above or the log file: D:\Programs\manim\manim\manimlib\files\Tex\6d518d13918960fc.log
And the command is extremely simple:
class WriteText(Scene):
def construct(self):
text = TextMobject("你好")
self.play(Write(text))
self.wait(3)
Any methods that were proven to work to solve the issue? For I am not the first one encountering this.
Edit:
It is what it says in D:\Programs\manim\manim\manimlib\files\Tex\6d518d13918960fc.log.
This is XeTeX, Version 3.14159265-2.6-0.999992 (MiKTeX 2.9.7400 64-bit) (preloaded format=xelatex 2020.5.4) 4 MAY 2020 05:14
entering extended mode
**D:/Programs/manim/manim/manimlib/files/Tex/6d518d13918960fc.tex
(D:/Programs/manim/manim/manimlib/files/Tex/6d518d13918960fc.tex
LaTeX2e <2020-02-02> patch level 5
L3 programming layer <2020-04-06>)
! Emergency stop.
<*> ...nim/manimlib/files/Tex/6d518d13918960fc.tex
Here is how much of TeX's memory you used:
18 strings out of 414218
562 string characters out of 2903153
244959 words of memory out of 3000000
17616 multiletter control sequences out of 15000+200000
532338 words of font info for 24 fonts, out of 3000000 for 9000
1348 hyphenation exceptions out of 8191
12i,0n,15p,95b,8s stack positions out of 5000i,500n,10000p,200000b,50000s
No pages of output.
Well, you can check if your MiKTeX is "Complete version" instead of "Basic version". You can delete it completely and then install it again, make sure to select "Complete version". If you still meet this bug, try using TeX Live. Just click this link https://matnoble.me/tech/ubuntu/install-texlive/ and find how to install it on Windows.

Python: Reading GuitarPro (.gp5) files

I'm new to writing questions here, so please feel free to point out how i can improve the quality of future questions!
Edit: More code included as was asked in the comments
I'm trying to read GuitarPro files into python. These files essentially contain the sheet music for songs, but contain more information than e.g. MIDI files.
I want to parse the notes and the duration of the notes into e.g. a list structure. Further, i hope other effects can be parsed from the GuitarPro files also, such as bends, slides, hammer-ons etc.
I have been trying to use the library PyGuitarPro, but get stuck:
import guitarpro
import os
# 'wet_sand.gp5' is the guitar pro file
parsed_song = guitarpro.parse('wet_sand.gp5')
song = guitarpro.gp5.GP5File(parsed_song,encoding='UTF-8')
song.readSong()
I get the following error from ReadSong() (documentation here):
Traceback (most recent call last):
File "<ipython-input-15-e1663229852d>", line 8, in <module>
song.readSong()
File "C:\Python27\lib\site-packages\guitarpro\gp5.py", line 62, in readSong
song.version = self.readVersion()
File "C:\Python27\lib\site-packages\guitarpro\iobase.py", line 114, in readVersion
self.version = self.readByteSizeString(30)
File "C:\Python27\lib\site-packages\guitarpro\iobase.py", line 97, in readByteSizeString
return self.readString(size, self.readByte())
File "C:\Python27\lib\site-packages\guitarpro\iobase.py", line 47, in readByte
return (self.read(*args, default=default) if count == 1 else
File "C:\Python27\lib\site-packages\guitarpro\iobase.py", line 35, in read
data = self.data.read(count)
AttributeError: 'Song' object has no attribute 'read'
Looking at the the examples provided, e.g. this one. I don't think you need this portion.
song = guitarpro.gp5.GP5File(parsed_song,encoding='UTF-8')
The following should be enough, as parse already calls readSong here.
song = guitarpro.parse('wet_sand.gp5')
Finally it looks like the file-format is automatically determined by parse here.
As an example you could do something like this.
import guitarpro
song = guitarpro.parse('test.gp5')
for track in song.tracks:
for measure in track.measures:
for voice in measure.voices:
for beat in voice.beats:
for note in beat.notes:
print(note.durationPercent)
print(note.effect)

PDAL: Couldn't create filter stage of type 'crop'

I'm trying to use pdal in python. I started with a super simple cropping:
json = """{
"pipeline":[
"ARRA-LFTNE_NewYork_2010_000636.las",
{
"type":"crop",
"bounds":"([616766.770,617765.46],[4510733.640,4511649.800])"
},
"output.laz"
]
}"""
pipeline = pdal.Pipeline(unicode(json,encoding="utf-8"))
pipeline.validate() # check if our JSON and options were good
pipeline.loglevel = 8 #really noisy
count = pipeline.execute()
arrays = pipeline.arrays
metadata = pipeline.metadata
log = pipeline.log
The json is from pdal's hp https://www.pdal.io/pipeline.html#pipeline, and should simply crop the image. However, at the validation it fails with the error:
Traceback (most recent call last):
File "/src/test.py", line 69, in <module>
pipeline.validate() # check if our JSON and options were good
File "/usr/local/lib/python2.7/dist-packages/pdal/pipeline.py", line 42, in validate
return self.p.validate()
File "pdal/libpdalpython.pyx", line 93, in pdal.libpdalpython.PyPipeline.validate (pdal/libpdalpython.cpp:2639)
RuntimeError: Couldn't create filter stage of type 'crop'.
I have tried running other small examples I found online, but I keep getting the "Couldn't create filter stage of type xx"-error!
I'm running it on a dockerfile from the image: pdal/pdal:1.5
Look again at the site you linked. The crop filter (docs here) uses the option bounds, not dimension to specify the bounding box. In PDAL, dimension means a dimension of the point data (X, Y, Z, Red, Green, Blue, etc).
Dimensions docs here
Your filter type should read filters.crop and not just crop.

Categories