Changeset - f52920fe83b5
[Not reviewed]
0 2 1
Lance Edgar (lance) - 12 years ago 2013-02-25 15:08:58
lance@edbob.org
Added Palm OS app interface.

This commit adds the Palm HotSync conduit, which is used to create CSV
files when a handheld running the Rattail app is synced with its
desktop PC.
3 files changed with 219 insertions and 0 deletions:
0 comments (0 inline, 0 general)
rattail/commands.py
Show inline comments
 
@@ -117,12 +117,57 @@ class LoadHostDataCommand(commands.Subcommand):
 
            return
 

	
 
        proc = load.LoadProcessor()
 
        proc.load_all_data(edbob.engines['host'], Progress)
 

	
 

	
 
class PalmCommand(commands.Subcommand):
 
    """
 
    Manages registration for the Hotsync Manager conduit; called as::
 

	
 
       rattail palm
 
    """
 

	
 
    name = 'palm'
 
    description = "Manage the Hotsync Manager conduit registration"
 

	
 
    def add_parser_args(self, parser):
 
        subparsers = parser.add_subparsers(title='subcommands')
 

	
 
        register = subparsers.add_parser('register', help="Register Rattail conduit")
 
        register.set_defaults(subcommand='register')
 

	
 
        unregister = subparsers.add_parser('unregister', help="Unregister Rattail conduit")
 
        unregister.set_defaults(subcommand='unregister')
 

	
 
    def run(self, args):
 
        from rattail import palm
 

	
 
        if args.subcommand == 'register':
 

	
 
            # Generate Python module to support Palm Classic Database type library.
 
            from win32com.client import gencache
 
            gencache.EnsureModule('{6FD7A7A0-FA1F-11D2-AC32-006008E3F0A2}', 0, 1, 0)
 

	
 
            # Register conduit's COM server.
 
            from win32com.server.register import RegisterClasses
 
            RegisterClasses(palm.PalmConduit)
 

	
 
            # Register conduit with Hotsync Manager.
 
            palm.register_conduit()
 

	
 
        elif args.subcommand == 'unregister':
 

	
 
            # Unregister conduit from Hotsync Manager.
 
            palm.unregister_conduit()
 

	
 
            # Unregister conduit's COM server.
 
            from win32com.server.register import UnregisterClasses
 
            UnregisterClasses(palm.PalmConduit)
 
            
 

	
 
def main(*args):
 
    """
 
    The primary entry point for the Rattail command system.
 
    """
 

	
 
    if args:
rattail/palm.py
Show inline comments
 
new file 100644
 
#!/usr/bin/env python
 
# -*- coding: utf-8  -*-
 
################################################################################
 
#
 
#  Rattail -- Retail Software Framework
 
#  Copyright © 2010-2012 Lance Edgar
 
#
 
#  This file is part of Rattail.
 
#
 
#  Rattail is free software: you can redistribute it and/or modify it under the
 
#  terms of the GNU Affero General Public License as published by the Free
 
#  Software Foundation, either version 3 of the License, or (at your option)
 
#  any later version.
 
#
 
#  Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
 
#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
#  FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
 
#  more details.
 
#
 
#  You should have received a copy of the GNU Affero General Public License
 
#  along with Rattail.  If not, see <http://www.gnu.org/licenses/>.
 
#
 
################################################################################
 

	
 
"""
 
``rattail.palm`` -- Palm OS Application Interface
 
"""
 

	
 
import os
 
import os.path
 
import socket
 
import getpass
 
import datetime
 
import logging
 

	
 
import edbob
 

	
 
import rattail
 
from rattail.csvutil import DictWriter
 

	
 
# Hack for docs' sake (building on Linux).
 
try:
 
    import pythoncom
 
except ImportError:
 
    pythoncom = object()
 
    pythoncom.CLSCTX_LOCAL_SERVER = 4
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class PalmConduit(object):
 
    """
 
    Implements a conduit for Palm's Hotsync Manager.
 
    """
 

	
 
    _reg_clsid_ = '{F2FDDEEC-254F-42C3-8801-C41E8A243F13}'
 
    _reg_progid_ = 'Rattail.PalmConduit'
 
    _reg_desc_ = "Rattail Conduit for Palm Hotsync Manager"
 

	
 
    # Don't let pythoncom guess this, for several reasons.  This way Python
 
    # will go about determining its path etc. as normal, and __name__ will be
 
    # "rattail.palm" instead of just "palm".
 
    _reg_class_spec_ = 'rattail.palm.PalmConduit'
 

	
 
    # Don't let Hotsync Manager run our code in-process, so that we may launch
 
    # wxPython dialogs as needed for configuration etc.
 
    _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER
 

	
 
    _typelib_guid_ = '{6FD7A7A0-FA1F-11D2-AC32-006008E3F0A2}'
 
    _typelib_version_ = 1, 0
 
    _com_interfaces_ = ['IPDClientNotify']
 

	
 
    _public_methods_ = ['BeginProcess', 'CfgConduit',
 
                        'ConfigureConduit', 'GetConduitInfo']
 

	
 
    def BeginProcess(self):
 
        """
 
        Called by Hotsync Manager when synchronization is ready to happen.
 
        This method implements the actual data sync.
 
        """
 

	
 
        from win32com.client import Dispatch
 

	
 
        edbob.init('rattail')
 
        data_dir = edbob.config.require('rattail.palm', 'collection_dir')
 
        if not os.path.exists(data_dir):
 
            os.makedirs(data_dir)
 

	
 
        db_query = Dispatch('PDDirect.PDDatabaseQuery')
 
        db = db_query.OpenRecordDatabase('Rattail_Scan', 'PDDirect.PDRecordAdapter')
 
        if db.RecordCount:
 
            
 
            sys_adapter = Dispatch('PDDirect.PDSystemAdapter')
 
            fname = '%s,%s,%s,%s.csv' % (socket.gethostname(), getpass.getuser(),
 
                                         sys_adapter.PDUserInfo.UserName,
 
                                         datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S'))
 
            data_path = os.path.join(data_dir, fname)
 
            log.info("PalmConduit.BeginProcess: writing %u handheld records to file: %s" %
 
                     (db.RecordCount, data_path))
 

	
 
            data_file = open(data_path, 'wb')
 
            writer = DictWriter(data_file, ['upc', 'cases', 'units'])
 
            writer.writeheader()
 
            for i in range(db.RecordCount):
 
                rec, unique_id, category, attrs = db.ReadByIndex(i)
 

	
 
                writer.writerow({
 
                        'upc': rec[:15].rstrip('\x00'),
 
                        'cases': rec[15:19].rstrip('\x00'),
 
                        'units': rec[19:23].rstrip('\x00'),
 
                        })
 

	
 
            data_file.close()
 

	
 
            log.info("PalmConduit.BeginProcess: removing all records from handheld")
 
            db.RemoveSet(0)
 
            log.info("PalmConduit.BeginProcess: done")
 

	
 
        else:
 
            log.info("PalmConduit.BeginProcess: nothing to do")
 

	
 
        return False
 

	
 
    def CfgConduit(self, nCreatorId, nUserId, bstrUserName, bstrPathName,
 
                   nSyncPerm, nSyncTemp, nSyncNew, nSyncPref):
 
        pass
 

	
 
    def ConfigureConduit(self, pPathName, pRegistry, nSyncPref, nSyncType):
 
        pass
 

	
 
    def GetConduitInfo(self, infoType, dwCreatorID, dwUserID, bstrUsername):
 
        return None
 

	
 

	
 
def register_conduit():
 
    """
 
    Registers the conduit with Palm Hotsync Manager.
 
    """
 

	
 
    import pywintypes
 
    from win32com.client import Dispatch
 

	
 
    conduit_mgr = Dispatch('PDStandard.PDSystemCondMgr')
 
    creator_id = conduit_mgr.StringToCreatorID('RTTL')
 
    assert creator_id
 

	
 
    try:
 
        info = conduit_mgr.GetConduitInfo(creator_id)
 
    except pywintypes.com_error:
 
        pass
 
    else:
 
        return # already registered
 

	
 
    info = Dispatch('PDStandard.PDConduitInfo')
 
    info.COMClassID = 'Rattail.PalmConduit'
 
    info.CreatorID = creator_id
 
    info.DesktopDataDirectory = 'Rattail'
 
    info.DisplayName = 'Rattail'
 
    conduit_mgr.RegisterConduit(info)
 

	
 

	
 
def unregister_conduit():
 
    """
 
    Unregisters the conduit from Hotsync Manager.
 
    """
 

	
 
    from win32com.client import Dispatch
 

	
 
    conduit_mgr = Dispatch('PDStandard.PDSystemCondMgr')
 
    creator_id = conduit_mgr.StringToCreatorID('RTTL')
 
    assert creator_id
 
    conduit_mgr.UnregisterConduit(creator_id)
setup.py
Show inline comments
 
@@ -112,12 +112,13 @@ rattailw = rattail.commands:main
 
rattail = rattail.db.extension:RattailExtension
 

	
 
[rattail.commands]
 
dbsync = rattail.commands:DatabaseSyncCommand
 
filemon = rattail.commands:FileMonitorCommand
 
load-host-data = rattail.commands:LoadHostDataCommand
 
palm = rattail.commands:PalmCommand
 

	
 
[rattail.batches.providers]
 
print_labels = rattail.batches.providers.labels:PrintLabels
 

	
 
[rattail.sil.column_providers]
 
rattail = rattail.sil.columns:provide_columns
0 comments (0 inline, 0 general)