#!/usr/bin/env python

"""
 macupdatelib.py
 
 Python library for take downloads informazion of 
 software inserted in MacUpdate database.
	
 Copyright (C) 2000-2004 Michele Ferretti
 black.bird@tiscali.it
 http://www.blackbirdblog.it

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or any later version.

 This program 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
		
 The library introduces 3 access method:
 	* searchByName()
 	* getById()
 	* getFromUrl()
 	
 Example:
 	>> import macupdatelib
 	>> ma = MacUpdateDownloads()
 	>> soft = ma.searchByName('HTML Tidy 1.1')
 	>> soft.downloads
 	>> 1197
	
"""

import urllib
import urllib2
import re

__author__ = 'Michele Ferretti'
__version__ = '1.0'


macupdate_search_url 	= 'http://www.macupdate.com/search.php?keywords=%s'
macupdate_info_url 		= 'http://www.macupdate.com/info.php/id/%s'

re_notfound				= r'Sorry, no results where found with the keywords'
re_results				= r'Search Results for'

re_get_name				= r'<title>(.*) [\.0-9a-z]+ - MacUpdate</title>'
re_get_version			= r'<title>.* (.*) - MacUpdate</title>'
re_get_downloads		= r'<tr><td> <b>Downloads</b>: </td><td> (.*)</td></tr>'


class MacUpdateDownloads:
	"""Class for get number of downloads for software inserted in MacUpdate database."""
	
	def __init__(self):
		pass
		
	def searchByName(self, software_name):
		"""Get SoftwareInfo by software name"""
		data = self._fetch_data(macupdate_search_url % urllib.quote(software_name) )
		
		if self._is_found(data):
			raise SoftwareNotFound('Software "%s" not found' % software_name)

		return self._parse_details(data)
		
	def getById(self, software_id):
		"""Get SoftwareInfo by software id"""
		data = self._fetch_data(macupdate_info_url % urllib.quote(software_id))
		return self._parse_details(data)

	def getFromUrl(self, software_details_url):
		"""Get SoftwareInfo from Url"""
		data = self._fetch_data(software_details_url)
		return self._parse_details(data)
		
	def _parse_details(self, data):
		"""Parse detail info"""
		name 		= self._get_re_result(re_get_name, data)
		version 	= self._get_re_result(re_get_version, data)
		downloads 	= self._get_re_result(re_get_downloads, data)
		return SoftwareInfo(name, version, downloads)
		
	def _get_re_result(self, re_string, search_data):
		"""Apply regular expression and return the result"""
		match = re.compile(re_string).search(search_data)
		if match:
			return match.group(1).strip()
		
	def _is_found(self, data):
		"""Check software is found"""
		return re.compile(re_notfound).search(data) or re.compile(re_results).search(data)
		
	def _fetch_data(self, url):
		"""Fetch data from url"""
		return urllib2.urlopen(url).read()
		
		
class SoftwareInfo:
	"""Software info container"""
	def __init__(self, name, version, downloads):
		self.name		= name
		self.version	= version
		self.downloads	= downloads
	
	
class SoftwareNotFound(Exception):
	"""Software not found exception"""
	pass
	
		
if __name__ == '__main__':
	
	print 'MacUpdate Library %s' % __version__
	print 'Control downloads software on MacUpdate.com'
	print 
	
	mad = MacUpdateDownloads()
	soft = mad.searchByName(raw_input('Software name: '))
	
	print 'The software %s have %s downloads.' % (soft.name, soft.downloads) 
	
	
