From: <tom...@us...> - 2008-09-26 23:55:20
|
Revision: 10522 http://amsn.svn.sourceforge.net/amsn/?rev=10522&view=rev Author: tomhennigan Date: 2008-09-26 23:55:14 +0000 (Fri, 26 Sep 2008) Log Message: ----------- In response to this post: http://www.amsn-project.net/forums/viewtopic.php?t=5273 I present a very simplistic amsn-extras package. This provides an API to install skins and plugins. Currently only the mac decompression routines have been added, but the others can easily be added. (see os_base.tcl) On OS X a user can drop a skin or plugin archive or directory onto the aMSN dock icon, and extras will install it. Tests are performed to determine if the directory (contained in an archive perhaps) is a valid skin/plugin. To test: pacakge require amsnextras ::extras::install path_to_folder (on os x this could also be a tar or gz archive) Added Paths: ----------- trunk/amsn/utils/amsn-extras/ trunk/amsn/utils/amsn-extras/extras.tcl trunk/amsn/utils/amsn-extras/os_base.tcl trunk/amsn/utils/amsn-extras/os_mac.tcl trunk/amsn/utils/amsn-extras/pkgIndex.tcl Added: trunk/amsn/utils/amsn-extras/extras.tcl =================================================================== --- trunk/amsn/utils/amsn-extras/extras.tcl (rev 0) +++ trunk/amsn/utils/amsn-extras/extras.tcl 2008-09-26 23:55:14 UTC (rev 10522) @@ -0,0 +1,112 @@ + +# amsn-extras +# Provides an interface to manipulate extras for amsn, such as installing plugins or skins +# ::extras::os +# - Provides a filesystem API to move/copy/delete files and folders. +# - Also provides decompression routines for the file extensions supported on the host system. + +namespace eval ::extras { + proc init { dir } { + source [file join $dir os_base.tcl] + if { [OnMac] } { + source [file join $dir os_mac.tcl] + } + } + + proc install { file_path } { + return [after 0 [list [namespace current]::installAsync $file_path]] + } + + proc installAsync { file_path } { + # Sanity check. + if {![file exists $file_path]} { + return 0 + } + + # Original archive should be deleted. + # Archive, decompress before testing for plugin/skin + set extns $::extras::os::supportedCompressedExtensions + + #set temp_dir "" + #if {[file isfile $file_path]} { + # set temp_dir [::extras::os::tempdir] + # ::extras::os::copyFile $file_path $temp_dir + # set file_path [file join $temp_dir [lindex [file split $file_path] end]] + #} + + while {![file isdirectory $file_path]} { + set file_path [::extras::os::decompress $file_path] + if { $file_path == "" } { + status_log "::extras::install: error decompressing file" red + return 0 + } + } + + if {![file exists $file_path]} { + # The arcive was decompressed, but we can't find the unarchive dir. + # The user should be notified that they can retry by installing the now decompressed folder. + status_log "::extras::install: error finding correctly decompressed archive ($file_path)" red + return 0 + } + + # We have a folder! So now detect skin or plugin, and install it! + set sop [testSkinOrPlugin $file_path] + + if { $sop == "invalid" } { + # Err, what are you doing!? + status_log "::extras::install: invalid pluign or skin file" red + return 0 + } + + # IE. ~/.amsn + set install_base [::extras::os::getaMSNDir] + + if { $sop == "skin" } { + # ~/.amsn/skins + set install_base [file join $install_base skins] + } elseif { $sop == "plugin" } { + # ~/.amsn/plugins + set install_base [file join $install_base plugins] + } else { + status_log "::extras::install: unhandled known type $sop \[shouldn't happen?!\]" + return 0 + } + + # Performs the actual install. + if {[catch { + status_log "::extras::install: installing $sop into $install_base" + [namespace current]::os::moveFolder $file_path $install_base + } err]} { + status_log "::extras::install error: $err" red + return 0 + } + + return 1 + } + + # @return (string){skin|plugin|invalid} + proc testSkinOrPlugin { folder_path } { + # Tests should be a list of tests to validate a particular type. + # Each test should be a subcommand of file (IE. isfile) followed by the file to test + set tests [list \ + skin [list isfile settings.xml isdirectory pixmaps] \ + plugin [list isfile plugininfo.xml] \ + ] + + # Test each type. + foreach {type file_tests} $tests { + set r 1 + foreach {test file} $file_tests { + if {![file $test [file join $folder_path $file]]} { + set r 0 + break + } + } + if { $r == 1 } { + return $type + } + } + + return "invalid" + } +} Added: trunk/amsn/utils/amsn-extras/os_base.tcl =================================================================== --- trunk/amsn/utils/amsn-extras/os_base.tcl (rev 0) +++ trunk/amsn/utils/amsn-extras/os_base.tcl 2008-09-26 23:55:14 UTC (rev 10522) @@ -0,0 +1,79 @@ + +namespace eval ::extras::os { + set ::extras::os::supportedCompressedExtensions [list] + + # Returns the path to the folder in which to install the plugins and skins. IE. ~/.amsn on linux + proc getaMSNDir {} { + return "~/.amsn" + } + + # Should NOT be recursive to work with multiple levels of compression, IE. tar.gz + # This will be handled by ::extras + # Decompression routines should be defined as: + # proc decompress.extension { compressed_file } { return decompressed_file or "" } + # @return: (string)path_to_folder or "" if not successful + proc decompress { file_path } { + set ext [file extension $file_path] + if {![file exists $file_path]} { + return "" + } + + if {[file isdirectory $file_path]} { + return $file_path + } + + if {[lsearch $::extras::os::supportedCompressedExtensions $ext] == -1} { + status_log "::extras::os::decompress: extension ($ext) not supported" + return "" + } + + status_log "::extras::os::decompress: ($ext) $file_path" red + + if {[catch { + set file_path [decompress${ext} $file_path] + } res]} { + status_log "::extras::os::decompress: error decompressing ($ext): $res" red + set file_path "" + } + + return $file_path + } + + # Functions to move files around. + proc copyFile { old_file new_file } { + file copy -force -- $old_file $new_file + } + proc moveFile { old_file new_file } { + copyFile $old_file $new_file + deleteFile $old_file + } + # @return: (bool)success + proc deleteFile { file_path } { + if {[file exists $file_path]} { + file delete -- $file_path + } + } + + # Functions to move folders around. + proc copyFolder { old_folder new_parent } { + copyFile $old_folder $new_parent + deleteFolder $old_folder + } + proc moveFolder { old_folder new_parent } { + deleteFolder [file join $new_parent [lindex [file split $old_folder] end]] + copyFolder $old_folder $new_parent + deleteFolder $old_folder + } + # @return: (bool)success + proc deleteFolder { folder_path } { + if {[file exists $folder_path]} { + file delete -force -- $folder_path + } + } + + # Functions to make temporary writable files and folders. + # @return: (string)path to temp folder + proc tempdir {} { return "" } + # @return: (string)path to temp file + proc tempfile {} { return "" } +} Added: trunk/amsn/utils/amsn-extras/os_mac.tcl =================================================================== --- trunk/amsn/utils/amsn-extras/os_mac.tcl (rev 0) +++ trunk/amsn/utils/amsn-extras/os_mac.tcl 2008-09-26 23:55:14 UTC (rev 10522) @@ -0,0 +1,40 @@ + +# todo: +# - add zip handler +# - fix return name of tar and gz (currently assuming that the return is the same as parent - the extension) + +# This handler lets us install documents dropped onto the application's icon in the dock. +proc ::tk::mac::OpenDocument { file } { + ::extras::install $file +} + +namespace eval ::extras::os { + set ::extras::os::supportedCompressedExtensions [list ".tar" ".gz" ".tgz"] + + proc getaMSNDir {} { + global env + return [file join $env(HOME) Library "Application Support" amsn] + } + + proc decompress.tgz { file_path } { + exec tar -C [file dirname $file_path] -xzf $file_path + deleteFile $file_path + return [file rootname $file_path] + } + proc decompress.tar { file_path } { + exec tar -C [file dirname $file_path] -xf $file_path + deleteFile $file_path + return [file rootname $file_path] + } + proc decompress.gz { file_path } { + exec gzip -d $file_path + return [file rootname $file_path] + } + + proc tempdir {} { + return [exec mktemp -d -t amsn-extras] + } + proc tempfile {} { + return [exec mktemp -t amsn-extras] + } +} Added: trunk/amsn/utils/amsn-extras/pkgIndex.tcl =================================================================== --- trunk/amsn/utils/amsn-extras/pkgIndex.tcl (rev 0) +++ trunk/amsn/utils/amsn-extras/pkgIndex.tcl 2008-09-26 23:55:14 UTC (rev 10522) @@ -0,0 +1,5 @@ + +set name "amsnextras" +set vers 0.1 + +package ifneeded $name $vers "[list source [file join $dir extras.tcl]]; [list ::extras::init $dir]; [list package provide $name $vers]" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |