1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Discovering the iPad interface

Discussion in 'TiVo Underground' started by wmcbrine, Jan 18, 2011.

  1. Jun 12, 2011 #81 of 366
    moyekj

    moyekj Well-Known Member

    11,144
    32
    Jan 23, 2006
    Mission...
    Very simply, to get recordings in My Shows it is:
    req = RpcRequest('recordingFolderItemSearch', bodyId='-')
    (One can use 'orderBy' argument to change the order)

    Also, I am glad to see I was wrong about response being only 1 item at a time. Above seems to return a full list (including folders and #items per folder).
     
  2. Jun 12, 2011 #82 of 366
    arantius

    arantius New Member

    60
    0
    Jul 25, 2009
    Here's a fun (if difficult to read) image to explain the request and response types:

    http://img820.imageshack.us/img820/3053/maprequeststoresponsesf.png

    You can see that subscriptionSearch could give a subscriptionList, or an idSequence. Then recordingSearch could give recordingList or idSequence, also recordingFolderItemSearch could give recordingFolderItemList or idSequence.

    I think you see where I'm going. I happen to see a recordingFolderItemSearch that sets "format": "idSequence", gets back

    Code:
    {
      "isBottom": false, 
      "isTop": false, 
      "objectIdAndType": [
        "94873", 
        "871425", 
        "870665", 
        "37169", 
        "120769", 
        "46006", 
        "57822", 
        "36231", 
        "36432", 
        "35665", 
        "35648", 
        "603352", 
        "35662", 
        "38264", 
        "35739", 
        "1", 
        "0"
      ], 
      "type": "idSequence"
    }
    Then very soon issues a recordingFolderItemSearch of

    Code:
    {
      "orderBy": [
        "startTime"
      ], 
      "bodyId": "tsn:7460001905F9871", 
      "objectIdAndType": [
        "94873", 
        "871425", 
        "870665", 
        "37169", 
        "120769"
      ], 
      "note": [
        "recordingForChildRecordingId"
      ], 
      "type": "recordingFolderItemSearch", 
      "responseTemplate": [...]
    }
    Notice how those are the first five in the list? It issues one RPC (in this case) to see what the groups are, then another to see what the contents of (some of those) groups are. There's more RPC(s) later to dig into the list of what the recordings are, if one of these results is actually a group. (I see items and groups with lengths mixed into this response. Exactly what you'd see on the "My Shows" section of the TiVo itself, if it's set to show groups, depending on what recordings you have.)
     
  3. Jun 13, 2011 #83 of 366
    orangeboy

    orangeboy yes, I AM orangeboy!

    4,083
    0
    Apr 19, 2004
    East Moline, IL
    Thanks. It's obvious that you took (and are taking) a good chunk of time getting this information together. I have little doubt that an iPad like app will be developed based on your efforts.
     
  4. Jun 15, 2011 #84 of 366
    moyekj

    moyekj Well-Known Member

    11,144
    32
    Jan 23, 2006
    Mission...
    Haven't had much time to play around with this but did so a little last night. arantius, this is a TiVo gold mine you have uncovered. It doesn't take much effort to get complete "My Shows" and "To Do" lists which I have prototypes for. No doubt season pass management, etc. can also be implemented. I haven't even touched possibilities with HME, show searching etc.

    This discovery basically unlocks and makes available a big chunk of the database on the Premiere that was not available previously directly from Premiere. It's akin to having a hacked Premiere without the need for hacking.
     
  5. Jun 17, 2011 #85 of 366
    orangeboy

    orangeboy yes, I AM orangeboy!

    4,083
    0
    Apr 19, 2004
    East Moline, IL
    I am absolutely awestruck by the amount of information that is now available. Using the remote.py script, I've been adding in the discovered RequestTypes as functions in the Remote Class, similar to the following:

    Code:
        ...
        # bodyConfigSearch
        def bodyConfigSearch(self):
            req = RpcRequest('bodyConfigSearch', 
                             bodyId='-')
            self.Write(req)
            result = self.Read()
            for item in result:
                print item
            print result['response']
            print " "
            print result
            print " "
    
        # channelSearch
        def channelSearch(self):
            req = RpcRequest('channelSearch',
                             noLimit='true', 
                             isReceived='false') 
            self.Write(req)
            result = self.Read()
            for item in result:
                print item
            print result['response']
            print " "
            print result
            print " "
        ...
    
    and just simply calling them to see what can be gleaned from my own Premiere:

    Code:
        ...
        remote = Remote()
    
        print 'bodyConfigSearch'
        remote.bodyConfigSearch()
    
        print 'channelSearch'
        remote.channelSearch()
    
       ...
    
    Oh. My. God.

    My mind is reeling with potential applications that can come from this. I can seriously see elimination of (TiVo) meta-generators that rely on IMDB and TheTVDB. Show and movie cover art and image links can be found, hardware information (userDiskSize, userDiskUsed), software information (hasScheduler(?), softwareVersion, parentalControlsState, clipOverlapping, etc.), Series information, Episode information, the list goes on and on. And I've only defined the first four RequestTypes! It makes me wonder what else is buried under the covers. What would be icing on the cake would be a "QuerySchema" request, that outputs ALL of the RequestTypes and their options, as well as output definitions.
     
  6. Jun 17, 2011 #86 of 366
    innocentfreak

    innocentfreak Active Member

    8,950
    3
    Aug 25, 2001
    Florida
    Is it strange I am excited about this and don't have clue what orangeboy just said :)?
     
  7. Jun 17, 2011 #87 of 366
    windracer

    windracer joined the 10k club

    11,580
    3
    Jan 3, 2003
    St. Pete, FL
    He had me at "Oh. My. God." :D
     
  8. Jun 17, 2011 #88 of 366
    orangeboy

    orangeboy yes, I AM orangeboy!

    4,083
    0
    Apr 19, 2004
    East Moline, IL
    I'm not a fan of hyperbole, but arantius' time and effort (I think) was monumental! There's a lot to go through, but I encourage downloading the "Request/Responses" zip found in this post: http://www.tivocommunity.com/tivo-vb/showthread.php?p=8556511#post8556511

    If you do get the zip, this file is an example of a collectionSearch: 61706-32-2-response-contentList.txt, that I think would provide an ideal set of data for a new meta-generator. Bah, here's the content of the file:

    Code:
    MRPC/2 76 2928
    Raw Packet=MRPC/2 76 2928
    Content-Type: application/json
    IsFinal: true
    RpcId: 32
    Type: response
    
    {
      "content": [
        {
          "category": [
            {
              "image": [
                {
                  "width": 360, 
                  "imageUrl": "http://i.tivo.com/images-static/bravo/genre-backgrounds/showcaseBanner/Drama.jpg", 
                  "type": "image", 
                  "imageType": "showcaseBanner", 
                  "height": 270
                }, 
                {
                  "width": 180, 
                  "imageUrl": "http://i.tivo.com/images-static/bravo/genre-backgrounds/moviePoster/Drama.jpg", 
                  "type": "image", 
                  "imageType": "moviePoster", 
                  "height": 270
                }
              ], 
              "displayRank": 0, 
              "type": "category", 
              "label": "Drama"
            }, 
            {
              "displayRank": 1, 
              "type": "category", 
              "label": "TV Show"
            }
          ], 
          "collectionType": "series", 
          "seasonNumber": 4, 
          "description": "Gossip flies about Caroline and a man (Gil Gerard) building her kitchen in exchange for room and board.", 
          "episodic": true, 
          "collectionId": "tivo:cl.19284", 
          "contentId": "tivo:ct.127876", 
          "image": [
            {
              "width": 139, 
              "imageUrl": "http://i.tivo.com/images-production/bravo/banner-med/dd/a7/dda739d69d9893b079ee4479043e9dea.jpg", 
              "type": "image", 
              "imageType": "showcaseBanner", 
              "height": 104
            }, 
            {
              "width": 200, 
              "imageUrl": "http://i.tivo.com/images-production/bravo/banner-lg/dd/a7/dda739d69d9893b079ee4479043e9dea.jpg", 
              "type": "image", 
              "imageType": "showcaseBanner", 
              "height": 150
            }
          ], 
          "episodeNum": [
            4
          ], 
          "originalAirYear": 1977, 
          "credit": [
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Landon", 
              "first": "Michael"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Grassle", 
              "first": "Karen"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Gilbert", 
              "first": "Melissa"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Anderson", 
              "first": "Melissa"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Swenson", 
              "first": "Karl"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Bull", 
              "first": "Richard"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "MacGregor", 
              "first": "Katherine"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Arngrim", 
              "first": "Alison"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Gilbert", 
              "first": "Jonathan"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Hagen", 
              "first": "Kevin"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Greer", 
              "first": "Dabbs"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Stewart", 
              "first": "Charlotte"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Olsen", 
              "first": "Merlin"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Laborteaux", 
              "first": "Patrick"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Parady", 
              "first": "Hersha"
            }, 
            {
              "role": "guestStar", 
              "type": "credit", 
              "last": "Gerard", 
              "first": "Gil"
            }, 
            {
              "role": "guestStar", 
              "type": "credit", 
              "last": "Baddeley", 
              "first": "Hermione"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Greenbush", 
              "first": "Lindsay"
            }, 
            {
              "role": "actor", 
              "type": "credit", 
              "last": "Greenbush", 
              "first": "Sidney"
            }, 
            {
              "role": "writer", 
              "type": "credit", 
              "last": "Heinemann", 
              "first": "Arthur"
            }, 
            {
              "role": "director", 
              "type": "credit", 
              "last": "Claxton", 
              "first": "William F."
            }
          ], 
          "title": "Little House on the Prairie", 
          "subtitle": "The Handyman", 
          "type": "content", 
          "tvRating": "pg"
        }
      ], 
      "type": "contentList"
    }
    
    Note that it contains: a couple "imageUrl"s, "seasonNumber", "episodeNum", "originalAirYear", "title" (Series title), and "subtitle" (Episode title), not to mention "description" and "role" for cast and crew, all handy/interesting information. Other than the images, I believe all the other information is local. Although the Request looks a bit daunting, I think the payoff is well worth the effort. Yessir, I like it! :up:
     
  9. Jun 17, 2011 #89 of 366
    innocentfreak

    innocentfreak Active Member

    8,950
    3
    Aug 25, 2001
    Florida
    I guess the next question is there anything us non programmers can do to help?
     
  10. Jun 17, 2011 #90 of 366
    ckrames1234

    ckrames1234 New Member

    4
    0
    May 1, 2011
    I love the API documentation, great work arantius. I will definitely try to contribute to it. There are so many things I could do with this, projects I could make, the possibilities are literally endless.

    I never posted sample code on here because in my sample, I tried using a random X-ApplicationSessionId, which I now know is not a good idea. :p

    (For some reason I never got notified when someone posted on here :/)
     
  11. Jun 17, 2011 #91 of 366
    orangeboy

    orangeboy yes, I AM orangeboy!

    4,083
    0
    Apr 19, 2004
    East Moline, IL
    Post ideas about what ya want! :D

    I have a feeling moyekj will have a java version of something out before long. I'm struggling with (personally) interpreting JSON nomenclature, and getting useful Requests put together. For example, when querying the (local) To Do List, I can only get the first item in the list. I'm sure there's something to say "get the rest", but for the time being, I'm just trying to get a grasp of all the things that can be had, and will worry about the details later....
     
  12. Jun 17, 2011 #92 of 366
    orangeboy

    orangeboy yes, I AM orangeboy!

    4,083
    0
    Apr 19, 2004
    East Moline, IL
    Nice to hear! More eyes on it could/should mean quicker development of stuff!
     
  13. Jun 17, 2011 #93 of 366
    innocentfreak

    innocentfreak Active Member

    8,950
    3
    Aug 25, 2001
    Florida
    LOL
    For example, does this mean potentially we could actually transfer and automatically rename shows so they end up in the SxxExx format in the name since the current way is hit or miss on season and episode information even though the Premiere screen will display it properly?
     
  14. Jun 17, 2011 #94 of 366
    orangeboy

    orangeboy yes, I AM orangeboy!

    4,083
    0
    Apr 19, 2004
    East Moline, IL
    With proper formatting of the information retrieved from the Premiere, I would think that yes, SxxExx could be added to the subtitle (episode name). I'll have to see if Search capabilities extend to sources like Netflix or Amazon for movies and/or documentaries.
     
  15. Jun 17, 2011 #95 of 366
    orangeboy

    orangeboy yes, I AM orangeboy!

    4,083
    0
    Apr 19, 2004
    East Moline, IL
    OK, got past the To Do List search only returning one item by including a "count=" option:
    Code:
        def ToDoSearch(self):
            req = RpcRequest('recordingSearch', 
                             levelOfDetail='low', 
                             bodyId='-', 
                             count='50',
                             state=['scheduled'])
    
    Setting a count too high results in:
    Code:
    {'debug': '', 'text': 'Count is out of range. 1 <= count <= 50', 'code': 'badArgument', 'type': 'error'}
    
    I'm looking for some type of "Anchor" statement that could continue listing beyond the first 50 items.

    Adding an offset seems to do the trick:
    Code:
        def ToDoSearch(self):
            req = RpcRequest('recordingSearch', 
                             levelOfDetail='low', 
                             bodyId='-', 
                             count='50',
                             offset='50',
                             state=['scheduled'])
    
     
  16. Jun 17, 2011 #96 of 366
    tomhorsley

    tomhorsley Active Member

    1,172
    4
    Jul 22, 2010
    The thing I'm most interested in is correcting rotten bits of the native tivo interface, like by having a cron job to download schedule info off the tivo and schedule recording of alternate showings of episodes you missed due to a conflict (but which are now not "new" anymore, so the tivo won't automatically record them).

    Or a way to correct the "new" flag by recording the descriptions of the shows and scheduling recordings for any show with a new description and cancelling recordings of shows marked new that have a description I already remember.

    I can also imagine using the tivo to get schedule info, then using it in a myth TV setup to get an additional tuner that will at least work on unencrypted channels.
     
  17. Jun 17, 2011 #97 of 366
    arantius

    arantius New Member

    60
    0
    Jul 25, 2009
    I'm generally mystified by that value yet. It just seemed strange that they seemed to be large numbers in a small range, for what samples I had, so I just did random within that range.

    As far as I can tell, (depending on options) you get one notification, then no more until you visit the site (thread?).
     
  18. Jun 17, 2011 #98 of 366
    orangeboy

    orangeboy yes, I AM orangeboy!

    4,083
    0
    Apr 19, 2004
    East Moline, IL
    Just got to "uiNavigate". Nice. Set a URI gathered from "uiDestinationInstanceSearch", and instantly jump to that (HME) app, just like hitting LiveTV or TiVo button.

    URIs:
    Code:
    Amazon:             x-tivo:hme:uuid:35FE011C-3850-2228-FBC5-1B9EDBBE5863
    Blockbuster:        x-tivo:hme:uuid:63ED0C3D-D49C-9602-C322-E0A3D3EA5A3D
    Browse Web Videos:  x-tivo:hme:uuid:19452283-D00B-C411-595D-447ABF62F37C
    Browse Web Videos:  x-tivo:hme:uuid:6784571A-016C-8A46-DF2F-FD842D78006F
    Fandango:           x-tivo:hme:uuid:B9DDBECF-BC6D-5E33-388A-4CF840068D79
    Music Choice:       x-tivo:hme:uuid:7FDF1BEB-AF92-B8B6-6269-FAE44C8F887D
    Netflix:            x-tivo:hme:uuid:7edeb291-0db8-487f-b842-6b97bc71ad9a
    One True Media:     x-tivo:hme:uuid:D1AF7BED-325E-5E6E-B087-72381C92D077
    Swivel:             x-tivo:hme:uuid:2BD40EF7-D9D2-3CD4-0130-6C18855CE898
    TiVoCast RSS:       x-tivo:hme:uuid:863cb78f-efdd-4106-b572-51733983dc76
    Youtube:            x-tivo:hme:uuid:9AA364C9-CF8A-1E1D-B50F-CC65C40D4A96
    
    The function:
    Code:
        def uiNavigate(self):
            req = RpcRequest('uiNavigate',
                             uri='x-tivo:hme:uuid:2BD40EF7-D9D2-3CD4-0130-6C18855CE898',
                             bodyId='-')
            self.Write(req)
    
     
  19. Jun 17, 2011 #99 of 366
    arantius

    arantius New Member

    60
    0
    Jul 25, 2009
    Dump more traffic (with my mdns daemon and tcpcatcher) to find out any details missing from my doc. E.g.how do i make a season pass? How do i cancel it? Etc.
     
  20. innocentfreak

    innocentfreak Active Member

    8,950
    3
    Aug 25, 2001
    Florida
    Ok I will have to look into it tomorrow and see if I can figure it out. Never messed with any of these tools.
     

Share This Page