Download files with a SketchUp plugin
-
I've been attempting to find a way to download a file from a website within a SketchUp plugin but cannot find a decent solution.
Specifically, I am looking for:
- a way to download a file from a URL to the local machine
- a cross-platform solution (e.g. Windows AND Mac)
- working examples to reference
- the most elegant solution possible (in an ideal world...)
Does anyone know how this can be accomplished?
-
Look at
.load_from_url(urlpath)
- which should download the file...
You need to specify the details to be able to use the downloaded file afterwards... -
@tig said:
Look at .load_from_url(urlpath) - which should download the file...
You need to specify the details to be able to use the downloaded file afterwards...This method is part of Sketchup::DefinitionList and assumes you wish to open a skp file and add it to the model as a Sketchup::ComponentDefintion object.
@TIG: what happens when the file ext is not .skp ?? Does the method raise an exception ?
Also the method returns boolean, not a handle to the loaded object. -
@ishboo said:
I've been attempting to find a way to download a file from a website within a SketchUp plugin but cannot find a decent solution.
Does anyone know how this can be accomplished?
Dana... the Ruby library modules URI and it's classes, specifically URI::FTP were designed to do this.
URI::FTP has OpenURI::OpenRead mixed in, that adds open() and read() instance methods.
Doc: module URI
Doc: mixin OpenURI::OpenReadThe user will need a full Ruby install, and the path to ruby lib added to their $LOAD_PATH array.
See my load path setter:
[Code] Ruby LOAD PATHs script for Win32 -
@dan rathbun said:
...what happens when the file ext is not .skp ?? Does the method raise an exception ?
Also the method returns boolean, not a handle to the loaded object.You can find the file added as a SKP as -
model.definitions.to_a[-1]
- BUT it IS a most obtuse method! It should return true/false but not sure if you try with a non-SKP ??? -
OK.. BUT... this is not what Dana wants.
He's working on a plugin downloader / updater / web repository.
-
OK - then it's more complicated...
Something like this... in a webdialog using javascript... download the file as a base64 encoded stream of the server-side file's data to javascript, via an xmlhttprequest (ajax call etc). When it's in the javascript, then call your Ruby method, to decode that base64 string into a byte-array and save it to a file in the temp-directory on the PC.
After it's there you can rename/relocate/use it as needed... -
A few remarks:
-
There is no simple way to download binary files on IE or Safari via XmlHttpRequest. Ajax is however fine to download HTML page as plain text (this is what I used for the Check for Update feature)
-
File attachments on most web sites cannot be downloaded by program. This is the case on Sketchucation forum, even when you are logged in. This is due to security settings of these sites.
-
There is a method, portable on Windows and on Mac (based on Curl), which normally works for binary files. But again, it does not solve the problem of security settings above. If someone knows a web site where binary files can be freely downloaded by program, then you can test it by calling (assuming you have LibFredo6 3.7 installed)
Traductor.download_from_url url, local_file
Personally, I made my test on url = http://www.google.com/images/chrome_48.gif
I need some tweaks for Mac for the asynchronous mode, but it seems Ok in synchronous mode.
- In practice, I am not sure it is worth automating the download of plugins (the unzip is also possible from Ruby). It is preferable that users connect to the page, check the release note and then decide to install or not.
Fredo
-
-
Wow, thank you everyone for your responses!
Dan: Requiring users to have their own full Ruby install is not ideal for this purpose as the tool is meant to be general purpose and widely usable without configuration. I'd love it if we had a full Ruby to play with on both OSs, but sadly that is not the case... Is there a way to have a bundled install of Ruby within the plugin? Say an .exe for windows and a bundle for Mac? Is this doable?
TIG: Would this be possible with a .zip file or a stream of text/image files? How well is this supported on Win/Mac? Have you tried this within SketchUp before? I thought about doing such a thing but felt it may not be an elegant/robust enough solution... Would love to hear your opinion.
Fredo: The tool I am working on will allow users to browse the website (which is pretty much done) with a trimmed down interface, allowing them to view plugins, read release notes and reviews, check ratings and more; all within SketchUp. I already have most of this working and I also have most of the core features to install tools into isolated directories, check for and install updates, allow for uninstall (e.g. deletion of the code) and listing of installed plugins working. I of course need to do more tweaking/testing and improvement but I have a good chunk working now.
On another note, I have been trying to use your
Traductor.download_from_url url, local_file
method but cannot seem to get it to work. I have gotten it to return the path to where the file should be located but there is no file there. Is there something I am doing wrong:Traductor.download_from_url 'http://www.somesite.com/something.zip', '/path/to/something.zip'
... which is returning nil
I have tried using curl locally on my Mac similar to how your tool works:
curl -o something.zip http://somesite.com/something.zip
... which works just fine. So I am not clear what I am doing wrong...
Also, are you saying base64 encoding of a zip file would fail with JavaScript?
Thanks again for all the responses!
Dana -
@ishboo said:
Dan: Requiring users to have their own full Ruby install is not ideal for this purpose as the tool is meant to be general purpose and widely usable without configuration.
I am a firm believer in users always having a full Ruby install, regardless of platform, to support all plugins, not just your plugin manager.
@ishboo said:
I'd love it if we had a full Ruby to play with on both OSs, but sadly that is not the case... Is there a way to have a bundled install of Ruby within the plugin? Say an .exe for windows and a bundle for Mac? Is this doable?
All Macs come with a full Ruby install "out of the box", the issue is however, that the full install is in most cases a much newer version and patch level than the old framworkized initial release of Ruby v1.8.5 that Mac Sketchup uses. (Upgrading the Sketchup Mac edition to load a newer Ruby is problematic. It seems that on Mac, [and I am not an expert in this area,] that the Sketchup Ruby API extensions are statically linked against this old 1.8.5-p0 Ruby framework. It would be nice if Mac users could force Sketchup to load a newer ruby version, but as a worst case, perhaps the missing 1.8.5 library files could copied into the framework dirs.)
Windows however is simple. There is already a one-click installer for Ruby 1.8.6-p287, the version & patch level that Sketchup 8 uses. (It's also simple on Windows to cause older Sketchup versions to load this version by replacing the msvcrt-ruby18.dll in the Sketchup dir with the file that ships in the bin dir of the full Ruby install, or the file that comes with Sketchup 8.)
Ruby (v1.8.6-p287) Windows One-Click Installer (25Mb)
I think the size of the installer is too large to bundle into your manager zip... better to just have the installer as a separate required download (which you could mirror on your website.) -
Dana,
The method is anyway based on Curl, which, on Mac, is part of the system utilities.
My code is just encapsulating it (and making it work for Windows) but it is not yet finished on Mac, as I did not really test it.If curl -o something.zip http://somesite.com/something.zip, then try to make it a string
cmd
and execute it from Ruby viasystem(cmd)
[note: you may need to put extra double quotes around the arguments) and tell me if it works.Fredo
-
Fredo,
the best I can offer for 10.5.8 (at least) is
system("curl -O http://homepage.mac.com/johnboundy/filechute/homer%20instal.dmg.zip open /homer%20instal.dmg.zip") system("osascript -e 'tell application \"Finder\"' -e 'activate' -e 'end tell'")
this downloads the zip, opens it (in the HD:) and then brings it to the front by opening Finder...
You can then click it to open for instal.Locally, I can open the .dmg fully with a single script in Terminal, but not through SU
I'll have a play later.
BTW: the file is just Jim's 'homer' [yell if you object Jim] in a wrapper if you want something to test download
john
-
Fredo: Thank you! This is what I needed! Finally got downloading working on both Mac and PC. For Mac I ended up doing something like:
system("curl -L -o \"/home/user/somefile.txt\" http://www.somesite.com/somefile.txt")
Using the -L option follows redirects so if the download link was something like http://www.somesite.com/download/?id=123 it would follow the download redirect, which comes in handy. Having the local filesystem URL in quotes helped, and wasn't needed for the URL. On windows, instead of calling curl I called the path to the curl_win.exe file that Fredo has in LibFredo6 3.7.
I finally have a working plugin installer tool! It downloads and install plugins from my website as well as from local files. It even handles uninstall with a restart. I'll update when I have something for people to try out!
Dan: I agree all users "should" have a full Ruby install but the harsh reality is that they don't and many users are not technical enough to install it. My tool needs to work "out of the box" and the curl solution allows for this. Also, the fact that the Ruby installer could not be bundled with my app is another reason I don't think that route will work for me. Thanks you for the suggestions though, I am sure they will come in handy in the future.
driven: Thanks for that. Luckily I found a workaround for downloading/extracting a zip, but I like the trick.
Cheers,
Dana -
@unknownuser said:
It would be nice if Mac users could force Sketchup to load a newer ruby version
I "upgraded" my Sketchup Ruby to 1.8.7 using this trick
I think it is more easy to create an extensions (PC/Mac) which downloads the file from a given URL (with redirect and authentification) than packaging curl
-
@ishboo said:
Dan: I agree all users "should" have a full Ruby install but the harsh reality is that they don't and many users are not technical enough to install it.
Does not make sense.
If many users are not technical enough to run a one-click installer executable, how are they technical enough to install your package?
And.. didn't they succeed in downloading and installing Sketchup's one-click installer executable despite their lack of technical skill?
-
And by the way.. pik (which is the Win32 equivalent of RVM,) uses the 7za.exe command line executable. (The file must be in the path environment var, or use an absolute path.)
There's also a DLL version. It's Free OpenSource, under GNU LPGL.
Command line versions are available for Win, Unix, Linux, OSX, etc.
http://www.7-zip.org/download.html -
@dan rathbun said:
Does not make sense.
If many users are not technical enough to run a one-click installer executable, how are they technical enough to install your package?
And.. didn't they succeed in downloading and installing Sketchup's one-click installer executable despite their lack of technical skill?
It does make sense. I was not talking about Window's one-click install but the hacking required to get it working on a Mac.
Also, having to require users to download a 25mb file and install it just to use my plugin is not acceptable in my eyes. I want this plugin to work on most systems by default, without any mucking around and dependencies.
@dan rathbun said:
And by the way.. pik (which is the Win32 equivalent of RVM,) uses the 7za.exe command line executable. (The file must be in the path environment var, or use an absolute path.)
There's also a DLL version. It's Free OpenSource, under GNU LPGL.
Command line versions are available for Win, Unix, Linux, OSX, etc.
http://www.7-zip.org/download.htmlSo this would be to extract a zip then? I got around local extraction because I do that server side and pull each file in manually, but would be interesting in case I change my mind or need that behavior in another plugin.
@unknownuser said:
I "upgraded" my Sketchup Ruby to 1.8.7 using this [url=http://stackoverflow.com/questions/3333163/how-to-update-ruby-in-google-sketchup:38tqxa52]trick[/url:38tqxa52]
Thanks for the link, if I need to upgrade I'll have to check that out.
@unknownuser said:
I think it is more easy to create an extensions (PC/Mac) which downloads the file from a given URL (with redirect and authentification) than packaging curl
Do you have an example of an extension that would download a file from the web? I asked around and searched quite a lot to no avail. Also, by extension, do you mean a C/C++ extension (I'm assuming so...)?
It seems like curl works fine for this use case (since it is working already and requires only a few lines of code and a very small .exe file). If there is a good reason to go with something else I'd love to hear it... Why do you think it is more easy to create an extension?
Thanks for all your replies guys!
-
pros for C/C++ ruby extension
• you can download directly to memory without the need to save to disk first
• no need to spawn to command line - faster
• provide a progress bar / cancel without the need to poll curl output
• smaller package sizecons
• must code it -
@unknownuser said:
pros for C/C++ ruby extension
• you can download directly to memory without the need to save to disk first
• no need to spawn to command line - faster
• provide a progress bar / cancel without the need to poll curl output
• smaller package sizecons
• must code itHow easy/hard is it to make it cross-*platform?
-
@thomthom said:
@unknownuser said:
pros for C/C++ ruby extension
• you can download directly to memory without the need to save to disk first
• no need to spawn to command line - faster
• provide a progress bar / cancel without the need to poll curl output
• smaller package sizecons
• must code itHow easy/hard is it to make it cross-*platform?
I'd also like to know this. Also would love to know if there is any open-source code or tutorials out there about how to make such an extension.
I am lacking in C knowledge and doing something like this would be a rather difficult task for me at this point.
Any info would be appreciated.
Cheers,
Dana
Advertisement