How to control windows master audio in python script - python

going off of the suggestion by abarnert in Python: Change Windows 7 master volume
I'm trying to write a python script to control the master volume in windows 7
I understand that in C++ this can be done like so:
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
mmde = CoCreateInstance(
CLSID_MMDeviceEnumerator, NULL,
CLSCTX_ALL, IID_IMMDeviceEnumerator,
(void**)&pEnumerator);
mmd = mmde.GetDefaultAudioEndpoint(eRender, eMultimedia);
mgr = mmd.Activate(IID_IAudioSessionManager);
sav = mgr.GetSimpleAudioVolume(None, True);
sav.SetMasterVolume(0.5);
I'm trying to get that functionality in python using pywin32, but I find myself stuck. The code I have so far is:
import pythoncom
CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator)
IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator)
mmde = pythoncom.CoCreateInstance(CLSID_MMDeviceEnumerator, None, CLSCTX_ALL, IID_IMMDeviceEnumerator)
mmd = mmde.GetDefaultAudioEndpoint(eRender, eMultimedia)
mgr = mmd.Activate(IID_IAudioSessionManager)
sav = mgr.GetSimpleAudioVolume(None, True)
sav.SetMasterVolume(0.5)
CoCreateInstance wants the class ID (CLSID) of the MMDeviceEnumerator, but doesn't seem to have any function like __uuidof() to use to get the class ID. (Not that I could find anyway.)
Does anyone have any ideas / suggestions? I'm new to both COM/OLE programming and pywin32 and feeling a little lost.

From the documentation
PyIUnknown = CoCreateInstance(clsid, unkOuter , context , iid )
where
clsid : PyIID
Class identifier (CLSID) of the object
A PyIID object is used whenever a COM GUID is used. PyIID objects can be created using the pywintypes.IID() function, although all functions that accept a GUID also accept a string in the standard GUID format.
PyIID = IID(iidString, is_bytes )
where iidString is a string representation of an IID, or a ProgID.
MMDeviceEnumerator CLSID is BCDE0395-E52F-467C-8E3D-C4579291692E
so try this
PyIID = IID("BCDE0395-E52F-467C-8E3D-C4579291692E", is_bytes )

Related

Python to Java script SendMailRequest with SourceArn and FromArn

I have here a part of a code in Python which is for AWS SendEmailRequest(SES)
response = boto3.client('ses').send_raw_email(
FromArn='response = boto3.client('ses').send_raw_email(
FromArn='arn:aws:ses:us-east-1:123456789012:identity/example.com',
SourceArn='arn:aws:ses:us-east-1:123456789012:identity/example.com',
RawMessage={
'Data': msg
},
)
This is working as expected. My problem is that I also need to have this in my Java script but I'm confused how to incorporate it. I've been trying but it seems to be not working. This is the existing Java script part below:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
message.writeTo(outputStream);
RawMessage rawMessage = new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));
SendRawEmailRequest rawEmailRequest = new SendRawEmailRequest(rawMessage)
client.sendRawEmail(rawEmailRequest);
I think the FromArn and SourceArn should be incorporated in the rawMessage or rawEmailRequest but I couldn't make it work. On the top of the code, there are values declared like this:
public class SESEMail {
static final String FROM = "example#web.com";
static final String key = Config.key;
static final String privatekey = Config.privateKey;
static Logger logger = Logger.getLogger(SESEMail.class);
public static Variables variables;
I've been reading this one but still confused with how Java language works. http://javadox.com/com.amazonaws/aws-java-sdk-ses/1.10.29/com/amazonaws/services/simpleemail/model/SendRawEmailRequest.html#getSourceArn()

Create activities for an user with Stream-Framework

I'm trying to setup stream-framework the one here not the newer getstream. I've setup the Redis server and the environment properly, the issue I'm facing is in creating the activities for a user.
I've been trying to create activities, following the documentation to add an activity but it gives me an error message as follows:
...
File "/Users/.../stream_framework/activity.py", line 110, in serialization_id
if self.object_id >= 10 ** 10 or self.verb.id >= 10 ** 3:
AttributeError: 'int' object has no attribute 'id'
Here is the code
from stream_framework.activity import Activity
from stream_framework.feeds.redis import RedisFeed
class PinFeed(RedisFeed):
key_format = 'feed:normal:%(user_id)s'
class UserPinFeed(PinFeed):
key_format = 'feed:user:%(user_id)s'
feed = UserPinFeed(13)
print(feed)
activity = Activity(
actor=13, # Thierry's user id
verb=1, # The id associated with the Pin verb
object=1, # The id of the newly created Pin object
)
feed.add(activity) # Error at this line
I think there is something missing in the documentation or maybe I'm doing something wrong. I'll be very grateful if anyone helps me get the stream framework working properly.
The documentation is inconsistent. The verb you pass to the activity should be (an instance of?*) a subclass of stream_framework.verbs.base.Verb. Check out this documentation page on custom verbs and the tests for this class.
The following should fix the error you posted:
from stream_framework.activity import Activity
from stream_framework.feeds.redis import RedisFeed
from stream_framework.verbs import register
from stream_framework.verbs.base import Verb
class PinFeed(RedisFeed):
key_format = 'feed:normal:%(user_id)s'
class UserPinFeed(PinFeed):
key_format = 'feed:user:%(user_id)s'
class Pin(Verb):
id = 5
infinitive = 'pin'
past_tense = 'pinned'
register(Pin)
feed = UserPinFeed(13)
activity = Activity(
actor=13,
verb=Pin,
object=1,
)
feed.add(activity)
I quickly looked over the code for Activity and it looks like passing ints for actor and object should work. However, it is possible that these parameters are also outdated in the documentation.
* The tests pass in classes as verb. However, the Verb base class has the methods serialize and __str__ that can only be meaningfully invoked if you have an object of this class. So I'm still unsure which is required here. It seems like in the current state, the framework never calls these methods, so classes still work, but I feel like the author originally intended to pass instances.
With the help of great answer by #He3lixxx, I was able to solve it partially. As the package is no more maintained, the package installs the latest Redis client for python which was creating too many issues so by installation redis-2.10.5 if using stream-framework-1.3.7, should fix the issue.
I would also like to add a complete guide to properly add activity to a user feed.
Key points:
If you are not using feed manager, then make sure to first insert the activity before you add it to the user with feed.insert_activity(activity) method.
In case of getting feeds with feed[:] throws an error something like below:
File "/Users/.../stream_framework/activity.py", line 44, in get_hydrated
activity = activities[int(self.serialization_id)]
KeyError: 16223026351730000000001005L
then you need to clear data for that user using the key format for it in my case the key is feed:user:13 for user 13, delete it with DEL feed:user:13, In case if that doesn't fix the issue then you can FLUSHALL which will delete everything from Redis.
Sample code:
from stream_framework.activity import Activity
from stream_framework.feeds.redis import RedisFeed
from stream_framework.verbs import register
from stream_framework.verbs.base import Verb
class PinFeed(RedisFeed):
key_format = 'feed:normal:%(user_id)s'
class UserPinFeed(PinFeed):
key_format = 'feed:user:%(user_id)s'
class Pin(Verb):
id = 5
infinitive = 'pin'
past_tense = 'pinned'
register(Pin)
feed = UserPinFeed(13)
print(feed[:])
activity = Activity(
actor=13,
verb=Pin,
object=1)
feed.insert_activity(activity)
activity_id = feed.add(activity)
print(activity_id)
print(feed[:])

QDBusInterface Upower Properties in Python are None

I am trying to convert some c++/qt code to Python/qt.
Using QDBusInterface in c++:
auto qi = make_unique<QDBusInterface>("org.freedesktop.UPower", /org/freedesktop/UPower, "org.freedesktop.UPower", QDBusConnection::systemBus());
at this point I can already read values from it's properties:
auto prop = qi.property("OnBattery");
Unfortunately it does not work that way while doing the same in Python:
qi = QDBusInterface(serviceObject, path, interface, QDBusConnection.systemBus())
qi.isValid() returns True but reading property:
onBattery = qi.property("OnBattery")
returns None.
Also calling methods like EnumerateDevices works on both C++ and Python
Is there a way to make it work?
The problem here is lack of good examples:
from PyQt5.QtDBus import QDBusConnection, QDBusInterface, QDBusMessage
# DBus connection and Interface.
dbus_service = 'org.freedesktop.UPower'
dbus_path = '/org/freedesktop/UPower'
interface = QDBusInterface(dbus_service, dbus_path, 'org.freedesktop.DBus.Properties', QDBusConnection.systemBus())
# Get all properties.
msg = interface.call('GetAll', 'org.freedesktop.UPower')
print(msg.arguments())
for k, v in msg.arguments()[0].items():
print('{}: {}'.format(k, v))
# Get just the requested property.
msg = interface.call('Get', 'org.freedesktop.UPower', 'OnBattery')
print(msg.arguments()[0])
I found indirect solution on my own.
It was resigning from using QDBusInterface and switching to Python's dbus which API can be used like in this link

How to use own created Automation Interface for CATIA V5 with Python?

I created own Automation Interface for CATIA V5. My interface implements one CAA interface.
Here is the example implementation of SetComment method. CAAInterface is a fake name
// MyXYZClass : SetComment
HRESULT MyXYZClass::SetComment( CATISpecObject_var ispObject, const
CATBSTR &irComment )
{
CAAInterface_var spInfo = ispObject;
if( !!spInfo )
{
CATUnicodeString commentToSet;
commentToSet.BuildFromBSTR( irComment );
spInfo->SetComment( commentToSet );
}
return S_OK;
}
I tested that with CATScript inside of my CATIA Environment:
Sub CATMain()
' retrieve ASMPRODUCT of Part or Product
Dim myPrd As Product
Set myPrd = CATIA.ActiveDocument.Product
' Retrieve My Factory of Document
Dim myFact As MyFactoryVB
Set myFact = myPrd
' Retrieve Object as part
Dim myObject As AnyObject
Set myObject = CATIA.ActiveDocument.Part
' SetComment
myFact.SetComment myObject, "comment"
And it worked perfectly.
Corresponding CATIA document
enter image description here
Additionally I created Visual Studio VB project, added reference->COM->Type Libraries (my CATIA V5 MyXYZAutInterf. If CATIA is running, I can see it).
Imports System.Runtime.InteropServices
Imports MyXYZAutInterf
Imports MECMOD
Imports ProductStructureTypeLib
' attach catia
Sub Main()
' retrieve ASMPRODUCT of Part or Product
Dim product As Product
product = CATIA.ActiveDocument.Product
' Retrieve My Factory of Document
Dim myFact As MyFactoryVB
myFact = product
' Retrieve Object as part
Dim part1 As Part
part1 = CATIA.ActiveDocument.Part
' Find object by Name
Dim myObject As AnyObject
myObject = part1.FindObjectByName("Pad.1")
' SetComment
myFact.SetComment(myObject, "comment")
End Sub
And it worked perfectly too.
Now I want use my automation interface with Python
# First I generated wrapper code for my type library
import sys
if not hasattr(sys, "frozen"):
from comtypes.client import GetModule
GetModule("C:/..//MyXYZTypeLib.tlb")
#load my module
from comtypes.gen import MyXYZAutInterf as myModul
# myModul -> MyFactoryVB -- <unbound method MyFactoryVB.SetComment>
# Connecting to windows COM
catapp = win32com.client.Dispatch("CATIA.Application")
documents1 = catapp.Documents
partDocument1 = documents1.Item("Part.CATPart")
part1 = partDocument1.Part
bodies1 = part1.Bodies
body1 = bodies1.Item("PartBody")
shapes1 = body1.Shapes
shape1 = shapes1.Item("Pad.1")
myFact = myModul.MyFactoryVB()
# now I can see all my implemented methods under _methods_
But now I am not able to use myFact.
If I do:
myFact.SetComment(shape1, "comment")
I get error: Expected a COM this pointer as first argument.
I should to assign myFact to product (like CATScript):
product1 = catapp.ActiveDocument.Product
myFact = product1
But I get error too: unknown.SetComment.
I'm realy frustrated. Can somebody help me, please?
I fixed it. I used GetCustomerFactory("ALIAS_NAME")
I have successfully created the *.tlb for the interface framework without any issue. I have also created the implementation framework which it derives from CATBaseObject and kept TIE mode as created interface.
CAAIAVbCalling.idl:
interface CAAIAVbCalling : CATIABase
{
HRESULT NewStrFun(in CATBSTR istr,
out /*IDLRETVAL*/ CATBSTR ostr );
};
Method implementation:
HRESULT __stdcall CAAEVbCallingComp::NewStrFun(CATBSTR istr,CATBSTR *ostr )
{
cout << "CAAEVbCallingComp::NewStrFun" << endl;
return S_OK;
}
I have added the created *.tlb under reference in VBEditor. I am unable to instantiate interface object from Vbscript.

What's the correct way to use win32inet.WinHttpGetProxyForUrl

I'm trying to use a feature of the Microsoft WinHttp library that has been exposed by the developers of Win32com. Unfortunately most of the library does not seem to be documented and there are no example of the correct way to use the win32inet features via the win32com library.
This is what I have so far:
import win32inet
hinternet = win32inet.InternetOpen("foo 1.0", 0, "", "", 0)
# Does not work!!!
proxy = win32inet.WinHttpGetProxyForUrl( hinternet, u"http://www.foo.com", 0 )
As you can see, all I am trying to do is use the win32inet feature to find out which proxy is the appropriate one to use for a given URL, int his case foo.com.
Can you help me correct the syntax of the last line? MSN has some good documentation for the function being wrapped but the args do not seem to map the to those of the python library perfectly.
The fixed version of this script should:
Be able to look up which proxy to use
for any given URL.
It should always do exactly what Internet Explorer would do (i.e. use the same proxy)
It should be valid on any valid Windows XP set-up. That means it should work with an explicitly configured proxy and also no proxy at all.
It only needs to work on Windows XP 32bit with Python 2.4.4. It can use any official released version of win32com.
I'm using Python2.4.4 with Win32Com on Windows XP.
UPDATE 0:
OR... can you give me an alternative implementation in cTypes? As long as I can make it work I'm happy!
Here is the code which creates HINTERNET session and uses that to get proxy details, using ctypes to directly access winhttp DLL.
It works without any error but I have no proxy set on my machine, you may have to tweak few constants to get it right. Go thru the msdn links in code, from where I have seen the API.
import ctypes
import ctypes.wintypes
winHttp = ctypes.windll.LoadLibrary("Winhttp.dll")
# http://msdn.microsoft.com/en-us/library/aa384098(VS.85).aspx
# first get a handle to HTTP session
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY=0
WINHTTP_NO_PROXY_NAME=WINHTTP_NO_PROXY_BYPASS=0
WINHTTP_FLAG_ASYNC=0x10000000
HINTERNET = winHttp.WinHttpOpen("PyWin32", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC)
print HINTERNET
# now get proxy using HTTP session
# http://msdn.microsoft.com/en-us/library/aa384097(VS.85).aspx
"""
BOOL WinHttpGetProxyForUrl(
__in HINTERNET hSession,
__in LPCWSTR lpcwszUrl,
__in WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions,
__out WINHTTP_PROXY_INFO *pProxyInfo
);
"""
# create C structure for WINHTTP_AUTOPROXY_OPTIONS
#http://msdn.microsoft.com/en-us/library/aa384123(VS.85).aspx
"""
typedef struct {
DWORD dwFlags;
DWORD dwAutoDetectFlags;
LPCWSTR lpszAutoConfigUrl;
LPVOID lpvReserved;
DWORD dwReserved;
BOOL fAutoLogonIfChallenged;
} WINHTTP_AUTOPROXY_OPTIONS;
"""
class WINHTTP_AUTOPROXY_OPTIONS(ctypes.Structure):
_fields_ = [("dwFlags", ctypes.wintypes.DWORD),
("dwAutoDetectFlags", ctypes.wintypes.DWORD),
("lpszAutoConfigUrl", ctypes.wintypes.LPCWSTR),
("lpvReserved", ctypes.c_void_p ),
("dwReserved", ctypes.wintypes.DWORD),
("fAutoLogonIfChallenged",ctypes.wintypes.BOOL),]
WINHTTP_AUTOPROXY_AUTO_DETECT = 0x00000001;
WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001;
WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002;
options = WINHTTP_AUTOPROXY_OPTIONS()
options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT
options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A
options.lpszAutoConfigUrl = 0
options.fAutoLogonIfChallenged = False
# create C structure for WINHTTP_AUTOPROXY_OPTIONS
# http://msdn.microsoft.com/en-us/library/aa383912(VS.85).aspx
"""
struct WINHTTP_PROXY_INFO {
DWORD dwAccessType;
LPWSTR lpszProxy;
LPWSTR lpszProxyBypass;
};
"""
class WINHTTP_PROXY_INFO(ctypes.Structure):
_fields_ = [("dwAccessType", ctypes.wintypes.DWORD),
("lpszProxy", ctypes.wintypes.LPCWSTR),
("lpszProxyBypass", ctypes.wintypes.LPCWSTR),]
info = WINHTTP_PROXY_INFO()
ret = winHttp.WinHttpGetProxyForUrl(HINTERNET, "http://www.google.com", ctypes.pointer(options), ctypes.pointer(info) )
print "proxy success?",ret
if not ret:
# some error lets see what is that?
import win32api
import win32con
errorCode = win32api.GetLastError()
print "win32 Error:",errorCode
s = ""
print win32api.FormatMessage(errorCode)
print info.dwAccessType, info.lpszProxy, info.lpszProxyBypass
Unless there is a strong reason for using win32inet (which is messy in this area due to limitations of SWIG), I recommend that you use ctypes instead.
At least with Python 2.7.6 and Pywin 218 on Windows XP x86 and Windows 8 x64, it works:
import win32inet
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384098(v=vs.85).aspx
hinternet = win32inet.WinHttpOpen("foo", 0, "", "", 0)
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384123(v=vs.85).aspx
autoproxy_options = (2, 0, u"http://your-proxy-script-path", None, 0, 1)
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384097(v=vs.85).aspx
proxy = win32inet.WinHttpGetProxyForUrl(hinternet, u"http://www.google.com",
autoproxy_options)
print proxy
Worth to mention that the example uses the autoproxy option WINHTTP_AUTOPROXY_CONFIG_URL in order to pass in an explicit URL. You can use other options, for instance, if you want to autodetect using DNS or DHCP you can do:
autoproxy_options = (1, 1|2, u"", None, 0, 1)
You can find other options in the link showed above (in the code)

Categories

Resources