#! /usr/bin/python

"""	newsList.py

	This is an outgrowth of a very earlier effort for me.

	newsList defines the newsList class, a collection pattern for news
	objects, objects (defined in the news.py module) that represent a
	single news item or "blurb" or weblog entry.

	Author:  Patrick Curtain <patrick at swdev.com>

	$Id: newsList.py,v 1.3 2001/02/18 06:12:16 patrick Exp $

	"""

import os, sys, string, cgi, time, pickle, glob, re, traceback

# import the module containing the definition of the news item
# object
sys.path.insert(0, os.getcwd())
import news

endl = os.linesep

docRoot = '/home/swdev/public_html'
if sys.platform == 'win32':
	docRoot = 'e:\\home\\httpd\\html'
elif sys.platform == 'mac':
	docRoot = 'macshare:html:swdev.com'
elif sys.platform in ['Darwin1.2', 'next']:
	docRoot = '/html'

_themesDir = docRoot + os.sep + 'themes' + os.sep + 'news' + os.sep
xmlDir = docRoot + os.sep + 'WeBlog' + os.sep + 'news' + os.sep
shelveDir = xmlDir + 'shelve' + os.sep

_dateTable = """
<TABLE WIDTH="95%%" BGCOLOR="#000000"><TR><TD ALIGN="RIGHT">
<FONT COLOR="WHITE"><B>%s</B></FONT>
</TD></TR></TABLE>
"""

TRUE = 1
FALSE = None 

max = 10	# set a default

class newsList:
	""" abstracts the behaviors around the whole list of news objects
		defined by news.py, acting as a list. """
	
	_list = [ ]
	max = 20
	topic = 'all'
	format = 'page'
	todayString = ''
	
	def __init__(self, dir=shelveDir):
		if dir:
			_dir = dir
		self.populateList(dir)
		timeNow = time.localtime( time.time() )
		self.todayString = time.strftime('%Y%m%d', timeNow)

	def __len__(self):
		if self._list:
			return len(self._list)

	def __getitem__(self, key):
		if self._list:
			return self._list[key]
	
	def __setitem__(self, key, value):
		if self._list:
			self._list[key] = value
			return self._list[key]
	
	def __delitem__(self, key):
		if self._list:
			del self._list[key]

	def __getslice__(self, i, j):
		if self._list:
			return self._list[i:j]
	
	def populateList(self, dir=shelveDir):
		filespec = shelveDir + "*" 
		newsFiles = glob.glob(filespec) 
		newsFiles.sort()		# ensure *some* order 
		newsFiles.reverse()		# now get the reverse, so newest is first

		for pfilename in newsFiles:
			pickleFile = open(pfilename, 'r')
			ni = pickle.load(pickleFile)
			self._list.append(ni)

		return self._list

	def getLength(self):
		"""
		listLength = len(self._list)
		self.setMax(self.max)
		return listLength
		"""
		
		return len(self._list)
	
	def setTopic(self, topic=''):
		self.topic=topic or self.topic
		newList = [ ]
		if self._list:
		 	for ni in self._list:
		 		if ni._category == self.topic:
		 			newList.append(ni)
		if newList:
			self._list = [ ]
			self._list = newList

	def setMax(self, max=20):
		max = max or self.max
		totalItems = len(self._list)
		if max >= totalItems:
			self.max=totalItems
		else:
			self.max=max

	def setFormat(self, fmt=''):
		self.format = fmt or self.format

	def search(self, searchstr=''):
		"""	Search the current list for any blurb containg the searchstr, 
			either in it's title, or it's body.
			"""
		if searchstr:
			newList = [ ]
			if self._list:
				for ni in self._list:
					if ni.contains(searchstr):
						newList.append(ni)
			if newList:
				self._list = [ ]
				self._list = newList

	def listForTopic(self, topic= ''):
		topic = topic or self.topic
		self.setTopic(topic)
		if self.topic <> 'all':
			# chase through, removing those that aren't part of the topic.
			topicList = [ ]
			for item in self._list:
				if item._category == topic:
					topicList.append(item)
			self._list = topicList
		return self._list
		
	def settingsComment(self):
		str = """
				<!--	newsList instance settings
						the value of format: %s
						the value of max:    %s
						the value of topic:  %s
						-->\n"""
		return str % (self.format, self.max, self.topic)
			
	def asHTML(self, fmt='', max=0, topic=''):
		self.setFormat(fmt)
		self.setMax(max)
		self.setTopic(topic)
		
		if self._list:
			if self.format == 'list':
				return self.list_html()
			if self.format == 'summary':
				return self.summary_html()
			if self.format == 'page':
				return self.index_html()
		else:
			htmlStr = "Content-type: text/html\n\n <h1>no items found</h2>"
			return htmlStr

	def list_html(self):
		str = "Content-type: text/html" + endl*2
		nlComment = self.settingsComment()
		str = str + nlComment
		i = 0
		for i in range(self.max - 1):
			ni = self._list[i]
			thisDate = ni.getDateComparableStr()
			commentLine = "<!-- newsFile: %s -->" % ni._filename
			summaryLine = ni.summaryLine() + "<BR>"
			str = str + commentLine + endl
			str = str + summaryLine + endl
			
		return str

	def listTable_html(self):
		str = "Content-type: text/html" + endl
		i = 0
		for i in range(self.max - 1):
			ni = self._list[i]
			thisDate = ni.getDateComparableStr()
			commentLine = "<!-- newsFile: %s -->" % ni._filename
			summaryLine = ni.summaryLine()
			str = str + commentLine + endl
			str = str + summaryLine + endl
			
		return str
		
	def summary_html(self):
		str = "Content-type: text/html" + endl
		str = str + self.settingsComment()
		lastDate = self.todayString
		i = 0
		for i in range(self.max - 1):
			ni = self._list[i]
			thisDate = ni.getDateComparableStr()
			summaryRow = ni.summaryRow()
			commentLine = "<!-- newsFile: %s -->" % ni._filename
			str = str + commentLine + endl
			str = str + summaryRow
			
		return str

	
	def index_html(self):
		str = """Content-type: text/html"""
		str = str + endl*2

		totalItems = self.getLength()

		newsHead = open(_themesDir + 'newsHead.html', 'r').read()
		str = str + newsHead
		str = str + self.settingsComment()
		
		if self.topic <> 'all':
			topicName = news.getTopicName(self.topic)
			_topicLine = open(_themesDir + 'topicTable.html', 'r').read()
			topicStr = _topicLine % topicName
			str = str + topicStr
		
		lastDate = self.todayString
		i = 0
		displayed = 0
		for i in range(self.max):
			ni = self._list[i]
			thisDate = ni.getDateComparableStr()
			if thisDate < lastDate:
				shortDate = thisDate[4:6]+'/'+thisDate[-2:]+'/'+thisDate[:4]
				str = str + _dateTable % shortDate + endl
				lastDate = thisDate
			commentLine = "<!-- newsFile: %s -->" % ni._filename
			newsString = ni.asTable()
			str = str + commentLine + endl
			str = str + newsString
			str = str + endl
			str = str + "<!-- end that one.  -->" + endl
			displayed = displayed + 1
			
		str = str + """<P ALIGN="RIGHT"><FONT SIZE=-1>"""
		str = str + "[displaying %s of %s total items]" % (`displayed`, `totalItems`)
		str = str + '</FONT><br>' + endl
		
		if displayed < totalItems:
			argString = 'fmt=page&max=%s&topic=%s' % (totalItems, self.topic)
			continueString = """
					for the complete list of items, click
					<A HREF="/WeBlog/nl.cgi?%s">here</a>
					</P>""" % argString
			str = str + continueString

		str = str + """
					<P align="LEFT">  
					python <a href="newsList_py.html">source</a> for this page.
					</P>"""

		titlesList = [ ]
		for i in range(len(self._list) - 1):
			ni = self._list[i]
			line = ni.summaryLine() + "<BR>"
			titlesList.append(line)
		_newsFoot = open( _themesDir + 'newsFoot.html', 'r').read()
		str = str + _newsFoot % { "EntriesList": string.join(titlesList) }
		
		return str
		

def getNewsObjects(topic='all'):
	nl = newsList()
	if topic == 'all':
		return nl
	else:
		l = nl.listForTopic(topic)
		return l

if __name__ == '__main__': 
	
	if sys.platform != 'mac':
		sys.stderr = sys.stdout

	try:
		nl = newsList()
		print "Got a news list with %d items." % len(nl)
	except:
		print "oops!"