Forum Archive

Open .gif or image in Safari?

donnieh

Can a gif or image loaded from the scripts main directory be opened into Safari using webbrowser.open()? If so, how?

dgelessus

The general way to open a local file in the browser is this:

import webbrowser
webbrowser.open("file://" + the_file)

(If the_file is not a full absolute path, you need to use os.path.abspath(the_file) to fix that. But in this case it won't be necessary.)

The path of the current script is available in the __file__ variable, so you can use os.path.dirname(__file__) to get the directory in which your script is stored. So something like this should do what you want (untested):

import os
import webbrowser
webbrowser.open("file://" + os.path.join(os.path.dirname(__file__), "funny_cat.gif"))
donnieh

Thank you, that is helpful. Can the image be opened "externally" in Safari? Using something like webbrowser.open("safari-https://...)

dgelessus

I don't think that would work. Safari is a separate app, so it probably can't access any files in Pythonista's sandbox. The webbrowser module also doesn't have a scheme like safari-file to open a local file in the real Safari, probably because it wouldn't work anyway.

JonB

you could spawn a bottle app and serve up the photo...

donnieh

Oh I see. Hmmm. Ok, thanks for the feed back guys. I wish Apple allowed the Open-in feature.

Maybe I will try to modify and use this server script...

```

coding: utf-8

'''Creates a zip archive of your Pythonista files and serves them via HTTP in your local network.'''

'''Must have workflow installed:
https://workflow.is/workflows/53b0ceb6d51d4b12ae293bb41a564b72'''

from SimpleHTTPServer import SimpleHTTPRequestHandler
import os
import shutil
import tempfile
import shutil
import webbrowser
import urllib
import time

PORT = 8080

if name == 'main':
doc_path = os.path.expanduser('~/Documents')
os.chdir(doc_path)
backup_path = os.path.join(doc_path, 'Backup.zip')
if os.path.exists(backup_path):
os.remove(backup_path)
print 'Creating backup archive...'
shutil.make_archive(os.path.join(tempfile.gettempdir(), 'Backup'), 'zip')
shutil.move(os.path.join(tempfile.gettempdir(), 'Backup.zip'), backup_path)
print 'Backup archive created, starting HTTP server...'
time.sleep(3)
webbrowser.open('workflow://x-callback-url/run-workflow?name=Backup_Pythonista&input='+urllib.quote(''))

from BaseHTTPServer import HTTPServer
server = HTTPServer(('', PORT), SimpleHTTPRequestHandler)
print 'You can now download a backup of your Pythonista scripts by entering this URL in Safari (on this device):'
print 'http://localhost:%i/Backup.zip' % (PORT,)
print 'If you want to download the backup to another device in your network, use your device\'s IP address instead of "localhost".'
print 'Tap the stop button in the editor or console when you\'re done.'
try:
    server.serve_forever()
except KeyboardInterrupt:
    server.shutdown()
    print 'Server stopped'
```
cvp

Try this, it should open Safari, after having started your web server:

from objc_util import nsurl,UIApplication
from socket import gethostname
app = UIApplication.sharedApplication()
URL = 'http://%s.local:8080' % gethostname()+'/Backup.zip' # or other file name of course
app.openURL_(nsurl(URL))

cvp

This functions in Python2 but you can use tool for converting to python3 because SimpleHTTPServer does no more exist in Python3

#!python2
# coding: utf-8
from SimpleHTTPServer import SimpleHTTPRequestHandler
import os
import shutil
import tempfile
import shutil
import webbrowser
import urllib
import time
from objc_util import nsurl,UIApplication
from socket import gethostname

PORT = 8080

if __name__ == '__main__':
    doc_path = os.path.expanduser('~/Documents')
    os.chdir(doc_path)

    from BaseHTTPServer import HTTPServer
    server = HTTPServer(('', PORT), SimpleHTTPRequestHandler)
    app = UIApplication.sharedApplication()
    URL = 'http://%s.local:8080' % gethostname()+'/IMG_5126.JPG'
    app.openURL_(nsurl(URL))
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        server.shutdown()
        print('Server stopped')
dgelessus

@cvp I think the BaseHTTPServer and SimpleHTTPServer modules were moved into a single http.server module in Python 3.

Out of curiosity, is there any reason to use UIApplication.sharedApplication().openURL_(nsurl(...)) instead of just webbrowser.open(...)? If you want to open the URL in the real Safari browser instead of Pythonista's built-in browser, you can use the fake safari-http and safari-https URL schemes. No need for objc_util. :)

Oh, and you can use localhost as the host name if you want to access the current device. localhost is always guaranteed to work, but the name returned by gethostname() sometimes doesn't, for example when you have no network connection.

donnieh

The goal is just to load a local .gif into Safari, nothing fancy. I have seen other apps do it using Openin (I think). I am trying to add the feature to my Pythonista script. I am not picky on how it is done. The shared application idea seems interesting...

If it is not likely to do this, I will just have to use a ui.webview() within the script.

cvp

It's more than interesting, it exactly does what you asked 😀

cvp

@dgelessus You're right but if I ask Pythonista to convert it into Python3, it uses http.server and the script has an execution error...

cvp

@donnieh I already have used the Workflow app to OpenIn a file directly in ONE app, without presenting a choice, and I had asked @omz why Pythonista can't do that...

donnieh

I am staying in Python 2. I have come so far in my learning and Python 3 seems to throw a wrench in it. :)

cvp

My error, conversion 2 to 3 is ok but I had left the #!python2 line, shame on me 😢

JonB

@donnieh another option might be encoding as a data: url.

donnieh

@JonB Is there a code example doing something similar?

JonB

stupid question... but what are you trying to achieve? Why not use the internal browser for this?

donnieh

@JonB I have an app almost ready to go on the AppStore. It is full of animated electronic circuit diagrams. If I added a feature for the gif diagram to be opened up in Safari, without much work I could have the save to camera roll, pinch to zoom, Workflows, and other share/extension functionality etc that safari has.

I do understand Pythonista can do all this, but I was going to do the Safari way for now to save time. Otherwise, I will suck it up and do all the in app code.

I will try the Objectice-C method. I very well could try the built in web browser, I can't argue that.

P.S. I also just realized imageview now animates gifs as where I don't think it worked a few years ago ( I think...).

dgelessus

If you want the user to be able to view, save and share the file, you could also use console.quicklook, console.open_in, or dialogs.share_image. Especially console.quicklook is very similar to what you would also achieve with Safari, with the advantage that you don't have to leave the app.

cvp

And you have also webview

import ui
import os
class MyView(ui.View):
    def __init__(self,w,h):
        self.width = w
        self.height = h

        wv = ui.WebView(frame=(0,0,w,h))
        doc_path = os.path.expanduser('~/Documents')
        file_path = os.path.join(doc_path,'IMG_5126.JPG') # your file name of course
        wv.load_url('file://'+file_path)
        self.add_subview(wv)

#w, h = ui.get_screen_size()
w, h = (540,620)
back = MyView(w, h)
back.present('sheet')
donnieh

Ok! That's sound legit. Thank you!