|
#!/usr/bin/python |
|
"""mount_shares_better.py |
|
|
|
Mount file shares on OS X. |
|
""" |
|
from CoreFoundation import CFURLCreateWithString |
|
import Foundation |
|
from objc import initFrameworkWrapper |
|
from objc import loadBundleFunctions |
|
from objc import pathForFramework |
|
|
|
class AttrDict(dict): |
|
"""Dict for attributes""" |
|
__getattr__ = dict.__getitem__ |
|
__setattr__ = dict.__setitem__ |
|
|
|
NETFS = AttrDict() |
|
# Can cheat and provide 'None' for the identifier, it'll just use |
|
# frameworkPath instead scan_classes=False means only add the contents |
|
# of this Framework |
|
NETFS_BUNDLE = initFrameworkWrapper( |
|
'NetFS', frameworkIdentifier=None, |
|
frameworkPath=pathForFramework('NetFS.framework'), |
|
globals=NETFS, scan_classes=False) |
|
|
|
# https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html |
|
# Fix NetFSMountURLSync signature |
|
del NETFS['NetFSMountURLSync'] |
|
loadBundleFunctions(NETFS_BUNDLE, NETFS, [('NetFSMountURLSync', 'i@@@@@@o^@')]) |
|
|
|
def mount_share(share_path): |
|
"""Mounts share at /Volumes |
|
|
|
Args: |
|
share_path (str): The remote path, including protocol and auth info. |
|
Returns: |
|
The mount point if successful. Raises an error otherwise. |
|
""" |
|
sh_url = CFURLCreateWithString(None, share_path, None) |
|
# Set UI to reduced interaction |
|
open_options = {NETFS.kNAUIOptionKey: NETFS.kNAUIOptionNoUI} |
|
# Allow mounting sub-directories of root shares |
|
mount_options = {NETFS.kNetFSAllowSubMountsKey: True} |
|
# Mount! |
|
result, output = NETFS.NetFSMountURLSync( |
|
sh_url, None, None, None, open_options, mount_options, None) |
|
# Check if it worked |
|
if result != 0: |
|
raise Exception('Error mounting url "{}": {}'.format |
|
(share_path, output)) |
|
# Return the mount path |
|
return str(output[0]) |
|
|
|
def mount_share_at_path(share_path, mount_path): |
|
"""Mounts a share at the specified path |
|
|
|
Args: |
|
share_path (str): The remote path, including protocol and auth info. |
|
mount_path (str): The path where share will be mounted locally. |
|
Returns: |
|
The mount point if successful. Raises an error otherwise. |
|
""" |
|
sh_url = CFURLCreateWithString(None, share_path, None) |
|
mo_url = CFURLCreateWithString(None, mount_path, None) |
|
# Set UI to reduced interaction |
|
open_options = {NETFS.kNAUIOptionKey: NETFS.kNAUIOptionNoUI} |
|
# Allow mounting sub-directories of root shares. |
|
# Also, specify the share should be mounted directly |
|
# at (not under) mount_path |
|
mount_options = { |
|
NETFS.kNetFSAllowSubMountsKey: True, |
|
NETFS.kNetFSMountAtMountDirKey: True,} |
|
# Mount! |
|
result, output = NETFS.NetFSMountURLSync( |
|
sh_url, mo_url, None, None, open_options, mount_options, None) |
|
# Check if it worked |
|
if result != 0: |
|
raise Exception( |
|
'Error mounting url "{}" at path "{}": {}'.format |
|
(share_path, mount_path, output)) |
|
# Return the mount path |
|
return str(output[0]) |