#! /usr/bin/python

#################################################
#  PyBuddyList v.0.2b
#
#  This software is open source and may
#  be used, modified, and redistributed 
#  free of charge...
#  for any non-commercial, non-profit
#  purposes provided these credits are
#  left intact, unedited.  This software 
#  comes with NO warrantee whatsoever, 
#  and the author, cylikon@hotmail.com, 
#  takes NO responsibility for any damages or
#  problems resulting from the use of this 
#  software. 
#
#  This is a Python script and requires you 
#  to have Python 2.2 or better installed.
#
#  Copyright April 2002 (cylikon@hotmail.com)
#  All rights reserved.
#################################################

import sys
import tkMessageBox 
import time
from threading import Thread,RLock
import string
from Tkinter import * 
import URLRead
import random
import thread
#from winsound import *

class buddy(Frame):
  def __init__(self, *args, **params):

    apply(Frame.__init__, (self,) + args, params)
    self._parent = None
    if len(args) != 0: self._parent = args[0]
    self.BUDDIES={}
    self.addWidgets()
    self.CUR_USER=None
    self.REFRESH_INT=75
    self.WATCHING=0
    self.MONITOR=RLock()
    self.stand_alone=0
    self.SOUND_FILE="DOOROPEN.WAV"
    

  def addWidgets(self):
    self.entry=StringVar(self)
    self.entry2=StringVar(self)
    self.entry.set("")
    self.entry2.set("")
    self._widgets = {}
    self._widgets['pframe'] = Frame(self, name='pframe', background='grey')
    self._widgets['pframe'].grid(column=1, row=3)
    self._widgets['uframe'] = Frame(self, name='uframe', background='grey')
    self._widgets['uframe'].grid(column=1, row=2, sticky='nesw')
    self._widgets['label#1'] = Label(self, name='label#1', background='blue', font='-*-MS Sans Serif-Bold-R-Normal-*-*-160-*-*-*-*-*-*', foreground='white', text='BP Buddy List')
    self._widgets['label#1'].grid(column=1, row=1, sticky='nesw')
    self._widgets['ulab'] = Label(self._widgets['uframe'], name='ulab', background='grey', foreground='black', text='Username:')
    self._widgets['ulab'].grid(column=1, row=1, sticky='nesw')
    self._widgets['label#3'] = Label(self._widgets['pframe'], name='label#3', background='grey', foreground='black', text='Password:')
    self._widgets['label#3'].grid(column=1, row=1, sticky='nesw')
    self._widgets['entry#1'] = Entry(self._widgets['uframe'], name='entry#1', textvariable=self.entry)
    self._widgets['entry#1'].grid(column=2, row=1, sticky='nesw')
    self._widgets['entry#2'] = Entry(self._widgets['pframe'], name='entry#2', textvariable=self.entry2)
    self._widgets['entry#2'].grid(column=2, row=1, sticky='nesw')
    self._widgets['logbutt'] = Button(self, name='logbutt', background='#696969', foreground='white', text='LOGIN', command=self.Login)
    self._widgets['logbutt'].grid(column=1, row=4, sticky='nesw')
    #self._widgets['lframe'] = Frame(self, name='lframe', background='white')
    #self._widgets['lframe'].grid(column=1, row=5,sticky='nesw')
    self._widgets['listbox#1'] = Listbox(self, name='listbox#1', foreground='black',background='#e6e6ff', height=0, width=0)
    self._widgets['listbox#1'].grid(column=1, row=5,sticky='nesw')
    #self._widgets['listbox#1'].pack(side=LEFT, fill=X)
    self._widgets['label#4'] = Label(self, name='label#4', background='#a60053', foreground='white', text='Ready.')
    self._widgets['label#4'].grid(column=1, row=6, sticky='nesw')
    ## Scroll commands

    ## Resize behavior(s)
    self["background"]="grey"
    self.grid_rowconfigure(5, weight=0, minsize=235)
    self.showTitle("BP Buddy List")
    try:
      self._widgets['entry#1'].insert(0,"PhrozenSmoke")
    except:
      pass
    self.addScroll()
    try:
      self.bind("<Destroy>",self.shutdown)
    except:
      pass
    try:
      self._parent.bind("<Destroy>",self.shutdown)
    except:
      pass

  def getRandom(self,_sequence):  # Dont use a Dictionary as _sequence
    return random.choice(_sequence)

  def Login(self):
    if self._widgets['entry#1'].get().strip() and self._widgets['entry#2'].get().strip():
      self.doLogin(self._widgets['entry#1'].get().strip(),self._widgets['entry#2'].get().strip())
    else:
      self.showMessage("Please enter a Username and Password first.")

  def doLogin(self,uname,pword):
    if uname and pword:
      self.showTitle("LOGGING IN...")
      self._widgets['label#4']["text"]="LOGGING IN..."
      uname=str(uname).strip()
      pword=str(pword).strip()
      _params={"OPERATION":"1","REMOTE_USER_PREF":"1","x":str(self.getRandom(range(90))),"y":str(self.getRandom(range(15))),"ALIAS":uname,"PASSWORD":pword}
      bp=str(URLRead.openUrl("http://www.blackplanet.com/auth.html",uname,0,_params,"http://www.blackplanet.com/",0))
      #print bp
      bp=bp.lower()
      bpstat=-1
      found=""
      bp_error=["blackplanet.com login","wrong username","re-enter your username","username and password","not logged in","not a member?","click here to register","forget your password?"]
      bp_succ=["pager.html","topnav3.html","the world is yours","/members/home/","no thanks"]
      for i in bp_error:
        if not bp.find(i)== -1:
          bpstat=0
          found=i
          break
      proof=0
      for i in bp_succ:
        if not bp.find(i)== -1:
          proof=1
          break
      if bpstat:
        if proof:
          self.showMessage("Login was successful for '"+uname+"'.")
        else:
          self.showMessage("Login was PROBABLY was successful for '"+uname+"'. No confirmation was found.\nSometimes BP shows ads instead of the login page.")
        self.CUR_USER=uname
        try:
          self._widgets['entry#2'].delete(0,self._widgets['entry#2'].index(5000))
        except:
          pass
        self.WATCHING=0
        self.startWatchThread()
      else:
        self.showError("Could not login!  Found: '"+found+"'")
      self.showTitle("BP Buddy List")
    

  def showStatus(self,statstr):
    self._widgets['label#4']["text"]=str(statstr)

  def getListBox(self):
    return self._widgets['listbox#1']

  def addScroll(self):
    self.scrollbary = Scrollbar(self._widgets['listbox#1'])
    self.scrollbary.pack(side=RIGHT, fill=Y)
    self.scrollbarx = Scrollbar(self._widgets['listbox#1'],orient="horizontal")
    self.scrollbarx.pack(side=BOTTOM, fill=X)
    self._widgets['listbox#1']["yscrollcommand"]=self.scrollbary.set
    self._widgets['listbox#1']["xscrollcommand"]=self.scrollbarx.set
    self.scrollbary.config(command=self._widgets['listbox#1'].yview)
    self.scrollbarx.config(command=self._widgets['listbox#1'].xview)
    """for i in range(50):
      self.getListBox().insert(0,str(i))"""

  def showTitle(self,TIT):
    try:
      self._parent.title(str(TIT))
    except:
      pass

  def showMessage(self,mess):
    tkMessageBox.showinfo("Buddy List",str(mess)) 

  def addBuddy(self,bname):
    if self.BUDDIES.has_key(bname):
      return None
    else:
      self.BUDDIES[bname]="NEW"
      return 1

  def checkBuddy(self,bname):
    if self.BUDDIES.has_key(bname):
      if self.BUDDIES[bname]=="NEW":
        return bname+" **"
      else:
        return bname
    return bname

  def updateBuddyList(self):
    if not self.CUR_USER:
      return
    bdata=URLRead.openUrl("http://find.blackplanet.com/online.html",self.CUR_USER,1,{},"http://find.blackplanet.com/",0)
    blist=string.split(bdata,"Members.BlackPlanet.com/")
    if not len(blist):
      blist=string.split(bdata.lower(),"Members.BlackPlanet.com/".lower())
    if len(blist):
      flist=[]
      for i in blist:
        ndata=str(i)
        if not ndata.find("/") == -1:
          if not ndata.lower().find("target") == -1:
            flist.append(ndata[0:ndata.find("/")].strip())
      if len(flist):
        #Mark all existing names as no-longer new
        for i,j in self.BUDDIES.items():
          self.BUDDIES[i]="1"
        for i in self.BUDDIES.keys():
          if not i in flist:
            del self.BUDDIES[i]
        self.getListBox().delete(0,END)  
        try:
          self.getListBox().delete(0,END) 
          self.getListBox().delete(0,END) 
          self.getListBox().delete(0,END) 
        except:
          pass
        some_new=0
        for i in flist:
          b=self.addBuddy(i)
          if not some_new:
            some_new=b     
          self.getListBox().insert(0,str(self.checkBuddy(i)))  
        if some_new:  # might want to play a sound here
          try:
            #PlaySound(self.SOUND_FILE,SND_ASYNC)
            gggkg=2
          except:
            pass
    else:
      self.getListBox().delete(0,END)  
      self.BUDDIES.clear()
    self.showBuddyCount()


  def doWatch(self):
    try:
      if self.CUR_USER:
        self.MONITOR.acquire()
        self.WATCHING=1
        while self.WATCHING and self.CUR_USER:
          self._widgets['label#4']["text"]="Updating..."
          self.updateBuddyList()
          self._widgets['label#4']["text"]="Ready."
          i=0
          while i < self.REFRESH_INT:          
            if self.WATCHING and self.CUR_USER:
              time.sleep(1)
              i=i+1
            else:
              break
     
    finally:
      self._widgets['label#4']["text"]="Ready."
      self.MONITOR.release()



  def startWatchThread(self):
    thread.start_new_thread(self.doWatch,())

  def showBuddyCount(self):
    self.getListBox().insert(0," ")
    self.getListBox().insert(0,"BUDDIES ONLINE: "+str(len(self.BUDDIES)))

  def shutdown(self,evt):
    self._widgets['label#4']["text"]="SHUTTING DOWN..."
    self.WATCHING=0
    time.sleep(1)
    """try:
      self._parent.destroy()
    except:
      pass
    if self.stand_alone:
      sys.exit(0)"""



def runit():
  root = Tk()
  o = buddy(root)
  o.pack(side=TOP, fill=BOTH, expand=1)
  o.stand_alone=1
  root.mainloop()

if __name__ == '__main__':
  runit()
