Created
December 2, 2016 19:47
-
-
Save virantha/4464c7be4dc40cfe66dc3658059cdc31 to your computer and use it in GitHub Desktop.
Bundling Python with Moneydance Extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
build file for ant | |
http://jakarta.apache.org/ant/index.html | |
--> | |
<project name="myextension" default="all" basedir="."> | |
<property name="version" value="2.2"/> | |
<property name="src" value="."/> | |
<property name="build" value="./build"/> | |
<property name="privkeyfile" value="${src}/priv_key"/> | |
<property name="pubkeyfile" value="${src}/pub_key"/> | |
<property name="privkeyid" value="99"/> | |
<property name="build.compiler" value="classic"/> | |
<property name="build.compiler.fulldepend" value="true"/> | |
<property name="build.sysclasspath" value="ignore" /> <!-- suppress ridiculous "includeantruntime not set" messages from ant --> | |
<property name="build.includeantruntime" value="false"/> | |
<property name="dist" value="../dist"/> | |
<property name="tmp" value="../tmp"/> | |
<property name="debug" value="on"/> | |
<property name="optimize" value="off"/> | |
<path id="classpath"> | |
<pathelement path="../lib/extadmin.jar"/> | |
<pathelement path="../lib/moneydance-dev.jar"/> | |
<pathelement path="../lib/jython-standalone-2.7.0.jar"/> | |
</path> | |
<target name="init"> | |
<mkdir dir="${dist}"/> | |
<mkdir dir="${build}"/> | |
</target> | |
<target name="myextension" depends="init"> | |
<javac target="1.6" source="1.6" srcdir="${src}" debug="${debug}" optimize="${optimize}" | |
classpathref="classpath" destdir="${build}" | |
includes="com/moneydance/modules/features/myextension/**"/> | |
<jar destfile="${dist}/myextension.mxt"> | |
<fileset dir="${src}" includes=" | |
com/moneydance/modules/features/myextension/meta_info.dict | |
com/moneydance/modules/features/myextension/*.gif | |
com/moneydance/modules/features/myextension/*.jpg | |
com/moneydance/modules/features/myextension/*.jpeg"/> | |
<fileset dir="${build}" includes="com/moneydance/modules/features/myextension/**"/> | |
<fileset dir="${src}/com/moneydance/modules/features/myextension/python" includes="**/**.py"/> | |
</jar> | |
<java newenvironment="true" | |
classpathref="classpath" | |
classname="com.moneydance.admin.KeyAdmin"> | |
<arg value="signextjar"/> | |
<arg value="${privkeyfile}"/> | |
<arg value="${privkeyid}"/> | |
<arg value="myextension"/> | |
<arg line="${dist}/myextension.mxt"/> | |
</java> | |
<move file="${src}/s-myextension.mxt" tofile="${dist}/myextension.mxt"/> | |
</target> | |
<target name="genkeys"> | |
<java | |
classpathref="classpath" | |
classname="com.moneydance.admin.KeyAdmin"> | |
<arg value="genkey"/> | |
<arg value="${privkeyfile}"/> | |
<arg value="${pubkeyfile}"/> | |
</java> | |
</target> | |
<target name="all" depends="myextension"/> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.moneydance.modules.features.myextension; | |
import com.moneydance.apps.md.controller.FeatureModule; | |
import com.moneydance.apps.md.controller.FeatureModuleContext; | |
import com.moneydance.apps.md.controller.ModuleUtil; | |
import com.moneydance.apps.md.controller.UserPreferences; | |
import java.io.*; | |
import java.util.*; | |
import java.text.*; | |
import java.awt.*; | |
import java.net.*; | |
import org.python.util.PythonInterpreter; | |
import org.python.core.*; | |
/** Pluggable module used to give users access to a Account List | |
interface to Moneydance. | |
*/ | |
public class Main | |
extends FeatureModule | |
{ | |
private PythonInterpreter pi = null; // Use this for running our python code | |
public void init() { | |
// the first thing we will do is register this module to be invoked | |
// via the application toolbar | |
FeatureModuleContext context = getContext(); | |
try { | |
context.registerFeature(this, "popup", | |
getIcon("accountlist"), | |
getName()); | |
this.pi = new PythonInterpreter(); | |
String path = getSourceFile().toString(); // Get the location of this mxt | |
this.pi.set("jarpath", path); | |
this.pi.exec("import sys"); | |
this.pi.exec("if jarpath not in sys.path: sys.path.append(jarpath)"); | |
this.pi.exec("from com.infinitekind.moneydance.model import *"); | |
this.pi.exec("import pyextension"); | |
this.pi.exec("reload(pyextension)"); | |
this.pi.set("context", context); | |
this.pi.set("extensionobject", this); | |
this.pi.exec("ext = pyextension.SimplePopupExtension()"); | |
this.pi.exec("ext.initialize (context, extensionobject, True)"); | |
} | |
catch (Exception e) { | |
e.printStackTrace(System.err); | |
} | |
} | |
public void cleanup() { | |
closeConsole(); | |
} | |
private Image getIcon(String action) { | |
try { | |
ClassLoader cl = getClass().getClassLoader(); | |
java.io.InputStream in = | |
cl.getResourceAsStream("/com/moneydance/modules/features/myextension/icon.gif"); | |
if (in != null) { | |
ByteArrayOutputStream bout = new ByteArrayOutputStream(1000); | |
byte buf[] = new byte[256]; | |
int n = 0; | |
while((n=in.read(buf, 0, buf.length))>=0) | |
bout.write(buf, 0, n); | |
return Toolkit.getDefaultToolkit().createImage(bout.toByteArray()); | |
} | |
} catch (Throwable e) { } | |
return null; | |
} | |
/** Process an invokation of this module with the given URI */ | |
public void invoke(String uri) { | |
String command = uri; | |
String parameters = ""; | |
int theIdx = uri.indexOf('?'); | |
if(theIdx>=0) { | |
command = uri.substring(0, theIdx); | |
parameters = uri.substring(theIdx+1); | |
} | |
else { | |
theIdx = uri.indexOf(':'); | |
if(theIdx>=0) { | |
command = uri.substring(0, theIdx); | |
} | |
} | |
// Pass through the invocation string to the Python handler | |
try { | |
this.pi.set("invoke_string", command); | |
this.pi.exec("ext.invoke(invoke_string)"); | |
} | |
catch (Exception e) { | |
e.printStackTrace(System.err); | |
} | |
} | |
public String getName() { | |
return "Show popup"; | |
} | |
FeatureModuleContext getUnprotectedContext() { | |
return getContext(); | |
} | |
synchronized void closeConsole() { | |
System.gc(); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from com.infinitekind.moneydance.model import * | |
import os | |
from javax.swing import JButton, JFrame, JScrollPane, JTextArea, BoxLayout, BorderFactory | |
class SimplePopupExtension(object): | |
def initialize(self, extension_context, extension_object, from_java=False): | |
self.moneydanceContext = extension_context | |
self.moneydanceExtensionObject = extension_object | |
# here we register ourselves with a menu item to invoke a feature | |
# (ignore the button and icon mentions in the docs) | |
if not from_java: | |
self.moneydanceContext.registerFeature(extension_object, "popup", None, "Test popup") | |
# invoke(eventstring) is called when we receive a callback for the feature that | |
# we registered in the initialize method | |
def invoke(self, eventString=""): | |
self.moneydanceContext.setStatus("Python extension received command: %s" % (eventString)) | |
if eventString=='popup': | |
self._show_popup() | |
def __str__(self): | |
return "SimplePopup" | |
# Our actual user code | |
def _show_popup(self): | |
self._initUI() | |
pass | |
book = self.moneydanceContext.getCurrentAccountBook() | |
account_names = [] | |
for acct in AccountUtil.getAccountIterator(book): | |
account_names.append(acct.getFullAccountName()) | |
self.text_area.text = '\n'.join(account_names) | |
def _initUI(self): | |
frame = JFrame('Simple popup', defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE, size=(300,300)) | |
frame.setLayout(BoxLayout(frame.contentPane, BoxLayout.PAGE_AXIS)) | |
# Call-back to close popup | |
def closeDialog(event): | |
frame.visible = False | |
frame.dispose() | |
# Instantiate components | |
self.text_area = JTextArea() | |
msgScroller = JScrollPane() | |
msgScroller.setBorder(BorderFactory.createTitledBorder("Accounts")) | |
msgScroller.setViewportView(self.text_area) | |
self.close_button = JButton('Close', actionPerformed = closeDialog) | |
# Add components to frame | |
frame.add(msgScroller) | |
frame.add(self.close_button) | |
frame.visible = True | |
# Tell moneydance this is an extension | |
moneydance_extension = SimplePopupExtension() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment