diff options
author | Filipp Lepalaan <filipp@mekanisti.fi> | 2009-12-28 22:02:04 +0200 |
---|---|---|
committer | Filipp Lepalaan <filipp@mekanisti.fi> | 2009-12-28 22:02:04 +0200 |
commit | 9845988e5e3cc1bec0ae98476f04b46dabc94f5a (patch) | |
tree | 7dde2a03a6059da790d5832f5730f229042ef134 | |
download | FinalStore-9845988e5e3cc1bec0ae98476f04b46dabc94f5a.tar.gz FinalStore-9845988e5e3cc1bec0ae98476f04b46dabc94f5a.tar.bz2 FinalStore-9845988e5e3cc1bec0ae98476f04b46dabc94f5a.zip |
First commit
-rw-r--r-- | README | 25 | ||||
-rwxr-xr-x | archive.sh | 8 | ||||
-rwxr-xr-x | awcli.sh | 138 | ||||
-rw-r--r-- | config.py | 7 | ||||
-rw-r--r-- | config.pyc | bin | 0 -> 320 bytes | |||
-rw-r--r-- | fcs.png | bin | 0 -> 354418 bytes | |||
-rwxr-xr-x | finalstore.py | 79 | ||||
-rw-r--r-- | presscut.pyc | bin | 0 -> 2831 bytes | |||
-rwxr-xr-x | restore.sh | 8 |
9 files changed, 265 insertions, 0 deletions
@@ -0,0 +1,25 @@ +## How it works ## +### Archive ### +- User selects assets in FCSvr and clicks Archive. FCSvr moves the asset to it's +Archive Device and marks it as archived +- archive.sh writes the file paths to /tmp/fcs_toArchive +- launchd job (fi.tvtools.finalstore) runs runner.py every n seconds +- finalstore.py forwards the file list to a customized awcli.sh, waits for the job +to finish and runs growlnotify to let the user know of what happened + +### Restore ### +- User selects assets in FCSvr and clicks Restore. +- restore.sh writes the file paths to /tmp/fcs_toRestore +- launchd job (fi.tvtools.finalstore) runs finalstore.py every n seconds +- finalstore.py forwards the file list to a customized awcli.sh, waits for the job +to finish and runs growlnotify to let the user know what happened + +## Installation ## + +- Drag the finalstore folder to /Library/Application Support/TV Tools/finalstore +- In FCSvr, open Administration > Devices > Archive and set the pahts of the archive and restore +scripts +- Configure your PressSTORE archive plan + +##Configuration## +... diff --git a/archive.sh b/archive.sh new file mode 100755 index 0000000..7b8f8be --- /dev/null +++ b/archive.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Collect archived assets to a text file +DST="/tmp/finalstore/archive" +if [ ! -d $DST ]; then + mkdir -p $DST +fi +echo $1 >> "${DST}/$(date +'%s').txt" +exit 0 diff --git a/awcli.sh b/awcli.sh new file mode 100755 index 0000000..e682ebc --- /dev/null +++ b/awcli.sh @@ -0,0 +1,138 @@ +#!/bin/sh +# This is a modified version of awcli.sh that comes bundled with PresSTORE +# The differences are: +# - returning the Job ID +# - support for servers running on other hosts +# +# See the file "license.txt" for information on usage and +# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. + +# +# Override locale settings +# + +source /Library/Application\ Support/TV\ Tools/FinalStore/config.py + +LC_ALL="C"; export LC_ALL + +usage() { + echo "usage: $0 [archive | restore] plan_name file1 file2 ... fileN" + exit 1 +} +clierr() { + echo "`$nc -c geterror`" + exit 1 +} + +# +# Locate the nsdchat utility +# + +if test -z "$AWPST_HOME"; then + nc="${NC} -s awsock:/${USER}:${PASSWORD}@${HOST}:9001" +else + nc=$AWPST_HOME/bin/nsdchat +fi + +# +# Check the operation. +# + +task="$1" +if test "$task" != "archive" -a "$task" != "restore"; then + usage +fi + +# +# Check the name of the Archive plan to use +# Bail-out if the plan is missing +# + +shift +aplan="$1" +dummy=`$nc -c ArchivePlan $aplan describe` +if test $? -ne 0; then + echo "$0: archive plan $aplan not found" + exit 1 +fi + +# +# Refuse to work when no files given +# + +shift +if test "$#" -eq 0; then + echo "$0 no files to $task" + exit 1 +fi + +# +# Now do the archive or restore task +# + +case $task in + archive) + # Create archive selection object + as=`$nc -c ArchiveSelection create localhost $aplan` + if test $? -ne 0; then + clierr + fi + # Add files to it + adfile=0 + for file do + if test ! -r "$file"; then + echo "$0: $file: no such file" + elif test ! -f "$file"; then + echo "$0: $file: not a plain file" + else + aentry=`$nc -c ArchiveSelection $as addentry "{$file}"` + if test $? -ne 0; then + clierr + fi + adfile=`expr $adfile + 1` + fi + done + # Submit archive job + if test $adfile -eq 0; then + echo "$0: no files selected for $task" + else + jobid=`$nc -c ArchiveSelection $as submit 1` + echo $jobid + if test $? -ne 0; then + clierr + fi + fi + ;; + + restore) + # Get the database for the given plan + dbase=`$nc -c ArchivePlan $aplan database` + if test $? -ne 0; then + clierr + fi + # Create restore selection object + rs=`$nc -c RestoreSelection create localhost` + if test $? -ne 0; then + clierr + fi + # Add files to it + for file do + aentry=`$nc -c ArchiveEntry handle localhost "{$file}" $dbase` + if test $? -ne 0; then + clierr + fi + apath=`$nc -c RestoreSelection $rs addentry $aentry` + if test $? -ne 0; then + clierr + fi + done + # Submit the restore job + jobid=`$nc -c RestoreSelection $rs submit 1` + echo $jobid + if test $? -ne 0; then + clierr + fi + ;; +esac + +exit 0 diff --git a/config.py b/config.py new file mode 100644 index 0000000..2ca0313 --- /dev/null +++ b/config.py @@ -0,0 +1,7 @@ +# This file is shared between Bash and Python +# so keep it clean! +USER="" +HOST="" +ARCHIVEPLAN="10001" +PASSWORD="" +NC="/usr/local/aw/bin/nsdchat" diff --git a/config.pyc b/config.pyc Binary files differBinary files differnew file mode 100644 index 0000000..d9e6926 --- /dev/null +++ b/config.pyc diff --git a/finalstore.py b/finalstore.py new file mode 100755 index 0000000..40e5bf4 --- /dev/null +++ b/finalstore.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python -Wall +# This is only run from launchd +# @author Filipp Lepalaan <filipp@tvtools.fi> +# @updated 10.12.2009 +# @created 09.12.2009 + +import sys, time, os, glob, traceback +from config import * +from subprocess import * + +""" + Time saver for posting Growl notifications +""" +def growl(str): + icon = sys.path[0] + "/fcs.png" + cmd = ["/usr/local/bin/growlnotify", "-s", "-m", str, "--image", icon] + try: + Popen(cmd, shell=False).communicate() + except Exception, e: + print "Growl failed" + + +""" + Forward the files to awcli + Wait for presstore to finish +""" +def doit(task, f, ap): + assets = [] + # Gather up all the assets marked for processing + for l in f.readlines(): + s = l.strip() + print "Processing " + l + if not s: break + assets.append(s) + + # Get rid of these as soon as possible + f.close() + os.unlink(f.name) + + awcli = sys.path[0] + "/awcli.sh" + r = Popen([awcli, task, ap] + assets, stdout=PIPE, shell=False).communicate() + jid = r[0].strip() + + print task + " job ID is " + jid + growl("Started %s job %s (%d assets)" % (task, jid, len(assets))) + + # Wait for the job to finish + sock = "awsock:/%s:%s@%s:9001" % (USER, PASSWORD, HOST) + cmd = "Job %s status" % (jid) + + while True: + try: + check = Popen([NC, "-s", sock , "-c", cmd], stdout=PIPE, shell=False) + s = check.communicate()[0].strip() + except Exception, e: + print traceback.print_exc(file=sys.stdout) + if s == "completed" or s == "cancelled" : break + time.sleep(2) + + growl("%s %s job %s" % (s.capitalize(), task, jid)) + +# DO IT +try: + for f in glob.glob("/tmp/finalstore/archive/*.txt"): + d = open(f, "r") + doit("archive", d, ARCHIVEPLAN) +except Exception, e: + print "Nothing to archive" + +try: + for f in glob.glob("/tmp/finalstore/restore/*.txt"): + d = open(f, "r") + doit("restore", d, ARCHIVEPLAN) +except Exception, e: + print "Nothing ro restore" + +# To not upset launchd +time.sleep(5) +sys.exit(0) diff --git a/presscut.pyc b/presscut.pyc Binary files differnew file mode 100644 index 0000000..80a4617 --- /dev/null +++ b/presscut.pyc diff --git a/restore.sh b/restore.sh new file mode 100755 index 0000000..1443eed --- /dev/null +++ b/restore.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Collect restored assets to a text file +DST="/tmp/finalstore/restore" +if [ ! -d $DST ]; then + mkdir -p $DST +fi +echo $1 >> "${DST}/$(date +'%s').txt" +exit 0 |