# TinyURLService

- `Download example`

A PyObjC Example without documentation

## Sources

### TinyURLService.py

    import traceback
    import urllib
    import urllib2

    import Cocoa
    import objc
    from PyObjCTools import AppHelper

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

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

    NAME = "TinyURLService-0.0"
    TINYURL_API = "http://tinyurl.com/api-create.php"

    def getTinyURL(url):
        data = urllib.urlencode({"url": url, "source": NAME})
        return urllib2.urlopen(TINYURL_API, data).read().decode("utf-8")

    class TinyURLService(Cocoa.NSObject):
        @serviceSelector
        def doTinyURLService_userData_error_(self, pboard, data, error):
            # Mail.app in 10.4.1 doesn't do NSURLPboardType correctly!
            # Probably elsewhere too, so we just use strings.
            try:
                types = pboard.types()
                url = None

                if Cocoa.NSStringPboardType in types:
                    urlString = pboard.stringForType_(Cocoa.NSStringPboardType)
                    url = Cocoa.NSURL.URLWithString_(urlString.strip())
                    if url is None:
                        return ERROR(
                            Cocoa.NSLocalizedString(
                                "Error: Given URL was not well-formed.",
                                "Given URL not well-formed.",
                            )
                        )

                if url is None:
                    return ERROR(
                        Cocoa.NSLocalizedString(
                            "Error: Pasteboard doesn't contain a valid URL.",
                            "Pasteboard doesn't contain a valid URL.",
                        )
                    )

                urlString = url.absoluteString()

                res = getTinyURL(urlString.UTF8String())

                resURL = Cocoa.NSURL.URLWithString_(res)
                if resURL is None:
                    return ERROR(
                        Cocoa.NSLocalizedString(
                            "Error: Resultant URL was not well-formed.",
                            "Resultant URL not well-formed.",
                        )
                    )
                pboard.declareTypes_owner_([Cocoa.NSStringPboardType], None)
                pboard.setString_forType_(resURL.absoluteString(), Cocoa.NSStringPboardType)
                return ERROR(None)
            except:  # noqa: E722, B001
                traceback.print_exc()
                return ERROR("Exception, see traceback")

    def main():
        serviceProvider = TinyURLService.alloc().init()
        Cocoa.NSRegisterServicesProvider(serviceProvider, "TinyURLService")
        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.TinyURLService",
        "LSBackgroundOnly": 1,
        "NSServices": [
            {
                "NSKeyEquivalent": {"default": "0"},
                "NSMenuItem": {"default": "Shorten URL"},
                "NSMessage": "doTinyURLService",
                "NSPortName": "TinyURLService",
                "NSReturnTypes": ["NSStringPboardType"],
                "NSSendTypes": ["NSStringPboardType"],
            }
        ],
    }

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