Welcome to the Pythonista Community Forums!

Pythonista is a Python programming environment for iOS. To learn more, head over to the Pythonista Website.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Twitter
Safari-URL to Dropbox file
  • After reading macsories.com's article on Pythonista I had to try the app :)

    The problem is, that I don't know Python (but I have some very basic programming skills).

    I would like to create a Safari bookmarklet, which, when tapped, will save the current URL to a Dropbox file. It would be ideal if the file was a clickable html file (like a .webloc file), which will open the side in Safari.

    So I started and with syncing my Pytonista files to a Dropbox folder, which works great.

    Next I made a bookmarklet, which gets the URL:

    javascript:window.location='pythonista://get_url?action=run&argv='+encodeURIComponent(document.location.href);

    and which shows the result in this script (from a user of this forum):
    import sys
    import pprint
    import console

    console.clear()

    pprint.pprint(sys.argv[1:])

    This all works. So the next step is, to change the URL to text. And here starts my problem.

    I have tried to modify different codes I found on the internet, but I cannot do this thing. By trying things like

    input_file = sys.argv[1:]
    s = input_file
    s = urllib.quote(s.encode('utf-8'))

    and similar I get syntax or encoding errors. I other words: I don't know what to do :-P

    The next problem is to get the URL into a file, which can be synced with Dropbox. I searched a bit and it seems that appending the text to a Notesy file would be the easiest.

    I tried to modify different scripts (mostly from macstories and macdrifter), like:

    from dropboxlogin import get_client
    dropbox_client = get_client()
    import clipboard
    import keychain
    import time
    import console
    import sys
    import webbrowser
    import httplib

    input_file = sys.argv[1:]
    s = input_file
    s = urllib.quote(s.encode('utf-8'))

    #response = dropbox_client.put_file('/URL_Paste/' + titles +)

    print "uploaded!", #response

    time.sleep(3) # delay for 3 seconds

    console.clear()

    def main():
    dropbox_client = get_client()
    f, meta = dropbox_client.get_file_and_metadata('/URL_Paste/URL_File.txt')
    content = f.read() # can use readlines here to get list of lines
    # print 'file content:'
    # clipboard.set(last)
    console.clear()
    # print last
    webbrowser.open(last)

    if __name__ == '__main__':
    main()

    and

    import sys
    import webbrowser
    import clipboard
    import urllib

    input_file = sys.argv[1:]

    s = input_file

    s = urllib.quote(s.encode('utf-8'))

    webbrowser.open('notesy://x-callback-url/append?path=URL/URL_File.txt' + s)

    But this won't work either :-P

    So now I am looking for some help with this. The best way would be:
    bookmarklet -> creating a http://....com.html file -> Dropbox-sync via Pythonista -> auto-switch-back to Safari

    But I am not sure if this is possible. If it is not possible to create a html file (like a .webloc file), a text file with the URL would be okay to.

    I thought also of something like:
    bookmarklet -> creating a clickable html file -> Adding file and Dropbox-syncing the file via Nostey app -> auto-switch-back to Safari

    If anyone has some tips for even a single step so that I will achieve this workaround, I will be very happy :)

    Greetings, Timo
  • First off, switching back to Safari isn't really possible without opening another tab. The problem is that the http URL scheme is currently always handled by Pythonista's internal browser. I plan to add an option to open web pages in Safari, but it's not there yet. If you're okay with opening another browser tab, you could sort-of work around this by using the little-known ftp or x-web-search URL schemes, e.g.:

    import webbrowser
    # This will show an error page but do nothing else:
    webbrowser.open('ftp://')
    # or:
    # This will do a web search for "foo":
    webbrowser.open('x-web-search://?foo')

    Next: sys.argv is a list (sequence) and Python has some special syntax for slicing and dicing sequences which you're probably not familiar with. The expression sys.argv[1:] that you've used actually extracts all elements beginning from the second, so the result will also be a list and not a string. To get just the second element, use sys.argv[1] (note the missing colon!). This will be a string (well, assuming that the script was started with arguments).

    This also applies to your Notesy sample. That's probably where you should continue experimenting. Doing this with the Notesy URL scheme will probably be easier at first than to upload a webloc file to Dropbox via script (but that's also possible of course).
  • Hi :)

    thank You for the tips (and for correcting code to pre) :) . It helped a lot. Here is what I got and it seems to work (without the '#'):

    import webbrowser
    import sys
    import clipboard

    #s = sys.argv[1]

    #clipboard.set(s)

    #webbrowser.open('notesy://x-callback-url/append?path=URL/&name=abc.webloc&text=' + s)


    So my bookmarklet creates now a abc.webloc file (which is just a txt file) in the folder "URL" and the webside's URL in it. Now the next step is to create a real webloc file.

    Using the code form above works, but it seems to have a bug. When I try to sync via dropboxsync (code from this forum), there appears an error in the dorpboxsync file: "IndexError: list index out of range" it the line "import pickle" from the dropboxsync file. When I add the '#' like it is now in the code above, the dropbox sync works.

    Any ideas?


    @omz
    Do You know the app 'EvernoteWebClipper'? It does the circle:

    Safari -> Bookmarklet -> Opens EvernoteWebClipper -> Starts snycing with Evernote -> Switches back to Safari -> Reloads the page from earlier

    So there seems to be a way to get back to Safari. I will do some research in a free minute :)


    For now thanks again, Timo

  • I didn't say it's impossible in general to switch back to Safari, just that it's currently impossible to do with Pythonista. To switch back to Safari, you would need to open the URL you came from, but http URLs are currently opened in Pythonista's internal browser. I plan to make that optional.
  • Hi,

    sorry I didn't meant to offend You. Now I understand the situation. Thanks for the feedback :)
  • I don't know if this is exactly what you're looking for, but I have a script that takes a URL via bookmarklet and makes it an HTML in Dropbox, using the Instapaper parser to clean up a webpage. It also assumes you are logged into Dropbox using the module and keychain method Ole linked to somewhere on the forums.


    import clipboard
    import urllib2
    import console
    from dropboxlogin import get_client
    dropbox_client = get_client()
    import keychain
    import time
    import webbrowser
    import sys
    import urllib
    import bs4

    numArgs = len(sys.argv)

    console.clear()

    if numArgs < 2:
    url = clipboard.get()
    console.show_activity()

    soup = bs4.BeautifulSoup(urllib.urlopen(url))
    title = soup.title.string
    name = title.encode('utf-8')

    console.hide_activity()

    else:
    webpage = sys.argv[1]
    name = webpage.encode('utf-8')
    url = sys.argv[2]

    insta = 'http://instapaper.com/text?u='

    URL = insta + url

    print 'Generating HTML file...'

    getText = urllib2.Request(URL)
    openText = urllib2.urlopen(getText)
    content = (openText.read().decode('utf-8'))

    final = content.encode('utf-8')

    print 'Uploading HTML file to Dropbox...'

    #Dropbox folder to put file into
    response = dropbox_client.put_file('/HTMLs/' + name + '.html', final)

    print 'Your HTML file has been uploaded'

    print 'Converting to PDF...'

    time.sleep(15)

    encoded = urllib.quote(name, safe='')

    urlstring = 'x-icabmobile://x-callback-url/open?url=http://dl.dropbox.com/u/yourDropboxPublicID/' + encoded + '.html.pdf'

    webbrowser.open(urlstring)


    On my Mac mini, I have Hazel moving .html files into my Public directory, which is what iCab is opening with a default URL (your Dropbox ID).
  • Hi viticci,

    thank You for Your script. It's very nice. I hadn't thought of such a thing :)

    My original intention was a bit different. I want to send open tabs from mobile Safari to Safari on the Mac. I use the Reeder app for checking my news and if I find there is something interesting, I open the article in Safari. Because Safari has it's limitation to 8 tabs and because I sometimes like to continue my reading on my Mac, I was searching for a solution.

    Of course I had thought and tried apps like Instapaper or Pocket. But I don't like reading on the iPhone with these apps; on the Mac I think they are even worse.

    iCould on the other hand is okay, but not ideal. It takes many taps to open all tabs from the iPhone on the Mac (I have a Keyboard Maestro shortcut which does the work for me hehe). So I searched for something else. And than I read about Pythonista on Macstories.

    Right know I am working with my last script from above. Pythonista fetches the URL, Notesy uploads it. Hazel on the Mac watches the Notesy folder and starts an Automator workflow, which opens the URL in Safari. I couldn't figure out how to create a working webloc file, which Safari could open directly, so I did this Automator workflow. Finally Prowl on the iPhone informs me when the work is done.

    This all isn't great, but it works (some kind of) and comes close to my wishes.

    The next thing for me to do is to get rid of the Notesy step, but right now I cannot figure out how it works (I have some errors, mentioned in my earlier post). But I will keep on trying :)
  • Just a little pointer for the webloc file: You can use plistlib to create such a file pretty easily:

    import plistlib
    webloc = {'URL': 'http://google.com'}
    plistlib.writePlist(webloc, 'bookmark.webloc')

    Of course you would still have to figure out how to upload that file etc., but maybe it's a start... I'm not sure if you can upload a file with a webloc extension with Notesy, but if you can, you could also use plistlib.writePlistToString(webloc) to create the text content of the webloc file.
  • My actual code looks like this:

    import sys
    from dropboxlogin import get_client
    dropbox_client = get_client()

    s = sys.argv[1]

    #Dropbox folder to put file into
    response = dropbox_client.put_file('/URL/link.txt', s)


    So Notesy isn't necessary anymore.

    omz, I tried Your webloc suggestion, but all it does for me is to create a txt file with the link in it, not a real webloc.

    The other thing is there script creates for each part of an URL a separate folder, if the Dropbox line looks like this:

    response = dropbox_client.put_file('/URL/' + s + '.txt', s)


    The strange folder structure for a link like e.g. http://www.google.com/files/new/newfile.txt looks like this:

    /http
    -/files
    --/new
    ---/http://www.google.com/files/new/newfile.txt

    Any idea why this happens?
  • omz, I tried Your webloc suggestion, but all it does for me is to create a txt file with the link in it, not a real webloc.

    Your code shows that you're always uploading a file with a .txt extension, you would have to change that to .webloc for Safari to recognize the file.

    To avoid creating the nested folders, you would have to replace the slashes in your URL with something else.
  • Hi there :)

    I had some free minutes and tried to word on my code:

    import sys
    from dropboxlogin import get_client
    dropbox_client = get_client()
    import datetime
    import plistlib

    s = sys.argv[1]

    w = plistlib.writePlistToString(s)

    fmt = '%Y-%m-%d_%H-%M-%S'

    dt = str(datetime.datetime.now().strftime(fmt))

    newname = 'Link_' + dt + '.webloc'

    #Dropbox folder to put file into
    response = dropbox_client.put_file('/URL/' + newname, w)


    It does everything I want it to do, but there seems to be something wrong with the webloc file.

    While a working webloc file looks like (I have replaced the '<' with a '(' and '>' with a ')' ):

    (?xml version="1.0" encoding="UTF-8"?)
    (!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd")
    (plist version="1.0")
    (dict)
    (key)URL(/key)
    (string)http://www.omz-software.com/(/string)
    (/dict)
    (/plist)


    the file my script creates looks like:

    (?xml version="1.0" encoding="UTF-8"?)
    (!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd")
    (plist version="1.0")
    (string)http://www.omz-software.com(/string)
    (/plist)


    It opens an empty Safari page on the Mac. When I add the missing
    (dict)(key)URL(/key)...(/dict)
    the webloc file works.

    Am I doing something wrong?
  • Assuming s is just your URL, you should save the webloc file like this:

    ...
    w = plistlib.writePlistToString({'URL': s})
    ...

    The curly braces are important to make it a dictionary.