'From etoys2.3 of 3 December 2007 [latest update: #1874] on 18 January 2008 at 6:59:17 pm'! "Change Set: xoBundle-bf Date: 17 January 2008 Author: Bert Freudenberg Make an OLPC XO bundle. To use, select a .pr or .st file in file list and choose 'make XO bundle' which will be placed in the default directory. The created bundle will only run correctly in an image that has this changeset loaded."! !SugarLauncher methodsFor: 'commands' stamp: 'bf 1/18/2008 15:37'! welcome: aUrl "Sent either when running from Sugar, or at regular startUp otherwise" aUrl isEmpty ifFalse: [ | url | url := (aUrl includes: $/) ifTrue: [aUrl] ifFalse: ['file:', (parameters at: 'BUNDLE_PATH'), '/', aUrl]. ^(url endsWith: '.pr') ifTrue: [Project fromUrl: url] ifFalse: [WorldState addDeferredUIMessage: [FileStream fileIn: (url copyAfter: $:)]]]. "only enter launcher if no script given on cmd line" ((SmalltalkImage current getSystemAttribute: 2) ifNil: ['']) ifNotEmpty: [^self]. Preferences eToyFriendly ifTrue: [ (Project named: 'Etoys Activity') ifNotNilDo: [:p | p enter]].! ! !SugarLauncher methodsFor: 'bundling' stamp: 'bf 1/17/2008 17:21'! bundleIcon ^self bundleIconTemplate replaceAll: Character cr with: Character lf! ! !SugarLauncher methodsFor: 'bundling' stamp: 'bf 1/17/2008 16:22'! bundleIconTemplate "template for activity/icon.svg" ^' ]> '! ! !SugarLauncher methodsFor: 'bundling' stamp: 'bf 1/17/2008 17:38'! bundleInfoTemplate "template for activity/activity.info" ^'[Activity] name = {TITLE} activity_version = {VERSION} host_version = 1 bundle_id = {BUNDLE} icon = {ICON} exec = etoys-launch --uri {FILE} show_launcher = yes '! ! !SugarLauncher methodsFor: 'bundling' stamp: 'bf 1/17/2008 17:40'! bundleInfoTitle: aTitle version: aVersion bundle: aBundle file: aFileName icon: anIconName | s | s := self bundleInfoTemplate. { '{TITLE}'. aTitle. '{VERSION}'. aVersion asString. '{BUNDLE}'. aBundle. '{ICON}'. anIconName. '{FILE}'. aFileName. String cr. String lf. } pairsDo: [:key :val | s := s copyReplaceAll: key with: val]. ^s! ! !SugarLauncher methodsFor: 'bundling' stamp: 'bf 1/17/2008 17:21'! bundleScript ^self bundleScriptTemplate replaceAll: Character cr with: Character lf! ! !SugarLauncher methodsFor: 'bundling' stamp: 'bf 1/17/2008 16:29'! bundleScriptTemplate "template for MyActivity.activity/bin/etoys-launch" ^'#!!/bin/sh # Author: Bert Freudenberg # Purpose: Run Etoys using the Squeak virtual machine # arguments are unordered, have to loop args="" while [ -n "$2" ] ; do case "$1" in -b | --bundle-id) bundle_id="$2" ; args="$args BUNDLE_ID $2" ;; -a | --activity-id) activity_id="$2" ; args="$args ACTIVITY_ID $2";; -o | --object-id) object_id="$2" ; args="$args OBJECT_ID $2";; -u | --uri) uri="$2" ; args="$args URI $2";; *) echo unknown argument $1 $2 ;; esac shift;shift done # really need bundle id and activity id if [ -z "$bundle_id" -o -z "$activity_id" ] ; then echo ERROR: bundle-id and activity-id arguments required echo Aborting exit 1 fi # more useful args args="$args BUNDLE_PATH $SUGAR_BUNDLE_PATH" # some debug output echo launching $bundle_id instance $activity_id [ -n "$object_id" ] && echo with journal obj $object_id [ -n "$uri" ] && echo loading uri $uri echo # sanitize [ -z "$SUGAR_PROFILE" ] && SUGAR_PROFILE=default [ -z "$SUGAR_ACTIVITY_ROOT" ] && SUGAR_ACTIVITY_ROOT="$HOME/.sugar/$SUGAR_PROFILE/etoys" # rainbow-enforced locations export SQUEAK_SECUREDIR="$SUGAR_ACTIVITY_ROOT/data/private" export SQUEAK_USERDIR="$SUGAR_ACTIVITY_ROOT/data/MyEtoys" # make group-writable for rainbow umask 0002 [ !! -d "$SQUEAK_SECUREDIR" ] && mkdir -p "$SQUEAK_SECUREDIR" && chmod o-rwx "$SQUEAK_SECUREDIR" [ !! -d "$SQUEAK_USERDIR" ] && mkdir -p "$SQUEAK_USERDIR" # do not crash on dbus errors export DBUS_FATAL_WARNINGS=0 # now run Squeak VM with Etoys image exec etoys \ -sugarBundleId $bundle_id \ -sugarActivityId $activity_id \ $args '! ! !SugarLauncher methodsFor: 'bundling' stamp: 'bf 1/18/2008 18:52'! bundle: aFileName | localName nameAndVersion cleanName | localName := (FileDirectory localNameFor: aFileName) copyUpToLast: $.. nameAndVersion := localName stemAndNumericSuffix. cleanName := nameAndVersion first select: [:c | c isAlphaNumeric]. ^self bundle: aFileName as: cleanName title: nameAndVersion first version: (nameAndVersion second max: 1) id: 'org.squeak.', cleanName icon: self bundleIcon ! ! !SugarLauncher methodsFor: 'bundling' stamp: 'bf 1/18/2008 18:01'! bundle: aFileName as: aBundleName title: aTitle version: aVersion id: aBundleID icon: anSVGIcon "Create a ZIP file named aBundleName-aVersion.xo containing aBundleName.activity/ aFileName bin/etoys-launch activity/activity.info activity/aBundleName-icon.svg " | dir archive fileAttr execAttr dirAttr localFileName | fileAttr := 16r81A4. execAttr := 16r81ED. dirAttr := 16r41ED. dir := aBundleName, '.activity/'. localFileName := FileDirectory localNameFor: aFileName. archive := ZipArchive new. #('' 'bin' 'activity') do: [:dirName | (archive addDirectory: dir, dirName) unixFileAttributes: dirAttr]. (archive addFile: aFileName as: dir, localFileName) unixFileAttributes: fileAttr. (archive addString: self bundleScript as: dir, 'bin/etoys-launch') unixFileAttributes: execAttr. (archive addString: (self bundleInfoTitle: aTitle version: aVersion bundle: aBundleID file: localFileName icon: aBundleName, '-icon') as: dir, 'activity/activity.info') unixFileAttributes: fileAttr. (archive addString: self bundleIcon as: dir, 'activity/', aBundleName, '-icon.svg') unixFileAttributes: fileAttr. archive members do: [:m | m setLastModFileDateTimeFrom: Time totalSeconds]. archive writeToFileNamed: aBundleName, '-', aVersion asString, '.xo'. archive close.! ! !SugarLauncher methodsFor: 'accessing' stamp: 'bf 1/17/2008 15:40'! bundlePath ^parameters at: 'BUNDLE_PATH' ifAbsent: [FileDirectory default pathName]! ! !SugarLauncher class methodsFor: 'class initialization' stamp: 'bf 1/18/2008 18:13'! initialize "self initialize" FileList registerFileReader: self. "Our startUp is handled by AutoStart, but not shutDown" Smalltalk addToShutDownList: self after: AutoStart! ! !SugarLauncher class methodsFor: 'services' stamp: 'bf 1/18/2008 18:08'! fileReaderServicesForFile: fullName suffix: suffix ^({ 'pr'. 'st'. 'cs'. '*' } includes: suffix) ifTrue: [self services] ifFalse: [#()]! ! !SugarLauncher class methodsFor: 'services' stamp: 'bf 1/18/2008 18:10'! services ^ {self serviceWrapAsXOBundle}! ! !SugarLauncher class methodsFor: 'services' stamp: 'bf 1/18/2008 18:18'! serviceWrapAsXOBundle "Answer a service for wrapping a file as an .xo bundle" ^ FileModifyingSimpleServiceEntry provider: self label: 'make XO bundle' selector: #wrapAsXOBundle: description: 'wrap as an OLPC XO bundle' buttonLabel: 'XO'! ! !SugarLauncher class methodsFor: 'services' stamp: 'bf 1/18/2008 18:59'! wrapAsXOBundle: aFileName Utilities informUser: 'Making bundle' translated during: [Cursor wait showWhile: [self current bundle: aFileName]]! ! SugarLauncher initialize! !SugarLauncher class reorganize! ('utilities' compileDBusMessageRegistry defaultDatastoreDirName) ('accessing' current) ('testing' isRunningInRainbow isRunningInSugar) ('class initialization' initialize shutDown) ('services' fileReaderServicesForFile:suffix: services serviceWrapAsXOBundle wrapAsXOBundle:) ! !SugarLauncher reorganize! ('running' shutDown startUp) ('commands' active: join quit save share takeScreenshot welcome:) ('bundling' bundleIcon bundleIconTemplate bundleInfoTemplate bundleInfoTitle:version:bundle:file:icon: bundleScript bundleScriptTemplate bundle: bundle:as:title:version:id:icon:) ('accessing' buddies bundlePath ownerBuddy) ('dbus' dbusMessageRegistry dbusSignalRegistry dispatchDBusMessage: handleActivitySetActive: handleBuddyJoined: handleBuddyLeft: handleDBusIntrospect: handleTakeScreenshot: introspect runDBusService: sendDBusMessage: sendDBusMessage:onSuccess:onError: sendDBusMessage:timeout:) ('events' windowEvent:) ('datastore' createJournalEntryFor:filename:mimetype: findJournalEntries: getFilename: getFile: getProperties: handleStream:mimetype:titled: makeJournalEntryFor:filename:mimetype: propertiesFrom: resumeJournalEntry: titleFromProject: updateJournalEntry: updateJournalEntry:for:filename:mimetype:) ('presence' badgeHolder buddyFromPath: buddyJoined: buddyLeft: enableSharedActivitySignals getSharedActivityBuddies getSharedActivityById: getSharedActivityProperties joinSharedActivity leaveSharedActivity makeBadges ownerFromDBus setSharedActivityProperties: shareActivityId:bundleId:name:properties:) ('telepathy') ('testing' isRunningInRainbow isRunningInSugar isShared) !