""" XML-RPC connector for upcdatabase.com. This connector allows thoughtandmemory to query upcdatabase for UPC lookups. ----- upcdatabase API Documentation (result of help() ): help - returns string Show available functions and their parameters. lookupEAN(ean string) - returns struct Lookup upc database entry. convertUPCE(upce string) - returns string Parameter 'upce' should be exactly 8 digits. Returns full EAN-13. All 'upc' parameters should be 12 digits long. All 'ean' parameters should be 13 digits long. """ """ Test Data from UPC Search: 0034000213108 Herseys minitures assorted candies 15.0 fl oz 15.4 oz Jun 19 2001 Result from XML-RPC: { 'description': 'Herseys minitures assorted candies 15.0 fl oz', 'ean': '0034000213108', 'lastModified': '2001-06-19 17:29:52', 'upc': '034000213108', 'isCoupon': False, 'pendingUpdates': 0, 'mfrGLN': '0340001010098', 'found': True, 'message': 'Database entry found', 'size': '15.4 oz', 'issuerCountry': 'United States', 'issuerCountryCode': 'us' } """ class EANException(Exception): pass import xmlrpclib import logging log = logging.getLogger('upcdatabase: ') server = 'http://www.upcdatabase.com/rpc' upcdb = xmlrpclib.Server(server) def lookupProduct(product=None): """ @type product: String @param product: EAN (13 digits) or UPCE (8 digits) @rtype: dict @returns: {'found':False} if no product found; otherwise something like: { 'description': 'Herseys minitures assorted candies 15.0 fl oz', 'ean': '0034000213108', 'lastModified': '2001-06-19 17:29:52', 'upc': '034000213108', 'isCoupon': False, 'pendingUpdates': 0, 'mfrGLN': '0340001010098', 'found': True, 'message': 'Database entry found', 'size': '15.4 oz', 'issuerCountry': 'United States', 'issuerCountryCode': 'us' } """ if product is None: raise TypeError('No argument given. Please provide an EAN (13 digits) or UPCE (8 digits)') if type(product) is not type(str()): #FIXME: or unicode() raise TypeError('Please provide an EAN (13 digits) or UPCE (8 digits) as a string') #good inputs, process them if len(product) is 8: #assume its a UPCE which needs to be converted ean = upcdb.convertUPCE(product) log.info('Converted UPCE %s to EAN %s' % (product, ean)) #kinda ugly but the next clause tests 'product' so just set it to our new EAN product = ean if len(product) is 13: #assume its a EAN and look it up result = upcdb.lookupEAN(product) else: #wrong length argument, don't bother trying to look it up #FIXME: pick a better exception type raise EANException('Please provide an EAN (13 digits) or UPCE (8 digits)') if type(result) is type(dict()): if result['found'] is False: msg = 'Look up found no entry for EAN %s' % (product) log.warning(msg) raise EANException(msg) result = None return result else: return None def test(): """ call test to see how the interface works and what output is returned by upcdatabase """ #valid EAN, valid EAN, valid EAN but no product, UPCE, too short upcs = ('0034000213108', '0034000315000', '0000000000000', '02349036', '000') print upcdb.help() #look up some test EANs, UPCEs and junk through the xml-rpc interface for upc in upcs: print upcdb.lookupEAN(upc) print '' #now do it again thru our module for upc in upcs: print lookupProduct(upc) print '' #if the file is executed run main, otherwise it is treated like a module and can be imported #note that __main__ should not do things that are needed if this is used as a module. if __name__ == '__main__': test()