2012-10-21 10:54:19 - Article

Remote controlling Tivo

Content.exe

I was interested in what my ethernet port was doing on my virgin media TIVO box, so I ran some tests and found I could control my TIVO box from my laptop, here are my findings.

First, I went into the Tivo boxes settings on screen and enabled network access.

Next, I logged into my home hub/router to find out what IP address it had been allocated
http://192.168.100.1/ and clicked devices.

Once I had its IP address, (192.168.0.7) I scanned its ports and found the following services:

adrian@adrian-laptop:~$ nmap 192.168.0.7

Starting Nmap 5.00 ( http://nmap.org ) at 2012-10-21 10:37 BST
Interesting ports on 192.168.0.7:
Not shown: 997 filtered ports
PORT     STATE SERVICE
443/tcp  open  https
2190/tcp open  unknown
2191/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 5.50 seconds

The obvious one that stands out is port 443, so visiting https://192.168.0.7/ shows a web server requesting login, I found that the username is tivo and the password is your media key found in settings > mediakey.

Once logged in, a list of recorded programmes will be displayed but however streaming and downloading are disabled :(.

I tried for sometime to circumvent the streaming restriction using various techniques the closest I came was with VLC and special plugins http://tivo-vlc.sourceforge.net/notes.php#install, but so far I haven’t been able to achieve this.

I looked into what the box is, and it turns out its fundamentally Linux box with a glossy coat, with some features disabled (like streaming something to do with UK copyright laws).

Along the way I found I could telnet to port 31339 on the box

telnet 192.168.0.7 31339

which responded with

CH_STATUS 0213 RECORDING

This is the status of the two tuners, and what they are doing, you can now use commands like:

KEYBOARD (Dunno what this does)

TELEPORT - e.g TIVO, LIVETV, GUIDE, and NOWPLAYING.

SETCH - Change channel. If the current tuner is recording a program, it will change the other tuner. If both tuners are recording, the TiVo will respond with "CH_FAILED RECORDING . Using this command while Tivo is replaying will give "CH_FAILED NO_LIVE".</p> <p>FORCECH <CHANNEL> - This command will force the current tuner to the tune the desired channel regardless of what it's doing. If a recording is being recorded it will cancel the recording and change the channel without confirmation.<br /> </code><br /> Also a complete set of IRCODE’s exist <code>IRCODE <COMMAND></code></p> <p> a quick google and I found the following IRCODE commands that seem to work.</p> <p>UP<br /> DOWN<br /> LEFT<br /> RIGHT<br /> SELECT<br /> TIVO<br /> LIVETV<br /> THUMBSUP<br /> THUMBSDOWN<br /> CHANNELUP<br /> CHANNELDOWN<br /> RECORD<br /> DISPLAY<br /> DIRECTV<br /> NUM0<br /> NUM1<br /> NUM2<br /> NUM3<br /> NUM4<br /> NUM5<br /> NUM6<br /> NUM7<br /> NUM8<br /> NUM9<br /> ENTER<br /> CLEAR<br /> PLAY<br /> PAUSE<br /> SLOW<br /> FORWARD<br /> REVERSE<br /> STANDBY<br /> NOWSHOWING<br /> REPLAY<br /> ADVANCE<br /> DELIMITER<br /> GUIDE</p> <p>Typing these commands into the telnet session, made the tivo box change channel etc…. cool!</p> <p>To exit the telnet session press <code>CTRL + ]</code> thats right, control and right square bracket!!, then type quit at the prompt</p> <p>I was able to source a nice GUI that can automate these commands https://github.com/wmcbrine/tivoremote</p> <p>So, as long as you have Python installed (Mac & linux users by default), just running the script produces a nice GUI that can manage your Tivo box from your laptop.</p> <p>I also found, if your interested in developing apps for it, its SDK is written for AS3 and can be found here http://developer.tivo.com/</p> </div> </div> <!-- Post Footer --> <footer class="post-footer"> <!-- Tags --> <!-- Author Bio --> </footer> </article> <!-- Related Posts --> <section class="related-posts terminal-block"> <div class="terminal-header"> <span>Related_Articles.query</span> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="terminal-content"> <h3 class="section-title neon-text">You might also be interested in:</h3> <div class="related-posts-grid"> <div class="related-post-item"> <div class="related-post-content"> <h4 class="related-post-title"> <a href="https://adriancallaghan.co.uk/desktop-tidy/">Desktop tidy</a> </h4> <div class="related-post-meta"> <span>[2014.12.03]</span> </div> <div class="related-post-excerpt"> A cluttered desktop can be a problem, typically people use the desktop becuase they know… </div> </div> </div> <div class="related-post-item"> <div class="related-post-content"> <h4 class="related-post-title"> <a href="https://adriancallaghan.co.uk/bash-script-to-create-virtual-hosting-in-fedora/">Bash script to create virtual hosting in Fedora</a> </h4> <div class="related-post-meta"> <span>[2014.08.15]</span> </div> <div class="related-post-excerpt"> I am often needing to add a script to create virtual hosting, below is one… </div> </div> </div> <div class="related-post-item"> <div class="related-post-content"> <h4 class="related-post-title"> <a href="https://adriancallaghan.co.uk/script-to-monitor-internet-connection/">Script to monitor internet connection</a> </h4> <div class="related-post-meta"> <span>[2015.04.21]</span> </div> <div class="related-post-excerpt"> The internet often drops at work, so to compile a csv report of the outage… </div> </div> </div> </div> </div> </section> <!-- Comments Section --> <section class="comments-section terminal-block"> <div class="terminal-header"> <span>Comments.log - 4 entries</span> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="terminal-content"> <div id="comments" class="comments-area"> <h3 class="comments-title neon-text"> 4 responses to “<span>Remote controlling Tivo</span>” </h3> <ol class="comment-list"> <li class="comment even thread-even depth-1 terminal-block comment-item" id="comment-223"><div class="terminal-header"><div class="comment-author-info"><strong class="comment-author-name">Adrian Byrne</strong><span class="comment-metadata"> [2017.01.02 at 13:13]</span></div><div class="terminal-buttons"><div class="terminal-button close"></div><div class="terminal-button minimize"></div><div class="terminal-button maximize"></div></div></div><div class="terminal-content"><div class="comment-avatar"><img alt='' src='https://secure.gravatar.com/avatar/420f280ea5fee1853dfef629ae505cb6a59c8f88a9301f3c09c4d92f01e1c594?s=60&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/420f280ea5fee1853dfef629ae505cb6a59c8f88a9301f3c09c4d92f01e1c594?s=120&d=mm&r=g 2x' class='avatar avatar-60 photo' height='60' width='60' decoding='async'/></div><div class="comment-content">You're a star I am thinking of hooking up Amazon Echo to this. Do you know where there might be some code for that? Adrian<div class="comment-actions"><span class="reply-link"><a rel="nofollow" class="comment-reply-link" href="https://adriancallaghan.co.uk/remote-controlling-tivo/?replytocom=223#respond" data-commentid="223" data-postid="712" data-belowelement="comment-223" data-respondelement="respond" data-replyto="Reply to Adrian Byrne" aria-label="Reply to Adrian Byrne">Reply</a></span></div></div></div></li> <li class="comment odd alt thread-odd thread-alt depth-1 terminal-block comment-item" id="comment-224"><div class="terminal-header"><div class="comment-author-info"><strong class="comment-author-name">Gary Wilson</strong><span class="comment-metadata"> [2018.11.16 at 21:14]</span></div><div class="terminal-buttons"><div class="terminal-button close"></div><div class="terminal-button minimize"></div><div class="terminal-button maximize"></div></div></div><div class="terminal-content"><div class="comment-avatar"><img alt='' src='https://secure.gravatar.com/avatar/a29b1e83f3c984487ae7c1da8b0fa8697db1e2530cef784201c2fd3e3716c499?s=60&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/a29b1e83f3c984487ae7c1da8b0fa8697db1e2530cef784201c2fd3e3716c499?s=120&d=mm&r=g 2x' class='avatar avatar-60 photo' height='60' width='60' decoding='async'/></div><div class="comment-content">is this https://www.tivo.com/assets/images/abouttivo/resources/downloads/brochures/TiVo_TCP_Network_Remote_Control_Protocol.pdf any good to you for the commands?<div class="comment-actions"><span class="reply-link"><a rel="nofollow" class="comment-reply-link" href="https://adriancallaghan.co.uk/remote-controlling-tivo/?replytocom=224#respond" data-commentid="224" data-postid="712" data-belowelement="comment-224" data-respondelement="respond" data-replyto="Reply to Gary Wilson" aria-label="Reply to Gary Wilson">Reply</a></span></div></div></div></li> <li class="comment even thread-even depth-1 terminal-block comment-item" id="comment-225"><div class="terminal-header"><div class="comment-author-info"><strong class="comment-author-name">Justin Glover</strong><span class="comment-metadata"> [2019.07.26 at 21:34]</span></div><div class="terminal-buttons"><div class="terminal-button close"></div><div class="terminal-button minimize"></div><div class="terminal-button maximize"></div></div></div><div class="terminal-content"><div class="comment-avatar"><img alt='' src='https://secure.gravatar.com/avatar/1c09ac971baddc24fb0ac6611bee46c2f44e7311f73d4043e844a135e5434006?s=60&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/1c09ac971baddc24fb0ac6611bee46c2f44e7311f73d4043e844a135e5434006?s=120&d=mm&r=g 2x' class='avatar avatar-60 photo' height='60' width='60' decoding='async'/></div><div class="comment-content">This is awesome i just wish there was a command for My Shows!<div class="comment-actions"><span class="reply-link"><a rel="nofollow" class="comment-reply-link" href="https://adriancallaghan.co.uk/remote-controlling-tivo/?replytocom=225#respond" data-commentid="225" data-postid="712" data-belowelement="comment-225" data-respondelement="respond" data-replyto="Reply to Justin Glover" aria-label="Reply to Justin Glover">Reply</a></span></div></div></div> <ol class="children"> <li class="comment odd alt depth-2 terminal-block comment-item" id="comment-226"><div class="terminal-header"><div class="comment-author-info"><strong class="comment-author-name">Antony Gerrish</strong><span class="comment-metadata"> [2020.05.30 at 01:49]</span></div><div class="terminal-buttons"><div class="terminal-button close"></div><div class="terminal-button minimize"></div><div class="terminal-button maximize"></div></div></div><div class="terminal-content"><div class="comment-avatar"><img alt='' src='https://secure.gravatar.com/avatar/75fbbce9c788add9f484576e4179293fdd1c13ae56cb6e5456d4974ba0b53bb5?s=60&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/75fbbce9c788add9f484576e4179293fdd1c13ae56cb6e5456d4974ba0b53bb5?s=120&d=mm&r=g 2x' class='avatar avatar-60 photo' height='60' width='60' loading='lazy' decoding='async'/></div><div class="comment-content">For the "My Shows" function I used "TELEPORT NOWPLAYING"<div class="comment-actions"><span class="reply-link"><a rel="nofollow" class="comment-reply-link" href="https://adriancallaghan.co.uk/remote-controlling-tivo/?replytocom=226#respond" data-commentid="226" data-postid="712" data-belowelement="comment-226" data-respondelement="respond" data-replyto="Reply to Antony Gerrish" aria-label="Reply to Antony Gerrish">Reply</a></span></div></div></div></li> </ol> </li> </ol> <div id="respond" class="comment-respond"> <h3 id="reply-title" class="comment-reply-title"><span class="neon-text">Leave a Response</span> <small><a rel="nofollow" id="cancel-comment-reply-link" href="/remote-controlling-tivo/#respond" style="display:none;">[Cancel Reply]</a></small></h3><form action="https://adriancallaghan.co.uk/wp-comments-post.php" method="post" id="commentform" class="comment-form terminal-form"><div class="comment-notes terminal-style"> <span class="neon-text">System Notice:</span> Your email address will not be published. Required fields are marked with <span class="required neon-text">*</span> </div><div class="comment-form-comment terminal-block"> <div class="terminal-header"> <label for="comment">Message Content</label> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="terminal-content"> <textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required placeholder="Enter your message here..."></textarea> </div> </div><div class="comment-form-author terminal-block"> <div class="terminal-header"> <label for="author">User Name <span class="required">*</span></label> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="terminal-content"> <input id="author" name="author" type="text" value="" size="30" maxlength="245" required placeholder="Your display name" /> </div> </div> <div class="comment-form-email terminal-block"> <div class="terminal-header"> <label for="email">Email Address <span class="required">*</span></label> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="terminal-content"> <input id="email" name="email" type="email" value="" size="30" maxlength="100" required placeholder="your@email.com" /> </div> </div> <div class="comment-form-url terminal-block"> <div class="terminal-header"> <label for="url">Website URL</label> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="terminal-content"> <input id="url" name="url" type="url" value="" size="30" maxlength="200" placeholder="https://yourwebsite.com" /> </div> </div> <p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" /> <label for="wp-comment-cookies-consent">Save my name, email, and website in this browser for the next time I comment.</label></p> <p class="form-submit"><input name="submit" type="submit" id="submit" class="submit neon-button" value="Submit Response" /> <input type='hidden' name='comment_post_ID' value='712' id='comment_post_ID' /> <input type='hidden' name='comment_parent' id='comment_parent' value='0' /> </p><p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="a1fa39e814" /></p><p style="display: none !important;" class="akismet-fields-container" data-prefix="ak_"><label>Δ<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js_1" name="ak_js" value="134"/><script>document.getElementById( "ak_js_1" ).setAttribute( "value", ( new Date() ).getTime() );</script></p></form> </div><!-- #respond --> </div> <style> /* Comments Area Styles */ .comments-area { margin-top: 3rem; font-family: var(--font-cyber); } .comments-title { margin-bottom: 2rem; font-size: 1.5rem; } .comment-list { list-style: none; padding: 0; } .comment-item { margin-bottom: 2rem; } .comment-item .terminal-content { display: flex; gap: 1rem; } .comment-avatar img { border-radius: 50%; border: 2px solid var(--neon-cyan); width: 60px; height: 60px; } .comment-content { flex: 1; } .comment-author-name { color: var(--neon-cyan); } .comment-metadata { color: var(--neon-orange); font-family: var(--font-mono); font-size: 0.9rem; } .comment-awaiting-moderation { display: block; margin-bottom: 1rem; padding: 0.5rem; background: rgba(255, 140, 0, 0.1); border-left: 3px solid var(--neon-orange); } .comment-actions { margin-top: 1rem; display: flex; gap: 1rem; } .reply-link a, .edit-link a { color: var(--neon-green); text-decoration: none; font-family: var(--font-mono); font-size: 0.9rem; border: 1px solid var(--neon-green); padding: 0.3rem 0.8rem; border-radius: 15px; transition: all 0.3s ease; } .reply-link a:hover, .edit-link a:hover { background: var(--neon-green); color: var(--dark-bg); box-shadow: 0 0 10px var(--neon-green); } /* Nested Comments */ .children { margin-top: 2rem; margin-left: 2rem; border-left: 2px solid var(--grid-color); padding-left: 2rem; } /* Comment Form */ .comment-form { margin-top: 3rem; } .comment-notes { margin-bottom: 2rem; padding: 1rem; background: rgba(0,255,255,0.1); border-radius: 8px; font-family: var(--font-mono); font-size: 0.9rem; } .required { color: var(--neon-pink); } .comment-form-author, .comment-form-email, .comment-form-url, .comment-form-comment { margin-bottom: 2rem; } .comment-form input[type="text"], .comment-form input[type="email"], .comment-form input[type="url"], .comment-form textarea { width: 100%; padding: 0.8rem; background: rgba(0,0,0,0.8); border: 1px solid var(--grid-color); border-radius: 5px; color: var(--text-primary); font-family: var(--font-mono); font-size: 0.9rem; transition: all 0.3s ease; } .comment-form input[type="text"]:focus, .comment-form input[type="email"]:focus, .comment-form input[type="url"]:focus, .comment-form textarea:focus { border-color: var(--neon-cyan); box-shadow: 0 0 15px rgba(0,255,255,0.3); outline: none; } .comment-form textarea { resize: vertical; min-height: 120px; } .neon-button { background: linear-gradient(135deg, var(--neon-cyan), var(--neon-purple)); color: var(--dark-bg); border: none; padding: 1rem 2rem; border-radius: 25px; font-family: var(--font-cyber); font-weight: bold; font-size: 1rem; cursor: pointer; transition: all 0.3s ease; text-transform: uppercase; letter-spacing: 1px; } .neon-button:hover { transform: translateY(-2px); box-shadow: 0 10px 30px rgba(0,255,255,0.4); } .neon-button:active { transform: translateY(0); } /* Comments Navigation */ .comment-navigation { margin: 2rem 0; display: flex; justify-content: space-between; } .comment-navigation a { color: var(--neon-green); text-decoration: none; padding: 0.5rem 1rem; border: 1px solid var(--neon-green); border-radius: 20px; transition: all 0.3s ease; } .comment-navigation a:hover { background: var(--neon-green); color: var(--dark-bg); box-shadow: 0 0 15px var(--neon-green); } .no-comments { text-align: center; padding: 2rem; font-family: var(--font-mono); font-size: 1.1rem; } /* Responsive Design */ @media (max-width: 768px) { .comment-item .terminal-content { flex-direction: column; text-align: center; } .children { margin-left: 1rem; padding-left: 1rem; } .comment-actions { justify-content: center; } .comment-navigation { flex-direction: column; gap: 1rem; text-align: center; } } @media (max-width: 480px) { .comment-avatar img { width: 50px; height: 50px; } .neon-button { width: 100%; padding: 1rem; } } </style> </div> </section> </div> <!-- Sidebar for Single Posts --> <aside class="sidebar single-sidebar"> <!-- Popular Posts --> <div class="popular-posts terminal-block widget"> <div class="terminal-header"> <h3>Popular_Posts.db</h3> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="terminal-content"> <ul class="popular-posts-list"> <li class="popular-post-item"> <a href="https://adriancallaghan.co.uk/zend-framework-2-restful-cms/" class="popular-post-link"> <span class="popular-post-title">Zend framework 2 restful CMS</span> <span class="popular-post-meta"> [2014.08.26] [2649 Views] </span> </a> </li> <li class="popular-post-item"> <a href="https://adriancallaghan.co.uk/clikstats/" class="popular-post-link"> <span class="popular-post-title">clikStats</span> <span class="popular-post-meta"> [2008.12.29] [2114 Views] </span> </a> </li> <li class="popular-post-item"> <a href="https://adriancallaghan.co.uk/zend-framework-2-dompdf-no-block-level-parent-found-not-good-error-message/" class="popular-post-link"> <span class="popular-post-title">Zend framework 2 DomPdf No block-level parent found. Not good. error message</span> <span class="popular-post-meta"> [2016.07.25] [1321 Views] </span> </a> </li> <li class="popular-post-item"> <a href="https://adriancallaghan.co.uk/addresses-of-tracy-connolly-steven-barker-and-jason-owen/" class="popular-post-link"> <span class="popular-post-title">Addresses of Tracy Connolly, Steven Barker and Jason Owen</span> <span class="popular-post-meta"> [2008.12.04] [706 Views] </span> </a> </li> <li class="popular-post-item"> <a href="https://adriancallaghan.co.uk/remote-controlling-tivo/" class="popular-post-link"> <span class="popular-post-title">Remote controlling Tivo</span> <span class="popular-post-meta"> [2012.10.21] [326 Views] </span> </a> </li> </ul> </div> </div> <!-- Categories --> <div class="categories-widget terminal-block widget"> <div class="terminal-header"> <h3>Categories.index</h3> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="terminal-content"> <ul class="categories-list"> <li class="category-item"> <a href="https://adriancallaghan.co.uk/Categorys/programming/applications/" class="category-link"> <span class="category-name">Applications</span> <span class="category-count">[3]</span> </a> </li> <li class="category-item"> <a href="https://adriancallaghan.co.uk/Categorys/misc/baby-p/" class="category-link"> <span class="category-name">baby p</span> <span class="category-count">[3]</span> </a> </li> <li class="category-item"> <a href="https://adriancallaghan.co.uk/Categorys/programming/bash/" class="category-link"> <span class="category-name">Bash</span> <span class="category-count">[4]</span> </a> </li> <li class="category-item"> <a href="https://adriancallaghan.co.uk/Categorys/misc/car-woes/" class="category-link"> <span class="category-name">Car woes</span> <span class="category-count">[2]</span> </a> </li> <li class="category-item"> <a href="https://adriancallaghan.co.uk/Categorys/misc/hardware/" class="category-link"> <span class="category-name">Hardware</span> <span class="category-count">[3]</span> </a> </li> <li class="category-item"> <a href="https://adriancallaghan.co.uk/Categorys/programming/javascript/" class="category-link"> <span class="category-name">Javascript</span> <span class="category-count">[5]</span> </a> </li> <li class="category-item"> <a href="https://adriancallaghan.co.uk/Categorys/misc/" class="category-link"> <span class="category-name">Misc</span> <span class="category-count">[0]</span> </a> </li> <li class="category-item"> <a href="https://adriancallaghan.co.uk/Categorys/misc/music/" class="category-link"> <span class="category-name">Music</span> <span class="category-count">[2]</span> </a> </li> <li class="category-item"> <a href="https://adriancallaghan.co.uk/Categorys/programming/php/" class="category-link"> <span class="category-name">Php</span> <span class="category-count">[8]</span> </a> </li> <li class="category-item"> <a href="https://adriancallaghan.co.uk/Categorys/programming/" class="category-link"> <span class="category-name">Programming</span> <span class="category-count">[26]</span> </a> </li> </ul> </div> </div> <!-- Regular Sidebar Widgets --> <div id="block-2" class="terminal-block widget widget_block widget_search"><form role="search" method="get" action="https://adriancallaghan.co.uk/" class="wp-block-search__button-outside wp-block-search__text-button wp-block-search" ><label class="wp-block-search__label" for="wp-block-search__input-1" >Search</label><div class="wp-block-search__inside-wrapper " ><input class="wp-block-search__input" id="wp-block-search__input-1" placeholder="" value="" type="search" name="s" required /><button aria-label="Search" class="wp-block-search__button wp-element-button" type="submit" >Search</button></div></form></div><div id="block-3" class="terminal-block widget widget_block"><div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow"><h2 class="wp-block-heading">Recent Posts</h2><ul class="wp-block-latest-posts__list wp-block-latest-posts"><li><a class="wp-block-latest-posts__post-title" href="https://adriancallaghan.co.uk/fizz-buzz-and-fibbonacci-combined/">Fizz Buzz and Fibbonacci combined</a></li> <li><a class="wp-block-latest-posts__post-title" href="https://adriancallaghan.co.uk/running-php-7-and-php-5-together-ubuntu/">running PHP 7 and PHP 5 together – ubuntu</a></li> <li><a class="wp-block-latest-posts__post-title" href="https://adriancallaghan.co.uk/wordpress-concrete5-zf2-php-mysql-database-dump/">WordPress, concrete5, ZF2, PHP, mysql database dump</a></li> <li><a class="wp-block-latest-posts__post-title" href="https://adriancallaghan.co.uk/how-to-create-a-zf2-nested-bootstrap-dropdown-menu/">How to create a ZF2 nested bootstrap dropdown menu</a></li> <li><a class="wp-block-latest-posts__post-title" href="https://adriancallaghan.co.uk/zend-framework-2-dompdf-no-block-level-parent-found-not-good-error-message/">Zend framework 2 DomPdf No block-level parent found. Not good. error message</a></li> </ul></div></div></div><div id="block-4" class="terminal-block widget widget_block"><div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow"><h2 class="wp-block-heading">Recent Comments</h2><ol class="wp-block-latest-comments"><li class="wp-block-latest-comments__comment"><article><footer class="wp-block-latest-comments__comment-meta"><span class="wp-block-latest-comments__comment-author">Antony Gerrish</span> on <a class="wp-block-latest-comments__comment-link" href="https://adriancallaghan.co.uk/remote-controlling-tivo/#comment-226">Remote controlling Tivo</a></footer></article></li><li class="wp-block-latest-comments__comment"><article><footer class="wp-block-latest-comments__comment-meta"><span class="wp-block-latest-comments__comment-author">bilgi</span> on <a class="wp-block-latest-comments__comment-link" href="https://adriancallaghan.co.uk/clikstats/#comment-208">clikStats</a></footer></article></li><li class="wp-block-latest-comments__comment"><article><footer class="wp-block-latest-comments__comment-meta"><span class="wp-block-latest-comments__comment-author">Justin Glover</span> on <a class="wp-block-latest-comments__comment-link" href="https://adriancallaghan.co.uk/remote-controlling-tivo/#comment-225">Remote controlling Tivo</a></footer></article></li><li class="wp-block-latest-comments__comment"><article><footer class="wp-block-latest-comments__comment-meta"><span class="wp-block-latest-comments__comment-author">Gary Wilson</span> on <a class="wp-block-latest-comments__comment-link" href="https://adriancallaghan.co.uk/remote-controlling-tivo/#comment-224">Remote controlling Tivo</a></footer></article></li><li class="wp-block-latest-comments__comment"><article><footer class="wp-block-latest-comments__comment-meta"><span class="wp-block-latest-comments__comment-author">Adrian Byrne</span> on <a class="wp-block-latest-comments__comment-link" href="https://adriancallaghan.co.uk/remote-controlling-tivo/#comment-223">Remote controlling Tivo</a></footer></article></li></ol></div></div></div><div id="block-5" class="terminal-block widget widget_block"><div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow"><h2 class="wp-block-heading">Archives</h2><ul class="wp-block-archives-list wp-block-archives"> <li><a href='https://adriancallaghan.co.uk/2017/05/'>May 2017</a></li> <li><a href='https://adriancallaghan.co.uk/2017/03/'>March 2017</a></li> <li><a href='https://adriancallaghan.co.uk/2016/12/'>December 2016</a></li> <li><a href='https://adriancallaghan.co.uk/2016/07/'>July 2016</a></li> <li><a href='https://adriancallaghan.co.uk/2015/07/'>July 2015</a></li> <li><a href='https://adriancallaghan.co.uk/2015/04/'>April 2015</a></li> <li><a href='https://adriancallaghan.co.uk/2015/02/'>February 2015</a></li> <li><a href='https://adriancallaghan.co.uk/2014/12/'>December 2014</a></li> <li><a href='https://adriancallaghan.co.uk/2014/08/'>August 2014</a></li> <li><a href='https://adriancallaghan.co.uk/2013/06/'>June 2013</a></li> <li><a href='https://adriancallaghan.co.uk/2013/03/'>March 2013</a></li> <li><a href='https://adriancallaghan.co.uk/2012/10/'>October 2012</a></li> <li><a href='https://adriancallaghan.co.uk/2012/06/'>June 2012</a></li> <li><a href='https://adriancallaghan.co.uk/2012/01/'>January 2012</a></li> <li><a href='https://adriancallaghan.co.uk/2011/12/'>December 2011</a></li> <li><a href='https://adriancallaghan.co.uk/2011/09/'>September 2011</a></li> <li><a href='https://adriancallaghan.co.uk/2011/08/'>August 2011</a></li> <li><a href='https://adriancallaghan.co.uk/2011/06/'>June 2011</a></li> <li><a href='https://adriancallaghan.co.uk/2010/08/'>August 2010</a></li> <li><a href='https://adriancallaghan.co.uk/2010/07/'>July 2010</a></li> <li><a href='https://adriancallaghan.co.uk/2009/08/'>August 2009</a></li> <li><a href='https://adriancallaghan.co.uk/2009/07/'>July 2009</a></li> <li><a href='https://adriancallaghan.co.uk/2009/04/'>April 2009</a></li> <li><a href='https://adriancallaghan.co.uk/2009/02/'>February 2009</a></li> <li><a href='https://adriancallaghan.co.uk/2009/01/'>January 2009</a></li> <li><a href='https://adriancallaghan.co.uk/2008/12/'>December 2008</a></li> <li><a href='https://adriancallaghan.co.uk/2008/11/'>November 2008</a></li> <li><a href='https://adriancallaghan.co.uk/2008/10/'>October 2008</a></li> </ul></div></div></div><div id="block-6" class="terminal-block widget widget_block"><div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow"><h2 class="wp-block-heading">Categories</h2><ul class="wp-block-categories-list wp-block-categories"> <li class="cat-item cat-item-11"><a href="https://adriancallaghan.co.uk/Categorys/programming/applications/">Applications</a> </li> <li class="cat-item cat-item-12"><a href="https://adriancallaghan.co.uk/Categorys/misc/baby-p/">baby p</a> </li> <li class="cat-item cat-item-13"><a href="https://adriancallaghan.co.uk/Categorys/programming/bash/">Bash</a> </li> <li class="cat-item cat-item-15"><a href="https://adriancallaghan.co.uk/Categorys/misc/car-woes/">Car woes</a> </li> <li class="cat-item cat-item-16"><a href="https://adriancallaghan.co.uk/Categorys/misc/hardware/">Hardware</a> </li> <li class="cat-item cat-item-17"><a href="https://adriancallaghan.co.uk/Categorys/programming/javascript/">Javascript</a> </li> <li class="cat-item cat-item-4"><a href="https://adriancallaghan.co.uk/Categorys/misc/music/">Music</a> </li> <li class="cat-item cat-item-18"><a href="https://adriancallaghan.co.uk/Categorys/programming/php/">Php</a> </li> <li class="cat-item cat-item-5"><a href="https://adriancallaghan.co.uk/Categorys/programming/">Programming</a> </li> <li class="cat-item cat-item-6"><a href="https://adriancallaghan.co.uk/Categorys/programming/thickdialog/">Thickdialog</a> </li> <li class="cat-item cat-item-8"><a href="https://adriancallaghan.co.uk/Categorys/programming/wordpress/">Wordpress</a> </li> <li class="cat-item cat-item-9"><a href="https://adriancallaghan.co.uk/Categorys/programming/zend/">ZF1</a> </li> <li class="cat-item cat-item-10"><a href="https://adriancallaghan.co.uk/Categorys/programming/zf2/">ZF2</a> </li> </ul></div></div></div> </aside> </div> <style> /* Single Post Wrapper */ .single-post-wrapper { grid-template-columns: 1fr 320px; gap: 2rem; } /* Post Content Styling */ .single-post .post-content .terminal-content { font-size: 1.1rem; line-height: 1.8; } .single-post .post-content h2, .single-post .post-content h3, .single-post .post-content h4, .single-post .post-content h5, .single-post .post-content h6 { color: var(--neon-cyan); margin: 2rem 0 1rem 0; text-shadow: 0 0 10px var(--neon-cyan); } .single-post .post-content p { margin-bottom: 1.5rem; } .single-post .post-content blockquote { border-left: 4px solid var(--neon-purple); padding-left: 1.5rem; margin: 2rem 0; font-style: italic; color: var(--neon-purple); background: rgba(191,0,255,0.1); padding: 1rem 1.5rem; border-radius: 0 8px 8px 0; } .single-post .post-content ul, .single-post .post-content ol { margin: 1.5rem 0; padding-left: 2rem; } .single-post .post-content li { margin-bottom: 0.5rem; } .single-post .post-content a { color: var(--neon-green); text-decoration: underline; transition: all 0.3s ease; } .single-post .post-content a:hover { color: var(--neon-cyan); text-shadow: 0 0 10px var(--neon-cyan); } /* Page Links */ .page-links { margin: 2rem 0; text-align: center; } .page-links .page-number { display: inline-block; padding: 0.5rem 1rem; margin: 0 0.2rem; background: rgba(0,255,255,0.1); border: 1px solid var(--neon-cyan); color: var(--text-primary); text-decoration: none; transition: all 0.3s ease; } .page-links .page-number:hover { background: var(--neon-cyan); color: var(--dark-bg); box-shadow: 0 0 15px var(--neon-cyan); } /* Post Tags */ .post-tags .terminal-content a { display: inline-block; padding: 0.3rem 0.8rem; margin: 0.2rem; background: rgba(57,255,20,0.1); border: 1px solid var(--neon-green); color: var(--neon-green); text-decoration: none; border-radius: 15px; font-size: 0.9rem; transition: all 0.3s ease; } .post-tags .terminal-content a:hover { background: var(--neon-green); color: var(--dark-bg); box-shadow: 0 0 10px var(--neon-green); } /* Author Bio */ .author-info { display: flex; gap: 1.5rem; align-items: flex-start; } .author-avatar img { border-radius: 50%; border: 2px solid var(--neon-cyan); width: 80px; height: 80px; } .author-details { flex: 1; } .author-name { margin-bottom: 0.5rem; } .author-name a { color: var(--neon-cyan); text-decoration: none; } .author-description { margin-bottom: 1rem; line-height: 1.6; } .author-links { display: flex; gap: 1rem; } .author-links a { font-size: 0.9rem; text-decoration: none; border: 1px solid currentColor; padding: 0.3rem 0.8rem; border-radius: 15px; transition: all 0.3s ease; } .author-links a:hover { box-shadow: 0 0 10px currentColor; } /* Related Posts */ .related-posts-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1.5rem; margin-top: 1.5rem; } .related-post-item { border: 1px solid var(--grid-color); border-radius: 8px; overflow: hidden; transition: all 0.3s ease; } .related-post-item:hover { border-color: var(--neon-cyan); box-shadow: 0 0 15px rgba(0,255,255,0.3); } .related-post-thumbnail img { width: 100%; height: 120px; object-fit: cover; transition: transform 0.3s ease; } .related-post-item:hover .related-post-thumbnail img { transform: scale(1.05); } .related-post-content { padding: 1rem; } .related-post-title a { color: var(--text-primary); text-decoration: none; font-size: 0.95rem; line-height: 1.4; } .related-post-title a:hover { color: var(--neon-cyan); } .related-post-meta { color: var(--neon-orange); font-size: 0.8rem; margin: 0.5rem 0; font-family: var(--font-mono); } .related-post-excerpt { font-size: 0.85rem; line-height: 1.4; color: rgba(255,255,255,0.8); } /* Sidebar Widgets */ .single-sidebar .widget { margin-bottom: 2rem; } .popular-posts-list, .categories-list { list-style: none; } .popular-post-item, .category-item { margin-bottom: 1rem; } .popular-post-link, .category-link { display: block; color: var(--text-primary); text-decoration: none; padding: 0.5rem; border-left: 2px solid transparent; transition: all 0.3s ease; } .popular-post-link:hover, .category-link:hover { border-left-color: var(--neon-green); background: rgba(57,255,20,0.1); color: var(--neon-green); } .popular-post-title, .category-name { display: block; font-size: 0.9rem; line-height: 1.3; } .popular-post-meta, .category-count { display: block; font-size: 0.8rem; color: var(--neon-orange); font-family: var(--font-mono); margin-top: 0.2rem; } /* Comments Styling */ .comments-section .terminal-content { max-height: 600px; overflow-y: auto; } /* Responsive Design */ @media (max-width: 1024px) { .single-post-wrapper { grid-template-columns: 1fr; gap: 2rem; } .related-posts-grid { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 768px) { .author-info { flex-direction: column; text-align: center; } .author-avatar { align-self: center; } .related-posts-grid { grid-template-columns: 1fr; } .author-links { justify-content: center; } } @media (max-width: 480px) { .single-post .post-content .terminal-content { font-size: 1rem; } .page-links .page-number { padding: 0.4rem 0.8rem; margin: 0.1rem; font-size: 0.9rem; } } </style> </div> <!-- .container --> </main><!-- .main-content --> <!-- Site Footer --> <footer class="site-footer" id="colophon"> <div class="footer-content"> <!-- Navigation Links for Posts --> <div class="post-navigation terminal-block"> <div class="terminal-header"> <span>Navigation</span> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="terminal-content"> <div class="nav-previous"><a href="https://adriancallaghan.co.uk/form-to-database-php/" class="neon-text">← form to database php</a></div><div class="nav-next"><a href="https://adriancallaghan.co.uk/galaxy-s3-no-internet-on-virgin-media-super-hub/" class="neon-text">Galaxy S3 no internet on… →</a></div> </div> </div> <!-- Copyright and Credits --> <div class="site-info terminal-block"> <div class="terminal-header"> <span>System Info</span> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="terminal-content"> <p class="copyright"> © 2025 <span class="neon-text">Adrian Callaghan</span> - Full Stack Developer </p> <p class="credits"> Powered by <span class="neon-text">WordPress</span> | Theme: <span class="neon-text">Adrians 80s</span> | Built with <span class="neon-text">❤</span> and lots of <span class="neon-text">caffeine</span> </p> </div> </div> <!-- Scroll to Top Button --> <button id="scroll-to-top" class="scroll-to-top" aria-label="Scroll to top"> <span>↑</span> </button> </div> </footer> </div><!-- .parallax-container --> <!-- Terminal Loading Animation --> <div id="page-loader" class="page-loader"> <div class="terminal-loader"> <div class="loader-header"> <span>LOADING...</span> <div class="terminal-buttons"> <div class="terminal-button close"></div> <div class="terminal-button minimize"></div> <div class="terminal-button maximize"></div> </div> </div> <div class="loader-content"> <div class="loading-text"> <span class="typing-text">Initializing CyberDev systems...</span> </div> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> </div> </div> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"\/*"},{"not":{"href_matches":["\/wp-*.php","\/wp-admin\/*","\/wp-content\/uploads\/*","\/wp-content\/*","\/wp-content\/plugins\/*","\/wp-content\/themes\/cyberdev-80s\/*","\/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <script type="text/javascript" id="cyberdev-animations-js-extra"> /* <![CDATA[ */ var cyberdev_ajax = {"ajax_url":"https:\/\/adriancallaghan.co.uk\/wp-admin\/admin-ajax.php","nonce":"b555da306a"}; /* ]]> */ </script> <script type="text/javascript" src="https://adriancallaghan.co.uk/wp-content/themes/cyberdev-80s/js/animations.js?ver=1.0.0" id="cyberdev-animations-js"></script> <script type="text/javascript" src="https://adriancallaghan.co.uk/wp-content/themes/cyberdev-80s/js/parallax.js?ver=1.0.0" id="cyberdev-parallax-js"></script> <script type="text/javascript" src="https://adriancallaghan.co.uk/wp-content/themes/cyberdev-80s/js/particles.js?ver=1.0.0" id="cyberdev-particles-js"></script> <script type="text/javascript" src="https://adriancallaghan.co.uk/wp-includes/js/comment-reply.min.js?ver=6.8.2" id="comment-reply-js" async="async" data-wp-strategy="async"></script> <script defer type="text/javascript" src="https://adriancallaghan.co.uk/wp-content/plugins/akismet/_inc/akismet-frontend.js?ver=1753178062" id="akismet-frontend-js"></script> <style> /* Page Loader Styles */ .page-loader { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: var(--dark-bg); z-index: 9999; display: flex; justify-content: center; align-items: center; transition: opacity 0.5s ease; } .page-loader.loaded { opacity: 0; pointer-events: none; } .terminal-loader { background: rgba(0,0,0,0.9); border: 2px solid var(--neon-cyan); border-radius: 10px; width: 400px; max-width: 90%; } .loader-header { background: var(--neon-cyan); color: var(--dark-bg); padding: 0.5rem 1rem; display: flex; justify-content: space-between; align-items: center; font-family: var(--font-mono); } .loader-content { padding: 2rem; } .typing-text { font-family: var(--font-mono); color: var(--neon-green); display: block; margin-bottom: 1rem; } .progress-bar { width: 100%; height: 4px; background: rgba(0,255,255,0.2); border-radius: 2px; overflow: hidden; } .progress-fill { height: 100%; background: var(--neon-cyan); width: 0; border-radius: 2px; animation: progressFill 2s ease-in-out; box-shadow: 0 0 10px var(--neon-cyan); } @keyframes progressFill { 0% { width: 0; } 100% { width: 100%; } } /* Scroll to Top Button */ .scroll-to-top { position: fixed; bottom: 2rem; right: 2rem; background: var(--neon-purple); color: var(--dark-bg); border: none; width: 50px; height: 50px; border-radius: 50%; cursor: pointer; opacity: 0; visibility: hidden; transition: all 0.3s ease; box-shadow: 0 0 20px var(--neon-purple); font-size: 1.2rem; font-weight: bold; z-index: 1000; } .scroll-to-top.visible { opacity: 1; visibility: visible; } .scroll-to-top:hover { transform: scale(1.1); box-shadow: 0 0 30px var(--neon-purple); } /* Footer Navigation */ .footer-navigation ul { display: flex; list-style: none; gap: 1rem; justify-content: center; margin-top: 1rem; } .footer-navigation a { color: var(--text-primary); text-decoration: none; font-family: var(--font-mono); font-size: 0.9rem; transition: color 0.3s ease; } .footer-navigation a:hover { color: var(--neon-orange); text-shadow: 0 0 10px var(--neon-orange); } /* Post Navigation */ .post-navigation { margin: 2rem 0; } .post-navigation .terminal-content { display: flex; justify-content: space-between; align-items: center; } .nav-previous, .nav-next { flex: 1; } .nav-next { text-align: right; } .nav-previous a, .nav-next a { font-family: var(--font-mono); font-size: 0.9rem; } @media (max-width: 768px) { .terminal-loader { width: 300px; } .loader-content { padding: 1rem; } .footer-navigation ul { flex-direction: column; gap: 0.5rem; text-align: center; } .post-navigation .terminal-content { flex-direction: column; gap: 1rem; text-align: center; } .nav-next { text-align: center; } .scroll-to-top { bottom: 1rem; right: 1rem; width: 40px; height: 40px; font-size: 1rem; } } </style> </body> </html> <!-- Dynamic page generated in 0.129 seconds. --> <!-- Cached page generated by WP-Super-Cache on 2025-08-22 06:05:26 --> <!-- Compression = gzip -->