Q: anyone working on...
anyone working on a Filemaker module for FCS?
Something that reads and writes metadata?
It would be great to set up job tracking in Filemaker with
a FCS database connected.
Something that reads and writes metadata?
It would be great to set up job tracking in Filemaker with
a FCS database connected.
MacPro(s), Mac OS X (10.6.4), FCS, Maya, CS5
Posted on Oct 29, 2010 10:16 AM
by Jim Mellor,Solvedanswer
There are a few ways of doing this. Perhaps the simplest to implement is to use XML files exchanged between applications. Conveniently Filemaker allows for XML import and export to be made using XSLT files which can be used to translate from one type of XML to another. These action can be scripted to ensure the process remains automated. Filemaker can also talk to AppleScript which is handy to perform any housekeeping duties, like clearing out watched folders.
Below are some templates I used to do exactly this with an Artbox system and a Filemaker job management system. Save them as plain text files with the extension .xslt
When exporting from Filemaker to Final Cut Server XML use the *Export Records...* function and specify XML. When asked to, use the fmp-fcsvr.xlst template you just created.
You will need to ensure that you have the asset ID in a field somewhere on your FMP database. Without this you don't have a UID to sync the data. Make sure its the first column you export, the XSLT looks for that colum to form the asset reference in the XML file. The exported xml file should be dropped into a watched folder with an XML read response. Make sure you test this on a backup system before you go live, this could modify or delete your precious metadata if something goes wrong.
fmp-fcsvr.xlst
(begin)
*<?xml version="1.0" encoding="UTF-8"?>*
*<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fmp="http://www.filemaker.com/fmpxmlresult" version="1.0" exclude-result-prefixes="fmp">*
*<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>*
*<!-- *
*XML stylesheet to format FMPXMLRESULT XML exported from Filemaker to FinalCutServer/Artbox*
*Asset setMd XML (see example below).*
*2007 Jim Mellor*
*Note: FileMaker XML must contain the Asset ID field as the first value of*
*each record (ie the first column of each row) for this template to work.*
*<?xml version="1.0"?>*
<FinalCutServer>
*<request reqId="setMd" entityId="/asset/38215">*
<params>
*<mdValue fieldName="Asset ID" dataType="integer">38215</mdValue>*
*<mdValue fieldName="Whatever" dataType="string">This is your data</mdValue>*
*<mdValue fieldName="Client" dataType="string">Super Company</mdValue>*
*<mdValue fieldName="Brand" dataType="string">Blue Wavey Gel</mdValue>*
*<mdValue fieldName="Product" dataType="string">Housebase April Campaign</mdValue>*
*<mdValue fieldName="Title" dataType="string">Etc etc</mdValue>*
</params>
</request>
</FinalCutServer>
-->
<!--
*Root match template*
-->
*<xsl:template match="fmp:FMPXMLRESULT">*
<FinalCutServer>
*<xsl:for-each select="fmp:RESULTSET/fmp:ROW">*
*<xsl:call-template name="request">*
*<xsl:with-param name="row" select="position()"/>*
</xsl:call-template>
</xsl:for-each>
</FinalCutServer>
</xsl:template>
*<xsl:template name="getEntityId">*
*<xsl:param name="row"/>*
*<xsl:variable name="entId">*
*<xsl:value-of select="normalize-space(/fmp:FMPXMLRESULT/fmp:RESULTSET/fmp:ROW[position()=$row ]/fmp:COL[position()=1])"/>*
</xsl:variable>
*<xsl:variable name="prefix">*
<xsl:text>/asset/</xsl:text>
</xsl:variable>
*<xsl:value-of select="concat($prefix, $entId)"/>*
</xsl:template>
*<xsl:template name="typeTranslator">*
*<xsl:param name="fmpType"/>*
<xsl:choose>
*<xsl:when test="$fmpType = 'TEXT'">*
<xsl:text>string</xsl:text>
</xsl:when>
*<xsl:when test="$fmpType = 'NUMBER'">*
<xsl:text>integer</xsl:text>
</xsl:when>
*<xsl:when test="$fmpType = 'BOOLEAN'">*
<xsl:text>bool</xsl:text>
</xsl:when>
*<xsl:when test="$fmpType = 'DATE'">*
<xsl:text>dateTime</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:template>
*<xsl:template name="request">*
*<xsl:param name="row"/>*
<request>
*<xsl:attribute name="reqId">*
<xsl:text>setMd</xsl:text>
</xsl:attribute>
*<xsl:attribute name="entityId">*
*<xsl:call-template name="getEntityId">*
*<xsl:with-param name="row" select="position()"/>*
</xsl:call-template>
</xsl:attribute>
<params>
*<xsl:for-each select="./fmp:COL">*
*<xsl:call-template name="mdValue">*
*<xsl:with-param name="col" select="position()"/>*
*<xsl:with-param name="row" select="$row"/>*
</xsl:call-template>
</xsl:for-each>
</params>
</request>
</xsl:template>
*<xsl:template name="mdValue">*
*<xsl:param name="col"/>*
*<xsl:param name="row"/>*
<mdValue>
*<xsl:attribute name="fieldName">*
*<xsl:value-of select="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD[$col]/@NAME"/>*
</xsl:attribute>
*<xsl:attribute name="dataType">*
* <xsl:call-template name="typeTranslator">*
*<xsl:with-param name="fmpType" select="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD[$col]/@TYPE"/>*
</xsl:call-template>
</xsl:attribute>
*<xsl:value-of select="normalize-space(/fmp:FMPXMLRESULT/fmp:RESULTSET/fmp:ROW[position()=$row ]/fmp:COL[position()=$col])"/>*
</mdValue>
</xsl:template>
</xsl:stylesheet>
(end)
Now, the other way! To send from Final Cut Server to FMP you need to *Import Records...* > *XML Data Source*. Tick use *XSL style sheet* and use the xslt file below. Your source files will come from an XML Write response from FCSvr. Typically this could be triggered on asset modification.
fcsvr-fmp.xslt
(begin)
*<?xml version="1.0" encoding="UTF-8"?>*
*<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.filemaker.com/fmpxmlresult" version="1.0">*
*<!-- *
*XML stylesheet to format FCSvr/Artbox Asset getMdReply XML to Filemaker FMPXMLRESULT.*
*2007 Jim Mellor*
*Note: If importing a combined bunch of entities, the first will define the*
*fields imported into Filemaker and their import order. For this reason it is*
*important to ensure that your Artbox getMdReply/entity entries contains the*
*same metadata fields in the same order.*
-->
<!--
*Root match template*
-->
*<xsl:template match="/">*
*<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">*
<ERRORCODE>0</ERRORCODE>
*<PRODUCT BUILD="" NAME="" VERSION=""/>*
*<DATABASE DATEFORMAT="M/d/yyyy" LAYOUT="" NAME="" RECORDS="{count(//)}" TIMEFORMAT="h:mm:ss a"/>*
*<xsl:call-template name="METADATA"/>*
*<xsl:call-template name="RESULTSET"/>*
</FMPXMLRESULT>
</xsl:template>
*<xsl:template name="METADATA">*
<METADATA>
*<xsl:for-each select="/artbox/getMdReply/entity[1]/metadata/mdValue">*
<FIELD>
*<xsl:attribute name="EMPTYOK">YES</xsl:attribute>*
*<xsl:attribute name="MAXREPEAT">1</xsl:attribute>*
*<xsl:attribute name="NAME">*
*<xsl:value-of select="@fieldName"/>*
</xsl:attribute>
*<xsl:attribute name="TYPE">*
*<xsl:call-template name="typeTranslator">*
*<xsl:with-param name="abType" select="@dataType"/>*
</xsl:call-template>
</xsl:attribute>
</FIELD>
</xsl:for-each>
</METADATA>
</xsl:template>
*<xsl:template name="typeTranslator">*
*<xsl:param name="abType"/>*
<xsl:choose>
*<xsl:when test="$abType = 'string'">*
<xsl:text>TEXT</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'integer'">*
<xsl:text>NUMBER</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'bool'">*
<xsl:text>TEXT</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'dateTime'">*
<xsl:text>DATE</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'coords'">*
<xsl:text>TEXT</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'int64'">*
<xsl:text>NUMBER</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'timecode'">*
<xsl:text>TEXT</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:template>
*<xsl:template name="RESULTSET">*
<RESULTSET>
*<xsl:attribute name="FOUND">*
*<xsl:value-of select="count(/artbox/getMdReply/entity)"/>*
</xsl:attribute>
*<xsl:for-each select="/artbox/getMdReply/entity/">
<ROW>
*<xsl:attribute name="MODID">0</xsl:attribute>*
*<xsl:attribute name="RECORDID">0</xsl:attribute>*
*<xsl:for-each select="mdValue">*
<COL>
<DATA>
*<xsl:value-of select="."/>*
</DATA>
</COL>
</xsl:for-each>
</ROW>
</xsl:for-each>
</RESULTSET>
</xsl:template>
</xsl:stylesheet>
(end)
Hope this helps your cause.
Below are some templates I used to do exactly this with an Artbox system and a Filemaker job management system. Save them as plain text files with the extension .xslt
When exporting from Filemaker to Final Cut Server XML use the *Export Records...* function and specify XML. When asked to, use the fmp-fcsvr.xlst template you just created.
You will need to ensure that you have the asset ID in a field somewhere on your FMP database. Without this you don't have a UID to sync the data. Make sure its the first column you export, the XSLT looks for that colum to form the asset reference in the XML file. The exported xml file should be dropped into a watched folder with an XML read response. Make sure you test this on a backup system before you go live, this could modify or delete your precious metadata if something goes wrong.
fmp-fcsvr.xlst
(begin)
*<?xml version="1.0" encoding="UTF-8"?>*
*<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fmp="http://www.filemaker.com/fmpxmlresult" version="1.0" exclude-result-prefixes="fmp">*
*<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>*
*<!-- *
*XML stylesheet to format FMPXMLRESULT XML exported from Filemaker to FinalCutServer/Artbox*
*Asset setMd XML (see example below).*
*2007 Jim Mellor*
*Note: FileMaker XML must contain the Asset ID field as the first value of*
*each record (ie the first column of each row) for this template to work.*
*<?xml version="1.0"?>*
<FinalCutServer>
*<request reqId="setMd" entityId="/asset/38215">*
<params>
*<mdValue fieldName="Asset ID" dataType="integer">38215</mdValue>*
*<mdValue fieldName="Whatever" dataType="string">This is your data</mdValue>*
*<mdValue fieldName="Client" dataType="string">Super Company</mdValue>*
*<mdValue fieldName="Brand" dataType="string">Blue Wavey Gel</mdValue>*
*<mdValue fieldName="Product" dataType="string">Housebase April Campaign</mdValue>*
*<mdValue fieldName="Title" dataType="string">Etc etc</mdValue>*
</params>
</request>
</FinalCutServer>
-->
<!--
*Root match template*
-->
*<xsl:template match="fmp:FMPXMLRESULT">*
<FinalCutServer>
*<xsl:for-each select="fmp:RESULTSET/fmp:ROW">*
*<xsl:call-template name="request">*
*<xsl:with-param name="row" select="position()"/>*
</xsl:call-template>
</xsl:for-each>
</FinalCutServer>
</xsl:template>
*<xsl:template name="getEntityId">*
*<xsl:param name="row"/>*
*<xsl:variable name="entId">*
*<xsl:value-of select="normalize-space(/fmp:FMPXMLRESULT/fmp:RESULTSET/fmp:ROW[position()=$row ]/fmp:COL[position()=1])"/>*
</xsl:variable>
*<xsl:variable name="prefix">*
<xsl:text>/asset/</xsl:text>
</xsl:variable>
*<xsl:value-of select="concat($prefix, $entId)"/>*
</xsl:template>
*<xsl:template name="typeTranslator">*
*<xsl:param name="fmpType"/>*
<xsl:choose>
*<xsl:when test="$fmpType = 'TEXT'">*
<xsl:text>string</xsl:text>
</xsl:when>
*<xsl:when test="$fmpType = 'NUMBER'">*
<xsl:text>integer</xsl:text>
</xsl:when>
*<xsl:when test="$fmpType = 'BOOLEAN'">*
<xsl:text>bool</xsl:text>
</xsl:when>
*<xsl:when test="$fmpType = 'DATE'">*
<xsl:text>dateTime</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:template>
*<xsl:template name="request">*
*<xsl:param name="row"/>*
<request>
*<xsl:attribute name="reqId">*
<xsl:text>setMd</xsl:text>
</xsl:attribute>
*<xsl:attribute name="entityId">*
*<xsl:call-template name="getEntityId">*
*<xsl:with-param name="row" select="position()"/>*
</xsl:call-template>
</xsl:attribute>
<params>
*<xsl:for-each select="./fmp:COL">*
*<xsl:call-template name="mdValue">*
*<xsl:with-param name="col" select="position()"/>*
*<xsl:with-param name="row" select="$row"/>*
</xsl:call-template>
</xsl:for-each>
</params>
</request>
</xsl:template>
*<xsl:template name="mdValue">*
*<xsl:param name="col"/>*
*<xsl:param name="row"/>*
<mdValue>
*<xsl:attribute name="fieldName">*
*<xsl:value-of select="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD[$col]/@NAME"/>*
</xsl:attribute>
*<xsl:attribute name="dataType">*
* <xsl:call-template name="typeTranslator">*
*<xsl:with-param name="fmpType" select="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD[$col]/@TYPE"/>*
</xsl:call-template>
</xsl:attribute>
*<xsl:value-of select="normalize-space(/fmp:FMPXMLRESULT/fmp:RESULTSET/fmp:ROW[position()=$row ]/fmp:COL[position()=$col])"/>*
</mdValue>
</xsl:template>
</xsl:stylesheet>
(end)
Now, the other way! To send from Final Cut Server to FMP you need to *Import Records...* > *XML Data Source*. Tick use *XSL style sheet* and use the xslt file below. Your source files will come from an XML Write response from FCSvr. Typically this could be triggered on asset modification.
fcsvr-fmp.xslt
(begin)
*<?xml version="1.0" encoding="UTF-8"?>*
*<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.filemaker.com/fmpxmlresult" version="1.0">*
*<!-- *
*XML stylesheet to format FCSvr/Artbox Asset getMdReply XML to Filemaker FMPXMLRESULT.*
*2007 Jim Mellor*
*Note: If importing a combined bunch of entities, the first will define the*
*fields imported into Filemaker and their import order. For this reason it is*
*important to ensure that your Artbox getMdReply/entity entries contains the*
*same metadata fields in the same order.*
-->
<!--
*Root match template*
-->
*<xsl:template match="/">*
*<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">*
<ERRORCODE>0</ERRORCODE>
*<PRODUCT BUILD="" NAME="" VERSION=""/>*
*<DATABASE DATEFORMAT="M/d/yyyy" LAYOUT="" NAME="" RECORDS="{count(//)}" TIMEFORMAT="h:mm:ss a"/>*
*<xsl:call-template name="METADATA"/>*
*<xsl:call-template name="RESULTSET"/>*
</FMPXMLRESULT>
</xsl:template>
*<xsl:template name="METADATA">*
<METADATA>
*<xsl:for-each select="/artbox/getMdReply/entity[1]/metadata/mdValue">*
<FIELD>
*<xsl:attribute name="EMPTYOK">YES</xsl:attribute>*
*<xsl:attribute name="MAXREPEAT">1</xsl:attribute>*
*<xsl:attribute name="NAME">*
*<xsl:value-of select="@fieldName"/>*
</xsl:attribute>
*<xsl:attribute name="TYPE">*
*<xsl:call-template name="typeTranslator">*
*<xsl:with-param name="abType" select="@dataType"/>*
</xsl:call-template>
</xsl:attribute>
</FIELD>
</xsl:for-each>
</METADATA>
</xsl:template>
*<xsl:template name="typeTranslator">*
*<xsl:param name="abType"/>*
<xsl:choose>
*<xsl:when test="$abType = 'string'">*
<xsl:text>TEXT</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'integer'">*
<xsl:text>NUMBER</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'bool'">*
<xsl:text>TEXT</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'dateTime'">*
<xsl:text>DATE</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'coords'">*
<xsl:text>TEXT</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'int64'">*
<xsl:text>NUMBER</xsl:text>
</xsl:when>
*<xsl:when test="$abType = 'timecode'">*
<xsl:text>TEXT</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:template>
*<xsl:template name="RESULTSET">*
<RESULTSET>
*<xsl:attribute name="FOUND">*
*<xsl:value-of select="count(/artbox/getMdReply/entity)"/>*
</xsl:attribute>
*<xsl:for-each select="/artbox/getMdReply/entity/">
<ROW>
*<xsl:attribute name="MODID">0</xsl:attribute>*
*<xsl:attribute name="RECORDID">0</xsl:attribute>*
*<xsl:for-each select="mdValue">*
<COL>
<DATA>
*<xsl:value-of select="."/>*
</DATA>
</COL>
</xsl:for-each>
</ROW>
</xsl:for-each>
</RESULTSET>
</xsl:template>
</xsl:stylesheet>
(end)
Hope this helps your cause.
Posted on Oct 29, 2010 5:00 PM