RS TV Show Tracker is a software designed for TV show addicts – by a TV show addict.
The software allows you to keep track of all the TV shows you watch, by notifying you when a new episode was aired.
Key features of the software:
1 The software only runs on Windows 7 and above.
2 This is accomplished by monitoring the open file handles of your video player. If an episode is open for more than 10 minutes, it’s marked as seen.
3 Scanning a 1 TB local drive containing 11,016 files and 783 folders takes only 0.23 seconds!
4 This feature only works when the target directory is on an NTFS partition.
The software supports the following sites:
* Features marked with a red asterisk are not yet available in the stable release, however if you’re feeling adventurous, they should be in the nightly builds.
1 Wikipedia and The Futon Critic support is very experimental and not yet selectable by users.
2 BitMeTV’s support has been deprecated due to their decision to globally ban a whole country. Don't click here.
3 EzTV is currently not included because eztv.it’s search is bogus.
4 Unfortunately Katz.cd was hacked and there’s a good chance it won’t come back online. More infos here.
5 PreScene has been removed because the database wasn’t always up-to-date and the servers were very slow to answer for some search queries.
6 Unfortunately Google has deprecated all of their web search APIs, so while they still work, all methods which use it should be ported in time to Bing.
7 Tube+ was removed in commit d653ade30141e8c47d90ee7668d52a32c1f43f4d.
8 Scroogle was discontinued and the new intended replacement is Seeks-Project.
9 ev0.in, Mukki.org and PhazeDDL have ceased to exist.
10 TVTorrentz.org has moved on.
After every major git commit, the software is compiled and uploaded to Dropbox, SkyDrive and/or Google Drive. Since stable releases on the Downloads page are rare, this page was created so you can enjoy the latest updates pushed into the git repository in binary form.
These packages contain work-in-progress binaries that may contain not yet fully developed features or UI elements that are not working as expected or not working at all. It may also corrupt your database and/or configuration file, so backup them before using these! If you plan to switch back to the stable releases, reload your database backup, as it may have been upgraded in a non-backwards-compatible way by the nightly builds. You've been warned.
AnyCPU
, which means it'll run natively on x86/x64/ARM
* Features marked with a red asterisk will require a donation key in the stable release, but they are freely available in these nightly versions, and will be available afterwards in the stable releases for those who are using an UUID which participated in the nightly testing going on right now.
The software was designed to automatically search for derived classes in the current application domain of a base class and use them. This way, every component of the software is extendable. You can integrate your own site into the software just by extending a class: this can be done either from within a .NET language compiled to a library or an external python script, which the software will interpret at runtime using IronPython.
A lot of useful methods are publicly exposed in the RoliSoft.TVShowTracker.Utils
class for you to use.
The software was designed to be extensible since day 1, however external assemblies were not searched and loaded until November 2011. This version is able to load any .NET assembly or Python script, and use their classes.
It's really easy to write a plugin using a .NET language:
anything.Plugin.dll
RSTVShowTracker.exe
as a referenceHtmlAgilityPack.dll
, Newtonsoft.Json.dll
, etc., depending on what you're going to useIPlugin
interface:Before starting, take a look at the already implemented classes in the repository. You can download a C# file from there, and only modify the names and XPaths, since those are already internal plugins.
Python scripts are officially supported as a way to implement plugins without having to compile the code to a .NET assembly.
It's easy to subclass a .NET type using IronPython. Here's a working line-by-line port of TvTorrentsRo.cs:
import clr
clr.AddReference("System")
clr.AddReferenceToFile("RSTVShowTracker.exe")
from System import *
from System.Collections.Generic import *
from System.Text.RegularExpressions import *
from RoliSoft.TVShowTracker import *
from RoliSoft.TVShowTracker.Parsers.Downloads import *
class TvTorrentsPy(DownloadSearchEngine):
def get_Name(self):
return "Tv Torrents Ro w/ IPy"
def get_Site(self):
return "http://freshon.tv/"
def get_Icon(self):
return "http://static.freshon.tv/favicon.ico"
def get_Developer(self):
return "RoliSoft"
def get_Version(self):
return Utils.DateTimeToVersion("2011-11-06")
def get_Private(self):
return True
def get_RequiredCookies(self):
return Array[str](["uid", "pass"])
def get_CanLogin(self):
return True
def get_LoginURL(self):
return self.get_Site() + "login.php?action=makelogin"
def get_LoginFields(self):
return Dictionary[str, object](dictionary = {"username": LoginFieldTypes.UserName, "password": LoginFieldTypes.Password})
def get_Type(self):
return Types.Torrent
def Login(self, username, password):
return self.GazelleTrackerLogin(username, password)
def Search(self, query):
html = Utils.GetHTML(self.Site + "browse.php?search=" + Uri.EscapeUriString(query), cookies = self.Cookies)
if self.GazelleTrackerLoginRequired(html.DocumentNode):
raise Security.Authentication.AuthenticationException()
links = html.DocumentNode.SelectNodes("//table/tr/td/div[1]/a")
if links is None:
return
for node in links:
link = Link(self)
link.Release = node.GetAttributeValue("title", None)
link.InfoURL = self.Site.rstrip("/") + node.GetAttributeValue("href", None)
link.FileURL = self.Site + "download.php?id=" + \
Regex.Replace(node.GetAttributeValue("href", None), "[^0-9]+", str.Empty) + "&type=torrent"
link.Size = node.GetHtmlValue("../../../td[@class='table_size']").strip().replace("<br>", " ")
link.Quality = FileNames.Parser.ParseQuality(link.Release)
link.Infos = Link.SeedLeechFormat.FormatWith(node.GetTextValue("../../../td[@class='table_seeders']").Trim(), \
node.GetTextValue("../../../td[@class='table_leechers']").Trim())
if node.GetHtmlValue("../..//img[@alt='50% Free']") is not None:
link.Infos += ", 50% Free"
if node.GetHtmlValue("../..//img[@alt='100% Free']") is not None:
link.Infos += ", 100% Free"
yield link
return
To run it, save the above code as TvTorrentsPy.Plugin.py
and place it near the application. The name of the file has to be exactly the name of the class you want to load plus .Plugin.py
. This means you can only extend 1 class/file.
If something isn't working out for you, you can contact me via email or by using the " Send feedback" menu option from within the software.
This is possible by subclassing the ScriptingPlugin
class. The newly derived class will register a new file extension, for example .js
, and when the software finds a file named like anything.Plugin.js
it'll call the LoadScript(file)
method of your class. This method will return a list of exposed types in the form of ExternalType
objects. When the software is ready to use your plugin, it'll call the CreateInstance
method.
For more informations on how to do this, read source of the base type, ScriptingPlugin.cs, and the source of a working implementation, IronPython.cs.
Quick tips:
ExternalType
class and include more information into it, like the IronPython
class does with its own DLRType
.CreateInstance
method will look:public override T CreateInstance<T>(ExternalType type)
{
dynamic obj = IronWhatNotEngine.CreateDynamicInstance(type);
// 'obj' is now a dynamic object, on which if you call a method it'll forward it to the interpreter
// but we need a native CLR object reference for the software, so we'll need to generate a proxy class
// which subclasses from our 'T' type and forwards any calls to 'obj'
// this is *EXACTLY* how you do it in impromptu with 'obj':
return obj.ActLike<T>();
}
It is possible to load a plugin when the software starts. This lets you to do a variety of things, such as registering background tasks or modify the UI. To do this, all you have to do is to subclass the StartupPlugin
class. These plugins will be called in RoliSoft.TVShowTracker.MainWindow.WindowLoaded
.
An example code in Python, which manipulates the tray icon at startup by changing its icon to and appending to its title:
import clr
clr.AddReference("System")
clr.AddReference("System.Drawing")
clr.AddReference("PresentationFramework")
clr.AddReferenceToFile("RSTVShowTracker.exe")
from System import *
from System.Drawing import Icon, Bitmap
from System.Windows import Application
from RoliSoft.TVShowTracker import *
class StartupTest(StartupPlugin):
def get_Name(self):
return "Startup Test"
def get_Developer(self):
return "RoliSoft"
def get_Version(self):
return Utils.DateTimeToVersion("2011-12-30")
def Run(self):
icon = Application.GetResourceStream(Uri("pack://application:,,,/RSTVShowTracker;component/Images/disc.png")).Stream
MainWindow.NotifyIcon.Text += " - now with 140% more awesomeness!"
MainWindow.NotifyIcon.Icon = Icon.FromHandle(Bitmap(icon).GetHicon())
The following languages are not officially supported as a way to write plugins, however I've played around with them in my free time and published my findings here. More are coming soon.
There are multiple ways to do .Net/Java interoperability.
This is probably the easiest way to do it and the most mature project to do it with. According to Mono-Project.com, IKVM.NET can run the whole Eclipse IDE under Mono.1
mscorlib
reference error when you try to touch RSTVShowTracker.exe
. To mend this, force the IKVM binaries to run under .Net 4.0. To do this, go into ikvm\bin\
and create the following three files:
ikvm.exe.config
ikvmc.exe.config
ikvmstub.exe.config
<configuration>
<startup>
<supportedRuntime version="v4.0.30319"/>
</startup>
</configuration>
RSTVShowTracker.jar
file which you will reference later in your project, issue the following command:ikvmstub -r:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll \
-r:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationCore.dll \
-namespace:RoliSoft.TVShowTracker \
"<em>FULL_PATH_TO_YOUR_INSTALLATION</em>\RSTVShowTracker.exe"
anything.Plugin.jar
RSTVShowTracker.jar
as a referenceIPlugin
interface.dll
file:ikvmc <em>anything</em>.Plugin.jar -r:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll \
-r:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationCore.dll \
-r:"<em>FULL_PATH_TO_YOUR_INSTALLATION</em>\RSTVShowTracker.exe" \
-r:"<em>FULL_PATH_TO_YOUR_INSTALLATION</em>\*.dll"
anything.Plugin.dll
file should be usable by the software without further modification.There are various solutions that offer interoperability between the two VMs by using an automatically generated internal webservice or something smarter. Most of these solutions are commercial, but you'll be able to find free and open-source solutions as well. Please avoid using commercial solutions if you want to publish your plugin: first off, their license may not permit the redistribution of their libraries in open-source softwares, and secondly, if you abandon the plugin it will be a lot harder or legally impossible for others to maintain your plugin.
An interesting project I found while researching this method was jni4net. Unfortunately I was not able to successfully generate a proxy using the provided proxygen.exe
tool. Maybe if it listed errors, I could've done something to fix them, but the generator terminates without printing any error messages or codes. On the mailing lists, the developer claims that the 0.8.x branch will never be able to generate proxies for complicated classes.2 While the project itself looks promising, it's still in an early stage of development.
Another interesting project is Espresso, which in turn is an extended version of Caffeine. However, I didn't play around with these since the original project is from 2004 and the updated one is from 2006. The most likely outcome of my experimentation would be that they're incompatible with .Net 4.0 and/or JRE 7.
*.Plugin.jar
supportIn the "Adding a custom interpreter" section I've talked about a theoretical way to dynamically invoke methods from other languages. It would be possible to use one of the first two methods and automate proxy generation and bridging in a ScriptingPlugin
class.
The software can be extended using files compiled by phpc.exe
in pure mode. The resulting library file will expose all the exported classes and the software will be able to cast it back to ParserEngine
and its derived classes.
<?
import namespace System;
import namespace System:::Collections:::Generic;
import namespace RoliSoft:::TVShowTracker;
import namespace RoliSoft:::TVShowTracker:::Parsers:::Downloads;
namespace RoliSoft:::TVShowTracker:::Parsers:::Downloads:::Engines:::Experimental
{
public class TestEngine extends DownloadSearchEngine
{
function get_Name()
{
return "Test Engine";
}
function get_Site()
{
return "http://lab.rolisoft.net/";
}
function get_Type()
{
return Types::Torrent;
}
function get_Private()
{
return true;
}
function get_RequiredCookies()
{
return array("uid", "pass");
}
function get_CanLogin()
{
return true;
}
function get_LoginURL()
{
return get_Site() + "login.php";
}
function get_LoginFields()
{
return array(
"username" => LoginFieldTypes::UserName,
"password" => LoginFieldTypes::Password
);
}
function Login($username, $password)
{
return GazelleTrackerLogin($username, $password);
}
function Search($query)
{
$list = new i'List'<:Link:>;
// TODO
return $list;
}
}
}
?>
To compile this PHP file into a .NET library, you'll have to issue the following command:
phpc /pure /target:dll /r:RSTVShowTracker.exe /out:TestEngine.Plugin.dll TestEngine.php
The compiled assembly's name doesn't have to match its classes name and can contain multiple exported classes. They will all load, once you place the compiled library near the application and restart it.
To redistribute your plugin, you'll have to include at least four additional assemblies:
If you want to use native extensions, you'll also have to include:
They are all located in your Phalanger installation's Bin
and Wrappers
directory. (C:\Program Files (x86)\Phalanger 2.1\Bin
)
Although it is possible to compile Perl scripts, it has some drawbacks:
Regardless, if you want to do it, here's a sample Perl script to get you started:
package RoliSoft::TVShowTracker::Parsers::Downloads::Engines::Experimental;
use strict;
use PerlNET qw(with AUTOCALL);
use namespace "System";
use namespace "System.Collections.Generic";
use namespace "RoliSoft.TVShowTracker";
use namespace "RoliSoft.TVShowTracker.Parsers.Downloads";
# define the exported interface
=for interface
[extends: DownloadSearchEngine]
string get_Name();
string get_Site();
string get_Icon();
bool get_Private();
string[] get_RequiredCookies();
bool get_CanLogin();
string get_LoginURL();
Types get_Type();
any Search(string query);
string Login(string username, string password);
=cut
# and now start implementing the functions above
sub get_Name {
return "TestEngine";
}
# ...
sub Login {
my($this, $self, $username, $password) = @_;
return $this->GazelleTrackerLogin($username, $password);
}
When you're done, to compile this Perl script, you'll have to issue the following command:
plc --reference RSTVShowTracker.exe --norunlib --target library --out TestEngine.Plugin.dll TestEngine.pl
You should know, that when I was playing around with PerlNET, it didn't support .NET 4, so I had to recompile the software for .NET 3.5, which meant cutting out some crucial parts of the software. If you find a way to get around this please send me an email with the instructions, so I can update this document.
To redistribute your plugin, you'll have to include two additional assemblies:
C:\Program Files\ActiveState Perl Dev Kit 9.1\bin
C:\WINDOWS\assembly\GAC_MSIL\Perl514RT910\9.1.0.32898__cea8284aa6739163\
To browse the source code of the project go to GitHub or BitBucket.
To get the source code and compile it, you’ll need to install git and either Windows 8.1 SDK or Visual Studio 2013, then issue the following commands:
git clone git://github.com/RoliSoft/RS-TV-Show-Tracker.git cd tvshowtracker msbuild
To edit the project you will need Visual Studio 2013, because it’s a .Net 4.5 WPF application.
The source is distributed under the Microsoft Reciprocal License, which is an OSI-certified open source license.
34cb7911 @ 2014-04-14 10:55:24 GMT+0000 (Coordinated Universal Time)
4c9c7236 @ 2014-04-14 09:55:50 GMT+0000 (Coordinated Universal Time)
add95153 @ 2014-04-14 09:09:42 GMT+0000 (Coordinated Universal Time)
7bf54bc0 @ 2014-04-14 09:01:23 GMT+0000 (Coordinated Universal Time)
bbfbeca8 @ 2014-04-14 08:32:01 GMT+0000 (Coordinated Universal Time)
5f9b7bc3 @ 2014-01-17 16:15:23 GMT+0000 (Coordinated Universal Time)
58f261ff @ 2013-12-29 04:23:23 GMT+0000 (Coordinated Universal Time)
3bb81cd6 @ 2013-12-29 04:09:43 GMT+0000 (Coordinated Universal Time)
9d917f5a @ 2013-12-28 06:37:59 GMT+0000 (Coordinated Universal Time)
2823cea3 @ 2013-12-28 05:45:47 GMT+0000 (Coordinated Universal Time)
c0f4270b @ 2013-12-28 05:34:12 GMT+0000 (Coordinated Universal Time)