NSLU2-Linux
view · edit · print · history

ToppyBiff is a concept for a new style of Topfield TAP.

Imagine your Toppy alerting you to new information from the internet:

  • New Emails
  • Syslog alerts
  • Stock prices
  • Horoscopes
  • RSS Feeds

... 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
timestamps: Date header contents
duration: ??
title: Subject/Headline
shortevt: From header contents / author information / source information
description: Message body
parental: ??
recording: ??


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

view · edit · print · history · Last edited by ttguy at toppy forum.
Based on work by tonymy01, Craig, and rwhitby.
Originally by rwhitby.
Page last modified on March 06, 2009, at 01:32 AM