aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilipp Lepalaan <filipp@mekanisti.fi>2009-12-28 22:02:04 +0200
committerFilipp Lepalaan <filipp@mekanisti.fi>2009-12-28 22:02:04 +0200
commit9845988e5e3cc1bec0ae98476f04b46dabc94f5a (patch)
tree7dde2a03a6059da790d5832f5730f229042ef134
downloadFinalStore-9845988e5e3cc1bec0ae98476f04b46dabc94f5a.tar.gz
FinalStore-9845988e5e3cc1bec0ae98476f04b46dabc94f5a.tar.bz2
FinalStore-9845988e5e3cc1bec0ae98476f04b46dabc94f5a.zip
First commit
-rw-r--r--README25
-rwxr-xr-xarchive.sh8
-rwxr-xr-xawcli.sh138
-rw-r--r--config.py7
-rw-r--r--config.pycbin0 -> 320 bytes
-rw-r--r--fcs.pngbin0 -> 354418 bytes
-rwxr-xr-xfinalstore.py79
-rw-r--r--presscut.pycbin0 -> 2831 bytes
-rwxr-xr-xrestore.sh8
9 files changed, 265 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..e85cbd3
--- /dev/null
+++ b/README
@@ -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
new file mode 100644
index 0000000..d9e6926
--- /dev/null
+++ b/config.pyc
Binary files differ
diff --git a/fcs.png b/fcs.png
new file mode 100644
index 0000000..0448a99
--- /dev/null
+++ b/fcs.png
Binary files differ
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
new file mode 100644
index 0000000..80a4617
--- /dev/null
+++ b/presscut.pyc
Binary files differ
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