# SimpleService

- `Download example`

Shows how to implement entries for the Services menu.

## Sources

### ServiceTest.py

    import Cocoa
    import objc

    def serviceSelector(fn):
        # this is the signature of service selectors
        return objc.selector(fn, signature=b"v@:@@o^@")

    def ERROR(s):
        # NSLog(u"ERROR: %s", s)
        return s

    class ServiceTest(Cocoa.NSObject):
        @serviceSelector
        def doOpenFileService_userData_error_(self, pboard, data, error):
            try:
                types = pboard.types()
                pboardString = None
                if Cocoa.NSStringPboardType in types:
                    pboardString = pboard.stringForType_(Cocoa.NSStringPboardType)
                if pboardString is None:
                    return ERROR(
                        Cocoa.NSLocalizedString(
                            "Error: Pasteboard doesn't contain a string.",
                            "Pasteboard couldn't give string.",
                        )
                    )

                if not Cocoa.NSWorkspace.sharedWorkspace().openFile_(pboardString):
                    return ERROR(
                        Cocoa.NSLocalizedString(
                            "Error: Couldn't open file %s.",
                            "Couldn't perform service operation for file %s.",
                        )
                        % pboardString
                    )

                return ERROR(None)
            except:  # noqa: E722, B001
                import traceback

                traceback.print_exc()
                return ERROR("Exception, see traceback")

        @serviceSelector
        def doCapitalizeService_userData_error_(self, pboard, data, err):
            # NSLog(u"doCapitalizeService_userData_error_(%s, %s)", pboard, data)
            try:
                types = pboard.types()
                pboardString = None
                if Cocoa.NSStringPboardType in types:
                    pboardString = pboard.stringForType_(Cocoa.NSStringPboardType)
                if pboardString is None:
                    return ERROR(
                        Cocoa.NSLocalizedString(
                            "Error: Pasteboard doesn't contain a string.",
                            "Pasteboard couldn't give string.",
                        )
                    )

                newString = Cocoa.NSString.capitalizedString(pboardString)

                if not newString:
                    return ERROR(
                        Cocoa.NSLocalizedString(
                            "Error: Couldn't capitalize string %s.",
                            "Couldn't perform service operation for string %s.",
                        )
                        % pboardString
                    )

                types = [Cocoa.NSStringPboardType]
                pboard.declareTypes_owner_([Cocoa.NSStringPboardType], None)
                pboard.setString_forType_(newString, Cocoa.NSStringPboardType)
                return ERROR(None)
            except:  # noqa: E722, B001
                import traceback

                traceback.print_exc()
                return ERROR("Exception, see traceback")

### SimpleService_main.py

    from Cocoa import NSRegisterServicesProvider
    from PyObjCTools import AppHelper
    from ServiceTest import ServiceTest

    def main():
        serviceProvider = ServiceTest.alloc().init()
        NSRegisterServicesProvider(serviceProvider, "PyObjCSimpleService")
        AppHelper.runConsoleEventLoop()

    if __name__ == "__main__":
        main()

### rebuild.py

    #!/usr/bin/env python
    """
    Quickie script to update the services
    """
    import AppKit

    AppKit.NSUpdateDynamicServices()

### setup.py

    """
    Script for building the example.

    Usage:
        python3 setup.py py2app
    """
    from setuptools import setup

    plist = {
        "CFBundleIdentifier": "net.sf.pyobjc.PyObjCSimpleService",
        "CFBundleName": "PyObjCSimpleService",
        "LSBackgroundOnly": 1,
        "NSServices": [
            {
                "NSKeyEquivalent": {"default": "F"},
                "NSMenuItem": {"default": "Open File"},
                "NSMessage": "doOpenFileService",
                "NSPortName": "PyObjCSimpleService",
                "NSSendTypes": ["NSStringPboardType"],
            },
            {
                "NSMenuItem": {"default": "Capitalize String"},
                "NSMessage": "doCapitalizeService",
                "NSPortName": "PyObjCSimpleService",
                "NSReturnTypes": ["NSStringPboardType"],
                "NSSendTypes": ["NSStringPboardType"],
            },
        ],
    }

    setup(
        name="Simple Service",
        app=["SimpleService_main.py"],
        options={"py2app": {"plist": plist}},
        setup_requires=["py2app", "pyobjc-framework-Cocoa"],
    )