Example #1
0
def build_xibless(edition, dest='cocoa/autogen'):
    import xibless
    ensure_folder(dest)
    FNPAIRS = [
        ('ignore_list_dialog.py', 'IgnoreListDialog_UI'),
        ('deletion_options.py', 'DeletionOptions_UI'),
        ('problem_dialog.py', 'ProblemDialog_UI'),
        ('directory_panel.py', 'DirectoryPanel_UI'),
        ('prioritize_dialog.py', 'PrioritizeDialog_UI'),
        ('result_window.py', 'ResultWindow_UI'),
        ('main_menu.py', 'MainMenu_UI'),
        ('preferences_panel.py', 'PreferencesPanel_UI'),
    ]
    for srcname, dstname in FNPAIRS:
        xibless.generate(op.join('cocoa', 'base', 'ui', srcname),
                         op.join(dest, dstname),
                         localizationTable='Localizable',
                         args={'edition': edition})
    if edition == 'pe':
        xibless.generate('cocoa/pe/ui/details_panel.py',
                         op.join(dest, 'DetailsPanel_UI'),
                         localizationTable='Localizable')
    else:
        xibless.generate('cocoa/base/ui/details_panel.py',
                         op.join(dest, 'DetailsPanel_UI'),
                         localizationTable='Localizable')
Example #2
0
def build_xibless(edition, dest='cocoa/autogen'):
    import xibless
    ensure_folder(dest)
    FNPAIRS = [
        ('ignore_list_dialog.py', 'IgnoreListDialog_UI'),
        ('deletion_options.py', 'DeletionOptions_UI'),
        ('problem_dialog.py', 'ProblemDialog_UI'),
        ('directory_panel.py', 'DirectoryPanel_UI'),
        ('prioritize_dialog.py', 'PrioritizeDialog_UI'),
        ('result_window.py', 'ResultWindow_UI'),
        ('main_menu.py', 'MainMenu_UI'),
        ('preferences_panel.py', 'PreferencesPanel_UI'),
    ]
    for srcname, dstname in FNPAIRS:
        xibless.generate(
            op.join('cocoa', 'base', 'ui', srcname), op.join(dest, dstname),
            localizationTable='Localizable', args={'edition': edition}
        )
    if edition == 'pe':
        xibless.generate(
            'cocoa/pe/ui/details_panel.py', op.join(dest, 'DetailsPanel_UI'),
            localizationTable='Localizable'
        )
    else:
        xibless.generate(
            'cocoa/base/ui/details_panel.py', op.join(dest, 'DetailsPanel_UI'),
            localizationTable='Localizable'
        )
Example #3
0
def build_xibless(dest='cocoa/autogen'):
    import xibless
    ensure_folder(dest)
    FNPAIRS = [
        ('ignore_list_dialog.py', 'IgnoreListDialog_UI'),
        ('deletion_options.py', 'DeletionOptions_UI'),
        ('problem_dialog.py', 'ProblemDialog_UI'),
        ('directory_panel.py', 'DirectoryPanel_UI'),
        ('prioritize_dialog.py', 'PrioritizeDialog_UI'),
        ('result_window.py', 'ResultWindow_UI'),
        ('main_menu.py', 'MainMenu_UI'),
        ('details_panel.py', 'DetailsPanel_UI'),
        ('details_panel_picture.py', 'DetailsPanelPicture_UI'),
    ]
    for srcname, dstname in FNPAIRS:
        xibless.generate(
            op.join('cocoa', 'ui', srcname), op.join(dest, dstname),
            localizationTable='Localizable'
        )
    for appmode in ('standard', 'music', 'picture'):
        xibless.generate(
            op.join('cocoa', 'ui', 'preferences_panel.py'),
            op.join(dest, 'PreferencesPanel%s_UI' % appmode.capitalize()),
            localizationTable='Localizable',
            args={'appmode': appmode},
        )
Example #4
0
def build_cocoa(dev):
    print("Creating OS X app structure")
    app = cocoa_app()
    # We import this here because we don't want opened module to prevent us replacing .pyd files.
    from core.app import Application as MoneyGuruApp
    app_version = MoneyGuruApp.VERSION
    filereplace('cocoa/InfoTemplate.plist',
                'build/Info.plist',
                version=app_version)
    app.create('build/Info.plist')
    print("Building localizations")
    build_localizations('cocoa')
    print("Building xibless UIs")
    build_cocoalib_xibless()
    build_xibless()
    print("Building Python extensions")
    build_cocoa_proxy_module()
    build_cocoa_bridging_interfaces()
    print("Building the cocoa layer")
    copy_embeddable_python_dylib('build')
    pydep_folder = op.join(app.resources, 'py')
    ensure_folder(pydep_folder)
    if dev:
        hardlink('cocoa/mg_cocoa.py', 'build/mg_cocoa.py')
    else:
        copy('cocoa/mg_cocoa.py', 'build/mg_cocoa.py')
    tocopy = ['core', 'hscommon', 'cocoalib/cocoa', 'objp']
    copy_packages(tocopy, pydep_folder, create_links=dev)
    sys.path.insert(0, 'build')
    collect_stdlib_dependencies('build/mg_cocoa.py', pydep_folder)
    del sys.path[0]
    copy_sysconfig_files_for_embed(pydep_folder)
    if not dev:
        # Important: Don't ever run delete_files_with_pattern('*.py') on dev builds because you'll
        # be deleting all py files in symlinked folders.
        compileall.compile_dir(pydep_folder, force=True, legacy=True)
        delete_files_with_pattern(pydep_folder, '*.py')
        delete_files_with_pattern(pydep_folder, '__pycache__')
    print("Compiling with WAF")
    os.chdir('cocoa')
    print_and_do(cocoa_compile_command())
    os.chdir('..')
    app.copy_executable('cocoa/build/moneyGuru')
    build_help()
    print("Copying resources and frameworks")
    resources = [
        'cocoa/dsa_pub.pem',
        'build/mg_cocoa.py',
        'build/help',
        'data/example.moneyguru',
    ] + glob.glob('images/*')
    app.copy_resources(*resources, use_symlinks=dev)
    app.copy_frameworks(
        'build/Python',
        'cocoalib/Sparkle.framework',
    )
    print("Creating the run.py file")
    tmpl = open('run_template_cocoa.py', 'rt').read()
    run_contents = tmpl.replace('{{app_path}}', app.dest)
    open('run.py', 'wt').write(run_contents)
Example #5
0
def build_xibless(dest='cocoa/autogen'):
    import xibless
    ensure_folder(dest)
    FNPAIRS = [
        ('lookup.py', 'MGLookup_UI'),
        ('schedule_scope_dialog.py', 'MGRecurrenceScopeDialog_UI'),
        ('custom_date_range_dialog.py', 'MGCustomDateRangePanel_UI'),
        ('account_reassign_panel.py', 'MGAccountReassignPanel_UI'),
        ('csv_layout_name.py', 'MGCSVLayoutNameDialog_UI'),
        ('csv_import_options.py', 'MGCSVImportOptions_UI'),
        ('import_window.py', 'MGImportWindow_UI'),
        ('export_panel.py', 'MGExportPanel_UI'),
        ('budget_panel.py', 'MGBudgetPanel_UI'),
        ('schedule_panel.py', 'MGSchedulePanel_UI'),
        ('mass_editing_panel.py', 'MGMassEditionPanel_UI'),
        ('transaction_panel.py', 'MGTransactionInspector_UI'),
        ('account_panel.py', 'MGAccountProperties_UI'),
        ('newtab_view.py', 'MGEmptyView_UI'),
        ('docprops_view.py', 'MGDocPropsView_UI'),
        ('cashculator_view.py', 'MGCashculatorView_UI'),
        ('transaction_view.py', 'MGTransactionView_UI'),
        ('account_view.py', 'MGAccountView_UI'),
        ('account_sheet_view.py', 'MGAccountSheetView_UI'),
        ('date_range_selector.py', 'MGDateRangeSelector_UI'),
        ('main_window.py', 'MGMainWindowController_UI'),
        ('preferences_panel.py', 'MGPreferencesPanel_UI'),
        ('main_menu.py', 'MGMainMenu_UI'),
    ]
    for srcname, dstname in FNPAIRS:
        srcpath = op.join('cocoa', 'ui', srcname)
        dstpath = op.join(dest, dstname)
        if modified_after(srcpath, dstpath + '.h'):
            print("Generating xibless UI %s" % srcpath)
            xibless.generate(srcpath, dstpath, localizationTable='Localizable')
Example #6
0
def build_xibless(dest='cocoa/autogen'):
    import xibless
    ensure_folder(dest)
    FNPAIRS = [
        ('lookup.py', 'MGLookup_UI'),
        ('schedule_scope_dialog.py', 'MGRecurrenceScopeDialog_UI'),
        ('custom_date_range_dialog.py', 'MGCustomDateRangePanel_UI'),
        ('account_reassign_panel.py', 'MGAccountReassignPanel_UI'),
        ('csv_layout_name.py', 'MGCSVLayoutNameDialog_UI'),
        ('csv_import_options.py', 'MGCSVImportOptions_UI'),
        ('import_window.py', 'MGImportWindow_UI'),
        ('export_panel.py', 'MGExportPanel_UI'),
        ('budget_panel.py', 'MGBudgetPanel_UI'),
        ('schedule_panel.py', 'MGSchedulePanel_UI'),
        ('mass_editing_panel.py', 'MGMassEditionPanel_UI'),
        ('transaction_panel.py', 'MGTransactionInspector_UI'),
        ('account_panel.py', 'MGAccountProperties_UI'),
        ('newtab_view.py', 'MGEmptyView_UI'),
        ('docprops_view.py', 'MGDocPropsView_UI'),
        ('transaction_view.py', 'MGTransactionView_UI'),
        ('account_view.py', 'MGAccountView_UI'),
        ('account_sheet_view.py', 'MGAccountSheetView_UI'),
        ('date_range_selector.py', 'MGDateRangeSelector_UI'),
        ('main_window.py', 'MGMainWindowController_UI'),
        ('preferences_panel.py', 'MGPreferencesPanel_UI'),
        ('main_menu.py', 'MGMainMenu_UI'),
    ]
    for srcname, dstname in FNPAIRS:
        srcpath = op.join('cocoa', 'ui', srcname)
        dstpath = op.join(dest, dstname)
        if modified_after(srcpath, dstpath + '.h'):
            print("Generating xibless UI %s" % srcpath)
            xibless.generate(srcpath, dstpath, localizationTable='Localizable')
Example #7
0
def build_xibless(dest='cocoa/autogen'):
    import xibless
    ensure_folder(dest)
    FNPAIRS = [
        ('ignore_list_dialog.py', 'IgnoreListDialog_UI'),
        ('deletion_options.py', 'DeletionOptions_UI'),
        ('problem_dialog.py', 'ProblemDialog_UI'),
        ('directory_panel.py', 'DirectoryPanel_UI'),
        ('prioritize_dialog.py', 'PrioritizeDialog_UI'),
        ('result_window.py', 'ResultWindow_UI'),
        ('main_menu.py', 'MainMenu_UI'),
        ('details_panel.py', 'DetailsPanel_UI'),
        ('details_panel_picture.py', 'DetailsPanelPicture_UI'),
    ]
    for srcname, dstname in FNPAIRS:
        xibless.generate(
            op.join('cocoa', 'ui', srcname), op.join(dest, dstname),
            localizationTable='Localizable'
        )
    for appmode in ('standard', 'music', 'picture'):
        xibless.generate(
            op.join('cocoa', 'ui', 'preferences_panel.py'),
            op.join(dest, 'PreferencesPanel%s_UI' % appmode.capitalize()),
            localizationTable='Localizable',
            args={'appmode': appmode},
        )
Example #8
0
def build_xibless(dest="cocoa/autogen"):
    import xibless

    ensure_folder(dest)
    FNPAIRS = [
        ("lookup.py", "MGLookup_UI"),
        ("schedule_scope_dialog.py", "MGRecurrenceScopeDialog_UI"),
        ("custom_date_range_dialog.py", "MGCustomDateRangePanel_UI"),
        ("account_reassign_panel.py", "MGAccountReassignPanel_UI"),
        ("csv_layout_name.py", "MGCSVLayoutNameDialog_UI"),
        ("csv_import_options.py", "MGCSVImportOptions_UI"),
        ("import_window.py", "MGImportWindow_UI"),
        ("export_panel.py", "MGExportPanel_UI"),
        ("budget_panel.py", "MGBudgetPanel_UI"),
        ("schedule_panel.py", "MGSchedulePanel_UI"),
        ("mass_editing_panel.py", "MGMassEditionPanel_UI"),
        ("transaction_panel.py", "MGTransactionInspector_UI"),
        ("account_panel.py", "MGAccountProperties_UI"),
        ("newtab_view.py", "MGEmptyView_UI"),
        ("docprops_view.py", "MGDocPropsView_UI"),
        ("transaction_view.py", "MGTransactionView_UI"),
        ("account_view.py", "MGAccountView_UI"),
        ("account_sheet_view.py", "MGAccountSheetView_UI"),
        ("date_range_selector.py", "MGDateRangeSelector_UI"),
        ("main_window.py", "MGMainWindowController_UI"),
        ("preferences_panel.py", "MGPreferencesPanel_UI"),
        ("main_menu.py", "MGMainMenu_UI"),
    ]
    for srcname, dstname in FNPAIRS:
        srcpath = op.join("cocoa", "ui", srcname)
        dstpath = op.join(dest, dstname)
        if modified_after(srcpath, dstpath + ".h"):
            print("Generating xibless UI %s" % srcpath)
            xibless.generate(srcpath, dstpath, localizationTable="Localizable")
Example #9
0
def build_cocoa(dev):
    print("Creating OS X app structure")
    app = cocoa_app()
    # We import this here because we don't want opened module to prevent us replacing .pyd files.
    from core.app import Application as MoneyGuruApp
    app_version = MoneyGuruApp.VERSION
    filereplace('cocoa/InfoTemplate.plist', 'build/Info.plist', version=app_version)
    app.create('build/Info.plist')
    print("Building localizations")
    build_localizations('cocoa')
    print("Building xibless UIs")
    build_cocoalib_xibless()
    build_xibless()
    print("Building Python extensions")
    build_cocoa_proxy_module()
    build_cocoa_bridging_interfaces()
    print("Building the cocoa layer")
    copy_embeddable_python_dylib('build')
    pydep_folder = op.join(app.resources, 'py')
    ensure_folder(pydep_folder)
    if dev:
        hardlink('cocoa/mg_cocoa.py', 'build/mg_cocoa.py')
    else:
        copy('cocoa/mg_cocoa.py', 'build/mg_cocoa.py')
    tocopy = ['core', 'hscommon', 'cocoalib/cocoa', 'objp', 'sgmllib']
    copy_packages(tocopy, pydep_folder, create_links=dev)
    sys.path.insert(0, 'build')
    collect_stdlib_dependencies('build/mg_cocoa.py', pydep_folder)
    del sys.path[0]
    copy_sysconfig_files_for_embed(pydep_folder)
    if not dev:
        # Important: Don't ever run delete_files_with_pattern('*.py') on dev builds because you'll
        # be deleting all py files in symlinked folders.
        compileall.compile_dir(pydep_folder, force=True, legacy=True)
        delete_files_with_pattern(pydep_folder, '*.py')
        delete_files_with_pattern(pydep_folder, '__pycache__')
    print("Compiling PSMTabBarControl framework")
    os.chdir('psmtabbarcontrol')
    print_and_do('{0} waf configure && {0} waf && {0} waf build_framework'.format(sys.executable))
    os.chdir('..')
    print("Compiling with WAF")
    os.chdir('cocoa')
    print_and_do(cocoa_compile_command())
    os.chdir('..')
    app.copy_executable('cocoa/build/moneyGuru')
    build_help()
    print("Copying resources and frameworks")
    resources = [
        'cocoa/dsa_pub.pem', 'build/mg_cocoa.py', 'build/help', 'data/example.moneyguru',
        'plugin_examples'
    ] + glob.glob('images/*')
    app.copy_resources(*resources, use_symlinks=dev)
    app.copy_frameworks(
        'build/Python', 'cocoalib/Sparkle.framework',
        'psmtabbarcontrol/PSMTabBarControl.framework'
    )
    print("Creating the run.py file")
    tmpl = open('run_template_cocoa.py', 'rt').read()
    run_contents = tmpl.replace('{{app_path}}', app.dest)
    open('run.py', 'wt').write(run_contents)
Example #10
0
def build_xibless():
    import xibless
    ensure_folder('cocoa/autogen')
    xibless.generate('cocoa/ui/edit_pane.py', 'cocoa/autogen/PMEditPane_UI')
    xibless.generate('cocoa/ui/build_pane.py', 'cocoa/autogen/PMBuildPane_UI')
    xibless.generate('cocoa/ui/page_pane.py', 'cocoa/autogen/PMPageController_UI')
    xibless.generate('cocoa/ui/main_window.py', 'cocoa/autogen/PMMainWindow_UI')
    xibless.generate('cocoa/ui/main_menu.py', 'cocoa/autogen/PMMainMenu_UI')
Example #11
0
def build_xibless():
    import xibless
    ensure_folder('cocoa/autogen')
    xibless.generate('cocoa/ui/edit_pane.py', 'cocoa/autogen/PMEditPane_UI')
    xibless.generate('cocoa/ui/build_pane.py', 'cocoa/autogen/PMBuildPane_UI')
    xibless.generate('cocoa/ui/page_pane.py',
                     'cocoa/autogen/PMPageController_UI')
    xibless.generate('cocoa/ui/main_window.py',
                     'cocoa/autogen/PMMainWindow_UI')
    xibless.generate('cocoa/ui/main_menu.py', 'cocoa/autogen/PMMainMenu_UI')
Example #12
0
def build_cocoa_bridging_interfaces():
    print("Building Cocoa Bridging Interfaces")
    import objp.o2p
    import objp.p2o
    import objp.const
    add_to_pythonpath('cocoa')
    add_to_pythonpath('cocoalib')
    from cocoa.inter import (PyGUIObject, GUIObjectView, PyTextField, PyTable, TableView, PyColumns,
        ColumnsView, PyOutline, PySelectableList, SelectableListView, PyBaseApp, BaseAppView)
    # This createPool() business is a bit hacky, but upon importing mg_cocoa, we call
    # install_gettext_trans_under_cocoa() which uses proxy functions (and thus need an active
    # autorelease pool). If we don't do that, we get leak warnings.
    from cocoa import proxy
    proxy.createPool()
    from mg_cocoa import (PyPanel, PanelView, PyBaseView,
        PyTableWithDate, PyCompletableEdit, PyDateWidget,
        PyCSVImportOptions, CSVImportOptionsView, PyImportTable, PySplitTable, PyLookup, LookupView,
        PyDateRangeSelector, DateRangeSelectorView, PyImportWindow, ImportWindowView,
        PyFilterBar, FilterBarView, PyReport, ReportView, PyScheduleTable, PyBudgetTable,
        PyEntryTable, PyTransactionTable, PyGeneralLedgerTable, PyChart, ChartView,
        PyAccountPanel, PyMassEditionPanel, PyBudgetPanel, BudgetPanelView, PyCustomDateRangePanel,
        PyAccountReassignPanel, PyExportPanel, ExportPanelView, PyPanelWithTransaction,
        PanelWithTransactionView, PyTransactionPanel, PySchedulePanel, SchedulePanelView,
        BaseViewView, PyAccountSheetView, PyTransactionView,
        PyAccountView, AccountViewView, PyScheduleView, PyBudgetView, PyCashculatorView,
        PyGeneralLedgerView, PyDocPropsView, PyEmptyView, PyReadOnlyPluginView, PyMainWindow,
        MainWindowView, PyDocument, DocumentView, PyMoneyGuruApp)
    from mg_cocoa import PyPrintView, PySplitPrint, PyTransactionPrint, PyEntryPrint
    allclasses = [PyGUIObject, PyTextField, PyTable, PyColumns, PyOutline, PySelectableList,
        PyBaseApp, PyPanel, PyBaseView, PyTableWithDate, PyCompletableEdit, PyDateWidget,
        PyCSVImportOptions, PyImportTable, PySplitTable, PyLookup, PyDateRangeSelector,
        PyImportWindow, PyFilterBar, PyReport, PyScheduleTable, PyBudgetTable,
        PyEntryTable, PyTransactionTable, PyGeneralLedgerTable, PyChart, PyAccountPanel,
        PyMassEditionPanel, PyBudgetPanel, PyCustomDateRangePanel, PyAccountReassignPanel,
        PyExportPanel, PyPanelWithTransaction, PyTransactionPanel, PySchedulePanel,
        PyAccountSheetView, PyTransactionView, PyAccountView, PyScheduleView, PyBudgetView,
        PyCashculatorView, PyGeneralLedgerView, PyDocPropsView, PyEmptyView, PyReadOnlyPluginView,
        PyMainWindow, PyDocument, PyMoneyGuruApp]
    proxy.destroyPool()
    allclasses += [PyPrintView, PySplitPrint, PyTransactionPrint, PyEntryPrint]
    for class_ in allclasses:
        objp.o2p.generate_objc_code(class_, 'cocoa/autogen', inherit=True)
    allclasses = [GUIObjectView, TableView, ColumnsView, SelectableListView, BaseAppView, 
        PanelView, CSVImportOptionsView, LookupView, DateRangeSelectorView, ImportWindowView,
        FilterBarView, ReportView, BudgetPanelView, ExportPanelView, PanelWithTransactionView,
        SchedulePanelView, BaseViewView, AccountViewView, MainWindowView,
        DocumentView, ChartView]
    clsspecs = [objp.o2p.spec_from_python_class(class_) for class_ in allclasses]
    objp.p2o.generate_python_proxy_code_from_clsspec(clsspecs, 'build/CocoaViews.m')
    py_folder = op.join(cocoa_app().resources, 'py')
    ensure_folder(py_folder)
    build_cocoa_ext('CocoaViews', py_folder, ['build/CocoaViews.m', 'build/ObjP.m'])
    import mg_const
    objp.const.generate_objc_code(mg_const, 'cocoa/autogen/PyConst.h')
Example #13
0
def build_cocoa(dev):
    print("Creating OS X app structure")
    app = cocoa_app()
    # We import this here because we don't want opened module to prevent us replacing .pyd files.
    from core.app import Application as MoneyGuruApp

    app_version = MoneyGuruApp.VERSION
    filereplace("cocoa/InfoTemplate.plist", "build/Info.plist", version=app_version)
    app.create("build/Info.plist")
    print("Building localizations")
    build_localizations("cocoa")
    print("Building xibless UIs")
    build_cocoalib_xibless()
    build_xibless()
    print("Building Python extensions")
    build_cocoa_proxy_module()
    build_cocoa_bridging_interfaces()
    print("Building the cocoa layer")
    copy_embeddable_python_dylib("build")
    pydep_folder = op.join(app.resources, "py")
    ensure_folder(pydep_folder)
    if dev:
        hardlink("cocoa/mg_cocoa.py", "build/mg_cocoa.py")
    else:
        copy("cocoa/mg_cocoa.py", "build/mg_cocoa.py")
    tocopy = ["core", "hscommon", "cocoalib/cocoa", "objp"]
    copy_packages(tocopy, pydep_folder, create_links=dev)
    sys.path.insert(0, "build")
    collect_stdlib_dependencies("build/mg_cocoa.py", pydep_folder)
    del sys.path[0]
    copy_sysconfig_files_for_embed(pydep_folder)
    if not dev:
        # Important: Don't ever run delete_files_with_pattern('*.py') on dev builds because you'll
        # be deleting all py files in symlinked folders.
        compileall.compile_dir(pydep_folder, force=True, legacy=True)
        delete_files_with_pattern(pydep_folder, "*.py")
        delete_files_with_pattern(pydep_folder, "__pycache__")
    print("Compiling with WAF")
    os.chdir("cocoa")
    print_and_do(cocoa_compile_command())
    os.chdir("..")
    app.copy_executable("cocoa/build/moneyGuru")
    build_help()
    print("Copying resources and frameworks")
    resources = ["cocoa/dsa_pub.pem", "build/mg_cocoa.py", "build/help", "data/example.moneyguru"] + glob.glob(
        "images/*"
    )
    app.copy_resources(*resources, use_symlinks=dev)
    app.copy_frameworks("build/Python", "cocoalib/Sparkle.framework")
    print("Creating the run.py file")
    tmpl = open("run_template_cocoa.py", "rt").read()
    run_contents = tmpl.replace("{{app_path}}", app.dest)
    open("run.py", "wt").write(run_contents)
Example #14
0
def build_cocoa_bridging_interfaces():
    print("Building Cocoa Bridging Interfaces")
    import objp.o2p
    import objp.p2o
    import objp.const
    add_to_pythonpath('cocoa')
    add_to_pythonpath('cocoalib')
    from cocoa.inter import (PyGUIObject, GUIObjectView, PyTextField, PyTable,
                             TableView, PyColumns, ColumnsView, PyOutline,
                             PySelectableList, SelectableListView, PyBaseApp,
                             BaseAppView)
    # This createPool() business is a bit hacky, but upon importing mg_cocoa, we call
    # install_gettext_trans_under_cocoa() which uses proxy functions (and thus need an active
    # autorelease pool). If we don't do that, we get leak warnings.
    from cocoa import proxy
    proxy.createPool()
    from mg_cocoa import (
        PyPanel, PanelView, PyBaseView, PyTableWithDate, PyCompletableEdit,
        PyDateWidget, PyCSVImportOptions, CSVImportOptionsView, PyImportTable,
        PySplitTable, PyLookup, LookupView, PyDateRangeSelector,
        DateRangeSelectorView, PyImportWindow, ImportWindowView, PyFilterBar,
        FilterBarView, PyReport, ReportView, PyScheduleTable, PyBudgetTable,
        PyEntryTable, PyTransactionTable, PyGeneralLedgerTable, PyChart,
        ChartView, PyAccountPanel, PyMassEditionPanel, PyBudgetPanel,
        BudgetPanelView, PyCustomDateRangePanel, PyAccountReassignPanel,
        PyExportPanel, ExportPanelView, PyPanelWithTransaction,
        PanelWithTransactionView, PyTransactionPanel, PySchedulePanel,
        SchedulePanelView, BaseViewView, PyAccountSheetView, PyTransactionView,
        PyAccountView, AccountViewView, PyScheduleView, PyBudgetView,
        PyGeneralLedgerView, PyDocPropsView, PyPluginListView, PyEmptyView,
        PyReadOnlyPluginView, PyMainWindow, MainWindowView, PyDocument,
        DocumentView, PyMoneyGuruApp)
    from mg_cocoa import PyPrintView, PySplitPrint, PyTransactionPrint, PyEntryPrint
    allclasses = [
        PyGUIObject, PyTextField, PyTable, PyColumns, PyOutline,
        PySelectableList, PyBaseApp, PyPanel, PyBaseView, PyTableWithDate,
        PyCompletableEdit, PyDateWidget, PyCSVImportOptions, PyImportTable,
        PySplitTable, PyLookup, PyDateRangeSelector, PyImportWindow,
        PyFilterBar, PyReport, PyScheduleTable, PyBudgetTable, PyEntryTable,
        PyTransactionTable, PyGeneralLedgerTable, PyChart, PyAccountPanel,
        PyMassEditionPanel, PyBudgetPanel, PyCustomDateRangePanel,
        PyAccountReassignPanel, PyExportPanel, PyPanelWithTransaction,
        PyTransactionPanel, PySchedulePanel, PyAccountSheetView,
        PyTransactionView, PyAccountView, PyScheduleView, PyBudgetView,
        PyGeneralLedgerView, PyDocPropsView, PyPluginListView, PyEmptyView,
        PyReadOnlyPluginView, PyMainWindow, PyDocument, PyMoneyGuruApp
    ]
    proxy.destroyPool()
    allclasses += [PyPrintView, PySplitPrint, PyTransactionPrint, PyEntryPrint]
    for class_ in allclasses:
        objp.o2p.generate_objc_code(class_, 'cocoa/autogen', inherit=True)
    allclasses = [
        GUIObjectView, TableView, ColumnsView, SelectableListView, BaseAppView,
        PanelView, CSVImportOptionsView, LookupView, DateRangeSelectorView,
        ImportWindowView, FilterBarView, ReportView, BudgetPanelView,
        ExportPanelView, PanelWithTransactionView, SchedulePanelView,
        BaseViewView, AccountViewView, MainWindowView, DocumentView, ChartView
    ]
    clsspecs = [
        objp.o2p.spec_from_python_class(class_) for class_ in allclasses
    ]
    objp.p2o.generate_python_proxy_code_from_clsspec(clsspecs,
                                                     'build/CocoaViews.m')
    py_folder = op.join(cocoa_app().resources, 'py')
    ensure_folder(py_folder)
    build_cocoa_ext('CocoaViews', py_folder,
                    ['build/CocoaViews.m', 'build/ObjP.m'])
    import mg_const
    objp.const.generate_objc_code(mg_const, 'cocoa/autogen/PyConst.h')
Example #15
0
def save(filename, document_id, properties, accounts, groups, transactions,
         schedules, budgets):
    def date2str(date):
        return date.strftime('%Y-%m-%d')

    def handle_newlines(s):
        # etree doesn't correctly save newlines. In fields that allow it, we have to escape them so
        # that we can restore them during load.
        # XXX It seems like newer version of etree do escape newlines. When we use Python 3.2, we
        # can probably remove this.
        if not s:
            return s
        return s.replace('\n', '\\n')

    def setattrib(attribs, attribname, value):
        if value:
            attribs[attribname] = value

    def write_transaction_element(parent_element, transaction):
        transaction_element = ET.SubElement(parent_element, 'transaction')
        attrib = transaction_element.attrib
        attrib['date'] = date2str(transaction.date)
        setattrib(attrib, 'description', transaction.description)
        setattrib(attrib, 'payee', transaction.payee)
        setattrib(attrib, 'checkno', transaction.checkno)
        setattrib(attrib, 'notes', handle_newlines(transaction.notes))
        attrib['mtime'] = str(int(transaction.mtime))
        for split in transaction.splits:
            split_element = ET.SubElement(transaction_element, 'split')
            attrib = split_element.attrib
            attrib['account'] = split.account_name
            attrib['amount'] = format_amount(split.amount)
            setattrib(attrib, 'memo', split.memo)
            setattrib(attrib, 'reference', split.reference)
            if split.reconciliation_date is not None:
                attrib['reconciliation_date'] = date2str(
                    split.reconciliation_date)

    root = ET.Element('moneyguru-file')
    root.attrib['document_id'] = document_id
    props_element = ET.SubElement(root, 'properties')
    for name, value in properties.items():
        if name == 'default_currency':
            value = value.code
        else:
            value = str(value)
        props_element.attrib[name] = value
    for group in groups:
        group_element = ET.SubElement(root, 'group')
        attrib = group_element.attrib
        attrib['name'] = group.name
        attrib['type'] = group.type
    for account in accounts:
        account_element = ET.SubElement(root, 'account')
        attrib = account_element.attrib
        attrib['name'] = account.name
        attrib['currency'] = account.currency.code
        attrib['type'] = account.type
        if account.group:
            attrib['group'] = account.group.name
        if account.reference is not None:
            attrib['reference'] = account.reference
        if account.account_number:
            attrib['account_number'] = account.account_number
        if account.inactive:
            attrib['inactive'] = 'y'
        if account.notes:
            attrib['notes'] = handle_newlines(account.notes)
    for transaction in transactions:
        write_transaction_element(root, transaction)
    # the functionality of the line below is untested because it's an optimisation
    scheduled = [s for s in schedules if s.is_alive]
    for recurrence in scheduled:
        recurrence_element = ET.SubElement(root, 'recurrence')
        attrib = recurrence_element.attrib
        attrib['type'] = recurrence.repeat_type
        attrib['every'] = str(recurrence.repeat_every)
        if recurrence.stop_date is not None:
            attrib['stop_date'] = date2str(recurrence.stop_date)
        for date, change in recurrence.date2globalchange.items():
            change_element = ET.SubElement(recurrence_element, 'change')
            change_element.attrib['date'] = date2str(date)
            if change is not None:
                write_transaction_element(change_element, change)
        for date, exception in recurrence.date2exception.items():
            exception_element = ET.SubElement(recurrence_element, 'exception')
            exception_element.attrib['date'] = date2str(date)
            if exception is not None:
                write_transaction_element(exception_element, exception)
        write_transaction_element(recurrence_element, recurrence.ref)
    for budget in budgets:
        budget_element = ET.SubElement(root, 'budget')
        attrib = budget_element.attrib
        attrib['account'] = budget.account.name
        attrib['type'] = budget.repeat_type
        attrib['every'] = str(budget.repeat_every)
        attrib['amount'] = format_amount(budget.amount)
        attrib['notes'] = budget.notes
        if budget.target is not None:
            attrib['target'] = budget.target.name
        attrib['start_date'] = date2str(budget.start_date)
        if budget.stop_date is not None:
            attrib['stop_date'] = date2str(budget.stop_date)
    for elem in root.getiterator():
        attrib = elem.attrib
        for key, value in attrib.items():
            attrib[key] = remove_invalid_xml(value)
    tree = ET.ElementTree(root)
    ensure_folder(op.dirname(filename))
    fp = open(filename, 'wt', encoding='utf-8')
    fp.write('<?xml version="1.0" encoding="utf-8"?>\n')
    # This 'unicode' encoding thing is only available (and necessary) from Python 3.2
    if sys.version_info[1] >= 2:
        tree.write(fp, encoding='unicode')
    else:
        tree.write(fp)
Example #16
0
def save(filename, document_id, properties, accounts, groups, transactions, schedules, budgets):
    def date2str(date):
        return date.strftime('%Y-%m-%d')

    def handle_newlines(s):
        # etree doesn't correctly save newlines. In fields that allow it, we have to escape them so
        # that we can restore them during load.
        # XXX It seems like newer version of etree do escape newlines. When we use Python 3.2, we
        # can probably remove this.
        if not s:
            return s
        return s.replace('\n', '\\n')

    def setattrib(attribs, attribname, value):
        if value:
            attribs[attribname] = value

    def write_transaction_element(parent_element, transaction):
        transaction_element = ET.SubElement(parent_element, 'transaction')
        attrib = transaction_element.attrib
        attrib['date'] = date2str(transaction.date)
        setattrib(attrib, 'description', transaction.description)
        setattrib(attrib, 'payee', transaction.payee)
        setattrib(attrib, 'checkno', transaction.checkno)
        setattrib(attrib, 'notes', handle_newlines(transaction.notes))
        attrib['mtime'] = str(int(transaction.mtime))
        for split in transaction.splits:
            split_element = ET.SubElement(transaction_element, 'split')
            attrib = split_element.attrib
            attrib['account'] = split.account_name
            attrib['amount'] = format_amount(split.amount)
            setattrib(attrib, 'memo', split.memo)
            setattrib(attrib, 'reference', split.reference)
            if split.reconciliation_date is not None:
                attrib['reconciliation_date'] = date2str(split.reconciliation_date)

    root = ET.Element('moneyguru-file')
    root.attrib['document_id'] = document_id
    props_element = ET.SubElement(root, 'properties')
    for name, value in properties.items():
        if name == 'default_currency':
            value = value.code
        else:
            value = str(value)
        props_element.attrib[name] = value
    for group in groups:
        group_element = ET.SubElement(root, 'group')
        attrib = group_element.attrib
        attrib['name'] = group.name
        attrib['type'] = group.type
    for account in accounts:
        account_element = ET.SubElement(root, 'account')
        attrib = account_element.attrib
        attrib['name'] = account.name
        attrib['currency'] = account.currency.code
        attrib['type'] = account.type
        if account.group:
            attrib['group'] = account.group.name
        if account.reference is not None:
            attrib['reference'] = account.reference
        if account.account_number:
            attrib['account_number'] = account.account_number
        if account.inactive:
            attrib['inactive'] = 'y'
        if account.notes:
            attrib['notes'] = handle_newlines(account.notes)
    for transaction in transactions:
        write_transaction_element(root, transaction)
    # the functionality of the line below is untested because it's an optimisation
    scheduled = [s for s in schedules if s.is_alive]
    for recurrence in scheduled:
        recurrence_element = ET.SubElement(root, 'recurrence')
        attrib = recurrence_element.attrib
        attrib['type'] = recurrence.repeat_type
        attrib['every'] = str(recurrence.repeat_every)
        if recurrence.stop_date is not None:
            attrib['stop_date'] = date2str(recurrence.stop_date)
        for date, change in recurrence.date2globalchange.items():
            change_element = ET.SubElement(recurrence_element, 'change')
            change_element.attrib['date'] = date2str(date)
            if change is not None:
                write_transaction_element(change_element, change)
        for date, exception in recurrence.date2exception.items():
            exception_element = ET.SubElement(recurrence_element, 'exception')
            exception_element.attrib['date'] = date2str(date)
            if exception is not None:
                write_transaction_element(exception_element, exception)
        write_transaction_element(recurrence_element, recurrence.ref)
    for budget in budgets:
        budget_element = ET.SubElement(root, 'budget')
        attrib = budget_element.attrib
        attrib['account'] = budget.account.name
        attrib['type'] = budget.repeat_type
        attrib['every'] = str(budget.repeat_every)
        attrib['amount'] = format_amount(budget.amount)
        attrib['notes'] = budget.notes
        if budget.target is not None:
            attrib['target'] = budget.target.name
        attrib['start_date'] = date2str(budget.start_date)
        if budget.stop_date is not None:
            attrib['stop_date'] = date2str(budget.stop_date)
    for elem in root.getiterator():
        attrib = elem.attrib
        for key, value in attrib.items():
            attrib[key] = remove_invalid_xml(value)
    tree = ET.ElementTree(root)
    ensure_folder(op.dirname(filename))
    fp = open(filename, 'wt', encoding='utf-8')
    fp.write('<?xml version="1.0" encoding="utf-8"?>\n')
    # This 'unicode' encoding thing is only available (and necessary) from Python 3.2
    if sys.version_info[1] >= 2:
        tree.write(fp, encoding='unicode')
    else:
        tree.write(fp)