![]() |
ToppyBiff is a concept for a new style of Topfield TAP. Imagine your Toppy alerting you to new information from the internet:
... or any other timestamped small snippet of read-only information which you might want to be alerted to by a discreet icon on your television screen, upon which you can click to see the information (and have it disappear after you have read it). Along the bottom edge of your TV screen (or top edge, a configurable option), there would be a row of icons each of which would contain an optional text string or number (e.g. to indicate the number of unread messages) - the icon would represent the type of information being presented: email, stocks, news, syslog, etc. A single click on the enter key on the remote would put you in selection mode and highlight the first icon, another enter would put you in reading mode and present the first unread message associated with that selected icon, and yet another enter would present the next unread message of that type. If no more were unread, that icon would disappear, and the next icon would be highlighted, ready for reading by hitting the enter key. You would be able to move the highlight on a row of icons to the left and right using the arrow keys whilst in the selection mode. Exit would exit the selection mode. Information would be uploaded to the ToppyBiff TAP via the well-known TGD format to a specific filename known by the TAP. All messages would be contained in the one single file. The file would be completely overwritten on each upload. Messages have (at a minimum) a date and timestamp, a message type, a subject, and a message body. The TAP would maintain a separate file containing the date and timestamp, message type and subject of recent messages which have been read. This excludes the need to have a reverse flow of information from the toppy back to the source computer. If an entry in the "read messages" file is dated earlier than the earliest message in the latest upload file, then it can be removed. If an entry in the "read messages" file corresponds to an entry in the latest upload file, then the entry in the upload file is identified as "read" by the TAP. If an entry in the latest upload file does not correspond to any entry in the "read messages" file, then the entry in the upload file is identified as "unread" by the TAP. Here is the mapping of TGD file formats to ToppyBiff fields: service_name: Message type Two threads discussing the older beta versions of EPG_uploader3 that supports some of this functionality: http://www.topfield-australia.com.au/frm/topic.asp?TOPIC_ID=3122 http://www.topfield-australia.com.au/frm/topic.asp?TOPIC_ID=3195 Release 3.3 and above of the EPG_uploader TAP work best for Toppybiff, with improved reader and different volume levels for the notification supported, download it here: http://tonyspage.abock.de Some images from Toppybiff: Email icon that pops up when a pending message/messages are there to read: ![]() The list shown when the OK is hit: ![]() The first page of a message when OK is hit: ![]() The second page of a message when OK is hit: ![]() A thread that discusses how these were created here: http://www.topfield-australia.com.au/frm/topic.asp?TOPIC_ID=5166 The images above demonstrate running Outlook an outlook script to display Toppybiff messages on the Toppy. Create VisualBasic? script in Outlook by simply Alt-F11 while in Outlook and paste the following (thanks Adam_G for the code):
' These scripts were written to take advantage of ToppyBIFF
'(http://www.nslu2-linux.org/wiki/Puppy/ToppyBiff)
' ToppyBiff allows your TV (if it is using a Topfield personal Video Recorder)
' to display a notification on the screen of receiving an email. You can then
' view the email text on your TV
'
' When a new email arrives the first script formats the message and creates a 99999997.tgd
' message file
' When a reminder occurs the second script creates a message file
'
' These scripts use TFCopy (http://www.8ung.at/aldarin/tools.html) to transfer
' the message file to the Topfield.
'
'
' To use the scripts download TFCopy and modify the Const statement below to point
' to the location of TFCopy.exe
'
' Roger Morton has modified the scripts to use FTP to transfer the files.
' This is useful if you run the FTP server for topfield application (as you do if running
' toppy web [a web interface to the Topfield PVR]
' To use the FTP modify the serverName,UserName and Password vars in the FTPFileToToppy
' Sub to be the appropriate values for the FTP server for Topfield of your setup.
' The code uses PASSIVE mode in the FTP process because RLM needed this.
' I discovered I needed passive mode when WS_FTP complained about "Blocking call cancelled"
' The weird thing is that I only get the "Blocking call cancelled" sometimes.
' But when I do setting FTP to passive mode seems to fix it.
' see http://www.ftpplanet.com/ftpresources/ftp_faq.html
' If you don't want to use Passive mode then in the FTPFileToToppy() function
' replace INTERNET_FLAG_PASSIVE in the
' InternetConnect() call with 0 [zero]
'
' To use this code:
' Open Outlook and press <ALT>F11 to open the Visual Basic editor, navigate to the
' ThisOutlookSession and past this entire code
'
' You will need EPGuploader (http://tonyspage.abock.de/) version 3 BETA or
' later for ToppyBIFF support
'
' Thanks to Tony (http://tonyspage.abock.de/) for writing and maintaining EPGuploader which at the time of this writing is the
' only Topfield TAP with ToppyBIFF support.
' Thanks also to Gary (Jammer) for his help with testing and enhancing these scripts.
'
' Adam_G April 30th 2006
'
' Topfield Australia forums - http://www.topfield-australia.com.au/frm/default.asp
'
'
'
Option Explicit
'
' InternetOpen Initializes an application's use of the WinINet functions.
Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" _
(ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, _
ByVal sProxyBypass As String, ByVal lFlags As Long) As Long
' Connect to the network
Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" _
(ByVal hInternetSession As Long, ByVal sServerName As String, _
ByVal nServerPort As Integer, ByVal sUsername As String, _
ByVal sPassword As String, ByVal lService As Long, _
ByVal lFlags As Long, ByVal lContext As Long) As Long
' Get a file using FTP
Private Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" _
(ByVal hFtpSession As Long, ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Long, ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
' dwFlagsAndAttributes is File attributes for the new file.
' This parameter can be any combination of the FILE_ATTRIBUTE_* flags used by the CreateFile function.
' dwContext is a pointer to a variable that contains the application-defined value that associates this search
' with any application data. This is used only if the application has already called InternetSetStatusCallback
' to set up a status callback function.
' good site for constants and other API references
' http://www.earlsoft.co.uk/api/
Const FILE_ATTRIBUTE_READONLY As Long = 1 '10x1
Const FILE_ATTRIBUTE_HIDDEN As Long = 2 ' 20x2
Const FILE_ATTRIBUTE_SYSTEM As Long = 4 ' 40x4
Const FILE_ATTRIBUTE_ARCHIVE As Long = 32 ' 320x20
Const FILE_ATTRIBUTE_NORMAL As Long = 128 '1280x80
Const FILE_ATTRIBUTE_TEMPORARY As Long = 256 '2560x100
Const INTERNET_FLAG_PASSIVE As Long = &H8000000
Const INTERNET_SERVICE_FTP As Long = 1
Const INTERNET_DEFAULT_FTP_PORT As Long = 21
'
' Send a file using FTP
Private Declare Function FtpPutFile Lib "wininet.dll" Alias "FtpPutFileA" _
(ByVal hFtpSession As Long, ByVal lpszLocalFile As String, _
ByVal lpszRemoteFile As String, ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
' Close the Internet object
Private Declare Function InternetCloseHandle Lib "wininet.dll" _
(ByVal hInet As Long) As Integer
Const MessageFile As String = "C:\temp\99999997.tgd" ' This can be any locally accessible location, the file name must remain as 99999997.tgd
Const TFCopyEXEPath As String = "c:\tfcopy\tfcopy.exe" ' This is where you have installed TFCopy
Const MessageFileDestinationPath As String = "#:\EPGdata\99999997.tgd" ' This is the location on the Toppy where the tgd file should be copied to
Private Sub Application_NewMail()
'On Error Resume Next
Dim currentNameSpace As NameSpace
Dim currentMAPIFolder As MAPIFolder
Dim SecondaryMAPIFolder As MAPIFolder
Dim currentMailItem As MailItem
Dim newBody As String
Dim WAIT As Double, blnFTPResult As Boolean
Set currentNameSpace = Application.GetNamespace("MAPI")
Set currentMAPIFolder = currentNameSpace.GetDefaultFolder(olFolderInbox) ' Select the default mail delivery folder
' if you want to check another mail boxes then specify a secondary mail box like this
' I have a mail box calle Agbioview underneath the main mail box called "Personal Folders"
' vvvvvvv commment this out if you only want to read the inbox
Set SecondaryMAPIFolder = currentNameSpace.Folders("Personal Folders").Folders("Agbioview")
If FileExists(MessageFile) Then Kill MessageFile ' Delete the old 99999997.tgd file
Open MessageFile For Output Shared As #1
For Each currentMailItem In currentMAPIFolder.Items.Restrict("[UnRead]=True") ' Check each mail item marked as unread
newBody = Replace(currentMailItem.Body, Chr(13), "<br>") ' Replace CR with tag
newBody = Replace(newBody, Chr(10), "<br>") ' Replace LF with tag
newBody = Replace(newBody, Chr(9), " ") ' Replace TAB with spaces
Print #1, "Email" & Chr(9) & Format(currentMailItem.ReceivedTime, "yyyy/mm/dd hh:mm") & _
Chr(9) & " " & Chr(9) & currentMailItem.Subject & Chr(9) & currentMailItem.SenderName & _
Chr(9) & newBody & Chr(13) ' Write to the message file
Next currentMailItem
'vvvvvvvvvvvvvvvv process un read mail in the secondary mail box
' comment this out if you only want to read the inbox
For Each currentMailItem In SecondaryMAPIFolder.Items.Restrict("[UnRead]=True") ' Check each mail item marked as unread
newBody = Replace(currentMailItem.Body, Chr(13), "<br>") ' Replace CR with tag
newBody = Replace(newBody, Chr(10), "<br>") ' Replace LF with tag
newBody = Replace(newBody, Chr(9), " ") ' Replace TAB with spaces
Print #1, "Email" & Chr(9) & Format(currentMailItem.ReceivedTime, "yyyy/mm/dd hh:mm") & _
Chr(9) & " " & Chr(9) & currentMailItem.Subject & Chr(9) & currentMailItem.SenderName & _
Chr(9) & newBody & Chr(13) ' Write to the message file
Next currentMailItem
'^^^^^^^^^^^^^ comment this out if you only want to read the inbox
Close #1
' Copy Messagefile to Toppy
' vvvvvvvvvvvvvvvvvvvvvvv un comment to use TFCopy
'Shell (TFCopyEXEPath & " " & MessageFile & " " & MessageFileDestinationPath) ' Transfer the newly created 99999997.tgd file to the Toppy
' Comment out if you are using TFCopy.
' vvvvvvvvvvvvvvvvvvvv FTP file to toppy
blnFTPResult = FTPFileToToppy(MessageFile, MessageFileDestinationPath)
If Not blnFTPResult Then
Debug.Print "FTP failed"
End If
'^^^^^^^^^^^^^^^ comment out if using TF copy
Set currentMAPIFolder = Nothing
Set currentNameSpace = Nothing
WAIT = Timer
While Timer < WAIT + 3 ' Pause for n seconds to allow TFcopy to do it's thing
DoEvents 'do nothing
Wend
End Sub
Private Sub Application_Reminder(ByVal ReminderItem As Object)
On Error Resume Next
Dim newBody, apptTime, apptImportance As String
Dim WAIT As Double, blnFTPResult As Boolean
If FileExists(MessageFile) Then Kill MessageFile ' Delete the old 99999997.tgd file
apptTime = ReminderItem.Start & " to " & ReminderItem.End ' Create the appointment time string
newBody = Replace(ReminderItem.Body, Chr(13), "<br>") ' Replace CR with tag
newBody = Replace(newBody, Chr(10), "<br>") ' Replace LF with tag
newBody = Replace(newBody, Chr(9), " ") ' Replace TAB with spaces
Select Case ReminderItem.Importance ' Change the Importance attribute from a number to a word
Case 0
apptImportance = "Low"
Case 1
apptImportance = "Normal"
Case 2
apptImportance = "High"
End Select
Open MessageFile For Output Shared As #1
Print #1, "Appointment" & Chr(9) & Format(ReminderItem.Start, "yyyy/mm/dd hh:mm") & Chr(9) & " " & Chr(9) & _
ReminderItem.Subject & Chr(9) & "Importance: " & apptImportance & newBody ' Write the file
Close #1
' Copy Messagefile to Toppy
' vvvvvvvvvvvvvvvvvvvvvvv un comment to use TFCopy
'Shell (TFCopyEXEPath & " " & MessageFile & " " & MessageFileDestinationPath) ' Transfer the newly created 99999997.tgd file to the Toppy
' Comment out if you are using TFCopy.
' vvvvvvvvvvvvvvvvvvvv FTP file to toppy
blnFTPResult = FTPFileToToppy(MessageFile, MessageFileDestinationPath)
If Not blnFTPResult Then
Debug.Print "FTP failed"
End If
'^^^^^^^^^^^^^^^ comment out if using TF copy
WAIT = Timer
While Timer < WAIT + 3
DoEvents 'do nothing
Wend
End Sub
Function FileExists(strFile As String) As Boolean
Dim lSize As Long
On Error Resume Next
lSize = -1
lSize = FileLen(strFile)
If lSize = 0 Then
FileExists = True
ElseIf lSize > 0 Then
FileExists = True
Else
FileExists = False
End If
End Function
Public Function FTPFileToToppy(pLocalFile As String, pRemoteFile As String) As Boolean
Dim lngINetConn
Dim lngINet
Dim blnRC As Boolean
Dim UserName As String
Dim Password As String
Dim serverName As String
'Dim hostFile As String, localFile As String
Const ASCII_TRANSFER = 1
Const BINARY_TRANSFER = 2
serverName = "192.168.5.4"
UserName = "anonymous"
Password = "spam_ttguy@aunix.com.au"
FTPFileToToppy = False
blnRC = False
lngINet = InternetOpen("MyFTP Control", 1, vbNullString, vbNullString, 0) ' Initializes an application's use of the WinINet functions.
If lngINet > 0 Then
' hInternetSession, sServerName, nServerPort, sUsername , sPassword, lService, lFlags ,lContext
lngINetConn = InternetConnect(lngINet, serverName, INTERNET_DEFAULT_FTP_PORT, UserName, Password, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0) ' Opens an File Transfer Protocol (FTP) for a given site.
'vvvvvvvvvv comment out the above and uncomment out this vvvvvv if you do not want to use passive FTP mode.
' lngINetConn = InternetConnect(lngINet, serverName, INTERNET_DEFAULT_FTP_PORT, UserName, Password, INTERNET_SERVICE_FTP, 0, 0)
If lngINetConn > 0 Then
'hFtpSession, lpszLocalFile ,lpszRemoteFile , dwFlags dwContext
blnRC = FtpPutFile(lngINetConn, pLocalFile, pRemoteFile, BINARY_TRANSFER, 0)
' hFtpSession , lpszRemoteFile lpszNewFile fFailIfExists dwFlagsAndAttributes dwContext
' blnRC = FtpGetFile(lngINetConn, hostFile, localFile, False, FILE_ATTRIBUTE_NORMAL, BINARY_TRANSFER, 0)' how to FTP files from the Toppy to the PC - for educational purposes
If (blnRC) Then
FTPFileToToppy = True
Else
Debug.Print "ERROR IN FTP OF FILE!!!!" & vbNewLine & Err.LastDllError
End If
InternetCloseHandle lngINetConn ' close the connection
Else
Debug.Print "ERROR IN InternetConnect!!!!" & vbNewLine & Err.LastDllError
End If
InternetCloseHandle lngINet ' close the internet
Else
Debug.Print "ERROR IN InternetOpen!!!!" & vbNewLine & Err.LastDllError
End If
End Function
If you run a SLUG, you can change the ' Copy Messagefile to Toppy Shell (TFCopyEXEPath & " " & MessageFile & " " & MessageFileDestinationPath) line to:
Dim whocares As Double
' Copy Messagefile to Toppy
whocares = Shell("ftp -A -s:c:\ftpcommand.txt slug", vbHide)
And create a file in c:\ called "ftpcommand.txt" with notepad, and add the lines: cd EPGdata put c:\99999997.tgd QUIT (you have to change EPGdata? to the relevant folder name in the Toppy that the TGD files get loaded up into). To stop Outlook asking about the script accessing your email addresses, run this: http://www.mapilab.com/outlook/security/ and allow the access when the popup happens the first time. To allow Outlook to run this macro when you restart Outlook, you will also have to either set the security level to low, (tools, macro, security, low in Outlook) or create a personal digital signature for the script. This is detailed here: http://www.microsoft.com/technet/prodtechnol/office/office2000/maintain/security/vbamacro.mspx Regards Tony |