Update Links of Powerpoint using win32com (Python) - python

I have a PowerPoint slide which has a linked image (table) and the data for that image is in excel.
I am trying to open the PowerPoint but even after PPTApp.DisplayAlerts = False my script gets stuck due to Security pop up which asks me to update the external links.
Here is my code:
import win32com.client
PPTApp = win32com.client.Dispatch("PowerPoint.Application")
if PPTApp.Visible == False:
PPTApp.Visible = True
PPTApp.DisplayAlerts = False
#PPTApp.AskToUpdateLinks = False (this does not work)
PPTPresentation = PPTApp.Presentations.Open(r"C:\Daily_Data_Slide.pptx")
PPTPresentation.UpdateLinks = True

Just call UpdateLinks() instead of setting the attribute UpdateLinks to True, and remove the line where you are invoking alerts PPTApp.DisplayAlerts = False :
import win32com.client
PPTApp = win32com.client.Dispatch("PowerPoint.Application")
if not PPTApp.Visible:
PPTApp.Visible = True
PPTPresentation = PPTApp.Presentations.Open(r"C:\Daily_Data_Slide.pptx")
PPTPresentation.UpdateLinks()

This is what I was able to work so far related to your question on my own projects.
I will first disable the Automatic Update for liks (File->Info->Edit Liks to file) to avoid getting stuck at the Security pop up which asks to update the external links. We will be update by looping through the slides and refreshing each shape if applicable.
Code:
import win32com.client as win32
from datetime import datetime
import time
path="\\\\Servername\\share$\\folder\\"
pptfile = "filename.pptx"
pptfilename=pptfile[:pptfile.find('.')] #filename without extension
date= datetime.now().strftime('%#d-%b-%Y')
pptApp = win32.Dispatch("PowerPoint.Application")
pptApp.DisplayAlerts = 0
Presentation = pptApp.Presentations.Open(path+pptfile,0,0,0) # This hide the power point
# Then Search in all slides and if it is a Linked object (Type 10) then Refresh
for slide in Presentation.Slides:
for shape in slide.Shapes:
if shape.Type == 10:
shape.LinkFormat.Update()
Presentation.SaveAs(FileName=path+pptfilename+"("+date+").pptx") # Save a copy with the date
Presentation.Close()
pptApp.Quit()

Related

kivy python android app why downloaded video from any website are not showing in honor android gallery even i have used to scane mediaScaner

my question is I build a android app using kivy and python for video downloader but there is a problem ,problem is when i downloading any video from any website that video immediately not showing in my android mobile media gallery my mobile model is honor 8x and real me6 , even i used to rescan MediaScannerConnection to scan video but not showing downloaded video in android gallery immediately,what is the reason?
or tell me how to do in python thanks in advance.
from jnius import autoclass, cast
PythonActivity = autoclass('org.kivy.android.PythonActivity')
currentActivity = cast('android.app.Activity', PythonActivity.mActivity)
context = cast('android.content.Context', currentActivity.getApplicationContext())
Intent = autoclass('android.content.Intent')
Uri = autoclass('android.net.Uri')
MediaScannerConnection = autoclass('android.media.MediaScannerConnection')
MediaScannerConnection.scanFile(context,[path],None, None)
Update: When I use your code, my phone will immediately show picture that I downloaded, so Maybe it is
Your phone gallery cache problem.
Your filepath or filename was wrong.
You putted your file in the path that will not show media.
Check if there is ".nomedia" file in your path or not, and delete it.
PythonActivity = autoclass('org.kivy.android.PythonActivity')
activity = PythonActivity.mActivity
currentActivity = cast('android.app.Activity', activity)
currentApplication = currentActivity.getApplicationContext()
Context = cast('android.content.Context', currentApplication)
MediaScannerConnection = autoclass('android.media.MediaScannerConnection')
def android_rescan_MediaStore(file):
if platform=="android":
MediaScannerConnection.scanFile(self.Context, [file], None, None)
To refresh the single file in MediaStore on Android, I use this way: (Test on Galaxy A8 2018.)
If this didn't work, try to clean your music player、gallery cache.
from jnius import autoclass, cast
PythonActivity = autoclass('org.kivy.android.PythonActivity')
activity = PythonActivity.mActivity
currentActivity = cast('android.app.Activity', activity)
File = autoclass('java.io.File')
Uri = autoclass('android.net.Uri')
Intent = autoclass('android.content.Intent')
Context = cast('android.content.Context', currentActivity.getApplicationContext())
def android_rescan_MediaStore(file):
file = Uri.fromFile(File(file))
mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, file)
Context.sendBroadcast(mediaScanIntent)
For example:
android_rescan_MediaStore("/storage/emulated/0/Download/example.mp3")
To find file path in primary external storage:
import os
from android.storage import primary_external_storage_path
from android.permissions import request_permissions, Permission
request_permissions([Permission.WRITE_EXTERNAL_STORAGE, Permission.READ_EXTERNAL_STORAGE])
AndroidPath = primary_external_storage_path()
filename = os.path.join(AndroidPath, "You file name and path in primary external storage")
# And then refresh it
android_rescan_MediaStore(filename)
# References:
# Stackoverflow tell me: You need at least 10 reputation to post more than 8 links.
# My reputation<10, so I use this way to post.
# https://stackoverflow.com/questions/72586638/downloaded-files-not-appearing-in-the-downloads-application-in-android-kivy
# https://developer.android.com/reference/android/content/Intent
# https://pyjnius.readthedocs.io/en/stable/android.html
# https://stackoverflow.com/questions/3572463/what-is-context-on-android
# https://developer.android.com/reference/android/content/Context
# https://developer.android.com/reference/android/content/package-summary
# https://stackoverflow.com/questions/4646913/android-how-to-use-mediascannerconnection-scanfile
# https://codertw.com/android-%E9%96%8B%E7%99%BC/331396/
# https://segmentfault.com/a/1190000014593444
# https://stackoverflow.com/questions/69054442/kivy-python-android-app-why-downloaded-video-from-any-website-are-not-showing-in
# https://stackoverflow.com/questions/54442336/using-mediastore-in-kivy-with-pyjnius
# https://developer.android.com/reference/android/provider/MediaStore
# https://stackoverflow.com/questions/3300137/how-can-i-refresh-mediastore-on-android
# https://stackoverflow.com/questions/60203353/action-media-scanner-scan-filestring-is-deprecated/63413716
# https://www.google.com/search?q=Android+Media+Storage
# https://www.google.com/search?q=Android%20rescan%20media

unotools insert image into document (libreoffice)

I'm trying to insert an image into a libreoffice document that is handled/controlled by unotools.
Therefore I start LibreOffice with this command:
soffice --accept='socket,host=localhost,port=8100;urp;StarOffice.Service'
Inside my python code I can connect to LibreOffice:
from unotools import Socket, connect
from unotools.component.writer import Writer
context = connect(Socket('localhost', 8100))
writer = Writer(context)
(This code is taken from this documentation: https://pypi.org/project/unotools/)
By using writer.set_string_to_end() I can add some text to the document. But I also want to insert an image into the document. So far I couldn't find any resource where this was done. The image is inside of my clipboard, so ideally I want to insert the image directly from there. Alternatively I can save the image temporarily and insert the saved file.
Is there any known way how to insert images by using unotools? Any alternative solution would also be great.
I've found a way to insert images by using uno instead of unotools:
import uno
from com.sun.star.awt import Size
from pythonscript import ScriptContext
def connect_to_office():
if not 'XSCRIPTCONTEXT' in globals():
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
'com.sun.star.bridge.UnoUrlResolver', localContext )
client = resolver.resolve("uno:socket,host=localhost,port=8100;urp;StarOffice.ComponentContext" )
global XSCRIPTCONTEXT
XSCRIPTCONTEXT = ScriptContext(client, None, None)
def insert_image(doc):
size = Size()
path = uno.systemPathToFileUrl('/somepath/image.png')
draw_page = self.doc.DrawPage
image = doc.createInstance( 'com.sun.star.drawing.GraphicObjectShape')
image.GraphicURL = path
draw_page.add(image)
size.Width = 7500
size.Height = 5000
image.setSize(size)
image.setPropertyValue('AnchorType', 'AT_FRAME')
connect_to_office()
doc = XSCRIPTCONTEXT.getDocument()
insert_image(doc)
sources:
https://ask.libreoffice.org/en/question/38844/how-do-i-run-python-macro-from-the-command-line/
https://forum.openoffice.org/en/forum/viewtopic.php?f=45&t=80302
I still don't know how to insert an image from my clipboard, I worked around that problem by saving the image first. If someone knows a way to insert the image directly from the clipboard that would still be helpful.

Refresh Excel Chart External Data Link with Python

I am trying to update the external data link for a chart in Excel using python. The chart sits in workbook1.xlsm and the data it references to update itself sits in external_workbook.xlsx. The reason for the separation is the data has to be updated in workbook1.xlsm periodically using python, which erases the chart if it's in workbook1.xlsm.
I've looked at various solutions but none are working for me so far. The two solutions I've tried so far include (1) refreshing the workbook programmatically and (2) running a macro in the workbook to refresh it programmatically.
Code for (1):
import win32com.client as w3c
xlapp = w3c.gencache.EnsureDispatch('Excel.Application')
xlapp.Visible = 0
xlwb = xlapp.Workbooks.Open(r'{}\{}'.format(path, fname), False, True, None)
xlwb.RefreshAll() # Runs with no errors, but doesn't refresh
time.sleep(5)
xlwb.Save()
xlapp.Quit()
Code for (2):
# ***************** #
# Excel macro - I've verified the macro works when I have the worksheet open.
Sub Update_Links()
ActiveWorkbook.UpdateLink Name:=ActiveWorkbook.LinkSources
End Sub
# ***************** #
import win32com.client as w3c
xlapp = w3c.gencache.EnsureDispatch('Excel.Application')
xlapp.Visible = 0
xlwb = xlapp.Workbooks.Open(r'{}\{}'.format(path, fname), False, True, None)
xlwb.Application.Run("{}!Module1.Update_Links".format(fname)) # Runs with no errors, but doesn't refresh
xlwb.Save()
xlapp.Quit()
The series for my chart in Excel is
# External data link for Excel chart #
=SERIES(,'...path_to_external_file...[external_workbook.xlsx]Sheet1'!$A$2:$A$2000,
'...path_to_external_file...[external_workbook.xlsx]Sheet1'!$F$2:$F$2000,1)
Could anyone provide me with an alternative solution of how to make this work?
EDIT
So I tried something simpler to test this. I created a new sheet called temp in workbook1.xlsm and tried to write a random value to cell A1 using the code below. The temp sheet is still blank after running the code.
import win32com.client as w3c
import random
xlapp = w3c.gencache.EnsureDispatch('Excel.Application')
xlapp.Visible = 0
xlwb = xlapp.Workbooks.Open(r'{}\{}'.format(path, fname), False, True, None)
books = w3c.Dispatch(xlwb)
sheet_temp = books.Sheets('temp')
sheet_temp.Cells(1,1).Value = random.random()
xlwb.RefreshAll() # Runs with no errors, but doesn't refresh
time.sleep(5)
xlwb.Save()
xlapp.Quit()
I get no errors with the code and am following examples other people have posted online. Could someone point me to where I'm going wrong with this?
The answer is I needed to open the workbook the external_workbook.xlsx prior to updating the workbook1.xlsm, so the data could be refreshed.
The working code is as follows:
import win32com.client as w3c
import random
xlapp = w3c.gencache.EnsureDispatch('Excel.Application')
xlapp.Visible = 0
# ********************************* #
# New line that fixes it #
xlwb_data = xlapp.Workbooks.Open(r'{}\{}'.format(path, 'external_workbook.xlsx'), False, True, None)
# ********************************* #
xlwb = xlapp.Workbooks.Open(r'{}\{}'.format(path, 'workbook1.xlsm'), False, True, None)
books = w3c.Dispatch(xlwb)
sheet_temp = books.Sheets('temp')
sheet_temp.Cells(1,1).Value = random.random()
xlwb.RefreshAll() # Runs with no errors, but doesn't refresh
time.sleep(5)
xlwb.Save()
xlapp.Quit()

win32com Excel PasteSpecial

I'm having some trouble with PasteSpecial in python. Here's the sample code:
import win32com.client as win32com
from win32com.client import constants
xl = win32com.gencache.EnsureDispatch('Excel.Application')
xl.Visible = True
wb = xl.Workbooks.Add ()
Sheet1 = wb.Sheets("Sheet1")
# Fill in some summy formulas
for i in range(10):
Sheet1.Cells(i+1,1).Value = "=10*"+str(i+1)
Sheet1.Range("A1:A16").Copy()
Sheet1.Range("C1").Select()
Sheet1.PasteSpecial(Paste=constants.xlPasteValues)
I'm getting the following error:
TypeError: Paste() got an unexpected keyword argument 'Paste'
I know that paste is a keyword argument because of the MSDN here:
http://msdn.microsoft.com/en-us/library/office/ff839476(v=office.15).aspx
Any idea why it won't let me do this? Can't really find much on the web.
Edit for solution(s):
import win32com.client as win32com
from win32com.client import constants
xl = win32com.gencache.EnsureDispatch('Excel.Application')
xl.Visible = True
wb = xl.Workbooks.Add ()
Sheet1 = wb.Sheets("Sheet1")
# Fill in some summy formulas
for i in range(10):
Sheet1.Cells(i+1,1).Value = "=10*"+str(i+1)
Sheet1.Range("A1:A16").Copy()
Sheet1.Range("C1").PasteSpecial(Paste=constants.xlPasteValues)
# OR this I just found right after I posted this works as well:
xl.Selection.PasteSpecial(Paste=constants.xlPasteValues)
You can get value for xlPasteFormats by execute macro in Excel vb:
Sub Macro2()
Range("A7").Select
ActiveCell.FormulaR1C1 = xlPasteFormats
End Sub
The value for xlPasteFormats is -4122
In Python script you can use
xlSheet.Range("A7:H7").Copy()
xlSheet.Range("A%s:H%s"%(r,r)).PasteSpecial(Paste=-4122)
I don't work with python but to do a PasteSpecial in Excel-VBA, you have to mention the cell where you want to perform the pastespecial, so try like
Sheet1.Range("C1").PasteSpecial(Paste=constants.xlPasteValues)
If you want a simple paste then I guess this should work
Sheet1.Paste

Google Analytics and Python

I'm brand new at Python and I'm trying to write an extension to an app that imports GA information and parses it into MySQL. There is a shamfully sparse amount of infomation on the topic. The Google Docs only seem to have examples in JS and Java...
...I have gotten to the point where my user can authenticate into GA using SubAuth. That code is here:
import gdata.service
import gdata.analytics
from django import http
from django import shortcuts
from django.shortcuts import render_to_response
def authorize(request):
next = 'http://localhost:8000/authconfirm'
scope = 'https://www.google.com/analytics/feeds'
secure = False # set secure=True to request secure AuthSub tokens
session = False
auth_sub_url = gdata.service.GenerateAuthSubRequestUrl(next, scope, secure=secure, session=session)
return http.HttpResponseRedirect(auth_sub_url)
So, step next is getting at the data. I have found this library: (beware, UI is offensive) http://gdata-python-client.googlecode.com/svn/trunk/pydocs/gdata.analytics.html
However, I have found it difficult to navigate. It seems like I should be gdata.analytics.AnalyticsDataEntry.getDataEntry(), but I'm not sure what it is asking me to pass it.
I would love a push in the right direction. I feel I've exhausted google looking for a working example.
Thank you!!
EDIT: I have gotten farther, but my problem still isn't solved. The below method returns data (I believe).... the error I get is: "'str' object has no attribute '_BecomeChildElement'" I believe I am returning a feed? However, I don't know how to drill into it. Is there a way for me to inspect this object?
def auth_confirm(request):
gdata_service = gdata.service.GDataService('iSample_acctSample_v1.0')
feedUri='https://www.google.com/analytics/feeds/accounts/default?max-results=50'
# request feed
feed = gdata.analytics.AnalyticsDataFeed(feedUri)
print str(feed)
Maybe this post can help out. Seems like there are not Analytics specific bindings yet, so you are working with the generic gdata.
I've been using GA for a little over a year now and since about April 2009, i have used python bindings supplied in a package called python-googleanalytics by Clint Ecker et al. So far, it works quite well.
Here's where to get it: http://github.com/clintecker/python-googleanalytics.
Install it the usual way.
To use it: First, so that you don't have to manually pass in your login credentials each time you access the API, put them in a config file like so:
[Credentials]
google_account_email = youraccount#gmail.com
google_account_password = yourpassword
Name this file '.pythongoogleanalytics' and put it in your home directory.
And from an interactive prompt type:
from googleanalytics import Connection
import datetime
connection = Connection() # pass in id & pw as strings **if** not in config file
account = connection.get_account(<*your GA profile ID goes here*>)
start_date = datetime.date(2009, 12, 01)
end_data = datetime.date(2009, 12, 13)
# account object does the work, specify what data you want w/
# 'metrics' & 'dimensions'; see 'USAGE.md' file for examples
account.get_data(start_date=start_date, end_date=end_date, metrics=['visits'])
The 'get_account' method will return a python list (in above instance, bound to the variable 'account'), which contains your data.
You need 3 files within the app. client_secrets.json, analytics.dat and google_auth.py.
Create a module Query.py within the app:
class Query(object):
def __init__(self, startdate, enddate, filter, metrics):
self.startdate = startdate.strftime('%Y-%m-%d')
self.enddate = enddate.strftime('%Y-%m-%d')
self.filter = "ga:medium=" + filter
self.metrics = metrics
Example models.py: #has the following function
import google_auth
service = googleauth.initialize_service()
def total_visit(self):
object = AnalyticsData.objects.get(utm_source=self.utm_source)
trial = Query(object.date.startdate, object.date.enddate, object.utm_source, ga:sessions")
result = service.data().ga().get(ids = 'ga:<your-profile-id>', start_date = trial.startdate, end_date = trial.enddate, filters= trial.filter, metrics = trial.metrics).execute()
total_visit = result.get('rows')
<yr save command, ColumnName.object.create(data=total_visit) goes here>

Categories

Resources