diff --git a/.gitignore b/.gitignore index e8e412b..240be62 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/TVServerXBMC/*.suo -/TVServerXBMC/bin -/TVServerXBMC/obj \ No newline at end of file +/TVServerKodi/*.suo +/TVServerKodi/bin +/TVServerKodi/obj \ No newline at end of file diff --git a/README b/README index 4a06f83..0e74702 100644 --- a/README +++ b/README @@ -1,4 +1,8 @@ -This TVServer plugin (or standalone tool for debugging purposes) is the server side for both the MediaPortal PVR clients and the python "TVServer" video plugin. This version is an extended and improved version of the existing MediaPortal TV Server plugin "TVServerXBMC" (by EvilDude/Prashant) from the MediaPortal mp-plugins repository. +This TVServer plugin (or standalone tool for debugging purposes) is the server side for both the MediaPortal PVR clients and the python "TVServer" video plugin. +This version is an extended and improved version of the existing MediaPortal TV Server plugin "TVServerXBMC" (by EvilDude/Prashant) from the MediaPortal mp-plugins repository. + +This plugin is compatible with the MediaPortal 1 TV Server. +Supported clients are: XBMC Frodo, XBMC Gotham, Kodi Helix and above Main changes: more commands added, needed for the PVR addon; diff --git a/TVServerKodi/Changelog.txt b/TVServerKodi/Changelog.txt new file mode 100644 index 0000000..8d78d20 --- /dev/null +++ b/TVServerKodi/Changelog.txt @@ -0,0 +1,184 @@ +1.14.0.133: +- Updated: referenced assemblies for TVServer 1.14.0 (final) +- Updated: solution to VS2013 + +1.12.0.132: +- Fixed: Don't log the ThreadAbortException on a normal TVService shutdown + +1.12.0.131: +- Fixed: ListSchedules: don't add a parent schedule id when the schedule type = once +- Extra try/catch blocks around socket connections + +1.12.0.130: +- Added: Support for the MediaPortal 2 version of the TV Server (needs SQLite support) +- Added: timers: additional return values: parentScheduleID, program genre string and program description +- Modified: timers: series: return also the actual schedule and not only the underlying programs + The underlying programs are now shown as subtimers with a parent timer in Kodi Jarvis (v16) +- Fixed: also stop the communication threads when the TV Server service is terminating us... + +1.12.0.129: +- Fixed: An early remote shutdown could cause a TV Server crash in the HandleConnection() function +- Added: Optional parameter to "GetUserName" for fetching all timeshift users (credits Romank1) +- Extended: "IsTimeshifting" command now also returns the UNC timeshift file (credits Romank1) +- Updated: referenced assemblies for TVServer 1.12.0 (final) + +1.10.0.128: +- Fixed: Deleting one or more recordings gives an empty list in Kodi/XBMC due to a database exception on the missing records +- Fixed: GetRecordingDriveSpace triggers an exception when one or more cards have no recording path set +- Fixed: GetRecordingDriveSpace returns 0 when the last card has no recording path set +- Changed: GetRecordingDriveSpace returns now the total disk size and free size for all cards and drives +- Fixed: EPG: episodeNumber should be episodeNum (credits: puenktchen) + +1.10.0.127: +- Added: PVRclientKodi connection protocol name +- Changed: New name: TVServerKodi +- Updated: referenced assemblies for TVServer 1.10.0 (final) + + +1.8.0.126: +- Updated: referenced assemblies for TVServer 1.8.0 (final) +- Added: MajorChannel.MinorChannel fields to the ListTVChannel and ListRadioChannel commands + +1.6.0.125 +- Added: HeartBeat support (re-uses the SignalQuality calls for this purpose) +- Changed: switched to VS2010 and .NET 4.0 +- Updated: referenced assemblies for TVServer 1.6.0 (final) + +1.5.0.124 +- Changed: do not cache the card list, channel lists and group lists +- Added: Support for downloading channel thumbs from the backend +- Updated: more exception handling to prevent TVServerXBMC plugin crashes +- Updated: referenced assemblies for TVServer 1.5.0 (final) + +1.4.0.123 +- Updated: referenced assemblies for TVServer 1.4.0 (final) + +1.3.0.122 +- Added: support for retrieving channels from multiple specified groups (>1, < All groups) +- Updated: referenced assemblies for TVServer 1.3.0 (final) +- Added: MPEI configuration for creating a MPEI file + +1.2.200.121: +- Added support for setting and retrieving the recording StopTime +- Added "GetRecordingStopTime" and "SetRecordingStopTime" commands + +1.2.200.120: +- Share creation improvements +- Channels: send also the VisibleInGuide option to XBMC + +1.2.200.119: +- Channel number fixes for MediaPortal TVServer 1.3.0 beta (v1.2.200). +- Fix SignalQuality value (was before identical to the SignalLevel value) +- Fix timeshift buffer id retrieval + +1.2.3.118: +- Add support for timer enable/disable of individual programs in a Series schedule + +1.2.3.117: +- Add support for retrieving and updating the recording "timesWatched" property +- Fixed: postRecordInterval retrieval for schedules + +1.2.3.116: +- Fixed: Recording title showed only episode name + +1.2.3.115: +- Add configuration tab in the TV Server plugin configuration +- Allow changing the TVServerXBMC port and store the setting in the TVServer database +- Add the option to create shares for the Timeshift and Recordings folders when using XBMC on a different machine +- Extend the GetCardSettings command with the sharenames (when available) +- Remove unneeded Gentle initialization from the plugin version. Only needed for the standalone exe +- Subscribe the plugin to TV Server events like EPG updates. TODO: forward them to XBMC + +1.2.3.114: +- Each MP Scheduled Program will translate into one Timer in xbmc. (Credits jajoflo) +- Each timer will retain it's schedule id so the behavior won't change when modifying/deleting a timer. (Credits jajoflo) + +1.2.3.113: +- Update binaries for MediaPortal TVServer 1.2.3 +- When there is an episode name, skip the title as it is usually redundant with the folder name. +- Properly handle Schedule not resolving to a program. (Occurs when the season is finished). +- Properly handle Instant recording not having a program name that matches the one in the EPG. + +1.2.2.112: +- Prefer program data for ListSchedules command when available (Thanks jajoflo) + +1.2.2.111: +- Extend ListRecordings command with Genre, IdChannel and IsRecording field + +1.2.2.110: +- Send timeshift buffer position to XBMC on a channel switch +- Update binaries for MediaPortal TVServer 1.2.2 + +1.2.1.109: +- Send TvResult as integer to XBMC to be able to show a localized error message when timeshifting fails + +1.2.1.108: +- Update to MediaPortal TVServer 1.2.1 +- Add GetSignalQuality command + +1.1.7.107: +- Fix radio webstream detection when starting a timeshift fails + +1.1.7.106: +- Add support for fetching TV card settings: GetCardSettings + +1.1.7.105: +- Extend ListRecordings command with episode/series fields + +1.1.7.104: +- Extend GetEPG command with optional start/endtime. Extended version returns also more EPG fields. + +1.1.7.103: +- Update sources and binaries for MediaPortal 1.2.0 beta (=v1.1.7) + +1.1.3.102: +- Use tuningdetails for retrieve the (provider) channel number + +1.1.3.101: +- Recompiled against MediaPortal TV Server v1.1.3 + +1.1.0.100: +- Add GetDriveSpace command (for recordings) +- [Schedule] Extend schedule API + +1.1.0.95: +- Fix for empty channel lists when one or more channels are deleted but still mapped to a group in the database (Thanks matejdro) +- Be more verbose on errors/exceptions +- Stop when the port is already in use + +1.1.0.90: +- Speedup TimeshiftChannel (no need to stop an existing timeshift, saves 2 sec) +- New command GetRecordingInfo for MediaPortal TSReader (RTSP) + +1.1.0.75: +- Fixed: Return the correct TVServerXBMC version number when running as plugin under the TV Server + +1.1.0.70: +- Better handling of multiple timeshifts from different users +- Give the Python TVServer plugin always the same user name to be able to stop the timeshifts + (Watching different channels from multiple python clients, is therefore not yet supported) +- Stop active timeshifts at client connection close for telnet and PVR clients +- Add new commands: GetUserName, SetUserName + +1.0.9.58: +- Add more TVServer log calls for DLL debugging purposes + +1.0.7.44: +- Use different usernames for different connections to prevent stopping timeshifts when 2 clients are watching the same stream + +1.0.7.24: +- Allow multiple connections +- GetVersion now return the TVServer version +- resolve hostnames for recording stream URLs +- Fix date/time formatting for schedules +- more status info during startup + +1.0.7.0: +- Added new commands: IsRecording/StopRecording +- Return more info about schedules + +1.0.6.0: +- Different date/time formatting to make the date/time fields locale/culture independent. + +1.0.5.0: +- Fix IPv6 name resolving. Should be always IPv4 now. \ No newline at end of file diff --git a/TVServerXBMC/Commands/AddSchedule.cs b/TVServerKodi/Commands/AddSchedule.cs similarity index 97% rename from TVServerXBMC/Commands/AddSchedule.cs rename to TVServerKodi/Commands/AddSchedule.cs index 1aff99d..aad25d9 100644 --- a/TVServerXBMC/Commands/AddSchedule.cs +++ b/TVServerKodi/Commands/AddSchedule.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class AddSchedule : CommandHandler { @@ -13,7 +13,7 @@ public AddSchedule(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // we want to list all channels in group arg[0] if ((arguments != null) && (arguments.Length >= 14)) diff --git a/TVServerXBMC/Commands/CloseConnection.cs b/TVServerKodi/Commands/CloseConnection.cs similarity index 88% rename from TVServerXBMC/Commands/CloseConnection.cs rename to TVServerKodi/Commands/CloseConnection.cs index c732392..a6b60a2 100644 --- a/TVServerXBMC/Commands/CloseConnection.cs +++ b/TVServerKodi/Commands/CloseConnection.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class CloseConnection : CommandHandler { @@ -12,7 +12,7 @@ public CloseConnection(ConnectionHandler connection) : base(connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // does not matter what arguments it has. diff --git a/TVServerXBMC/Commands/CommandHandler.cs b/TVServerKodi/Commands/CommandHandler.cs similarity index 90% rename from TVServerXBMC/Commands/CommandHandler.cs rename to TVServerKodi/Commands/CommandHandler.cs index 20f98f1..095e991 100644 --- a/TVServerXBMC/Commands/CommandHandler.cs +++ b/TVServerKodi/Commands/CommandHandler.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { abstract class CommandHandler { @@ -25,7 +25,7 @@ public DataWriter writer } } - public abstract void handleCommand(String command, String[] arguments, ref TvControl.User me); + public abstract void handleCommand(String command, String[] arguments, ref TvControl.IUser me); public abstract String getCommandToHandle(); } } diff --git a/TVServerXBMC/Commands/DataWriter.cs b/TVServerKodi/Commands/DataWriter.cs similarity index 94% rename from TVServerXBMC/Commands/DataWriter.cs rename to TVServerKodi/Commands/DataWriter.cs index 4c6677a..d8a84da 100644 --- a/TVServerXBMC/Commands/DataWriter.cs +++ b/TVServerKodi/Commands/DataWriter.cs @@ -3,13 +3,14 @@ using System.Text; using System.Net.Sockets; using System.IO; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class DataWriter { readonly StreamWriter writer; + readonly BinaryWriter binWriter; // will always end with a newline, so this is anything before that private String commandSeparator = Environment.NewLine; @@ -21,6 +22,7 @@ class DataWriter public DataWriter(NetworkStream stream) { writer = new StreamWriter(stream); + binWriter = new BinaryWriter(stream); } private String getSameString(String str) @@ -109,6 +111,12 @@ public void write(String line) Console.WriteLine("Socket write: " + line + commandSeparator); writer.Flush(); } + + public void writeBytes(Byte[] bytes) + { + binWriter.Write(bytes); + binWriter.Flush(); + } public void writeList(List list) { diff --git a/TVServerXBMC/Commands/DeleteRecordedTV.cs b/TVServerKodi/Commands/DeleteRecordedTV.cs similarity index 92% rename from TVServerXBMC/Commands/DeleteRecordedTV.cs rename to TVServerKodi/Commands/DeleteRecordedTV.cs index 45a8da5..14dbf06 100644 --- a/TVServerXBMC/Commands/DeleteRecordedTV.cs +++ b/TVServerKodi/Commands/DeleteRecordedTV.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class DeleteRecordedTV : CommandHandler { @@ -12,7 +12,7 @@ public DeleteRecordedTV(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { if (arguments == null) { diff --git a/TVServerXBMC/Commands/DeleteSchedule.cs b/TVServerKodi/Commands/DeleteSchedule.cs similarity index 92% rename from TVServerXBMC/Commands/DeleteSchedule.cs rename to TVServerKodi/Commands/DeleteSchedule.cs index b115965..387b6ad 100644 --- a/TVServerXBMC/Commands/DeleteSchedule.cs +++ b/TVServerKodi/Commands/DeleteSchedule.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class DeleteSchedule : CommandHandler { @@ -12,7 +12,7 @@ public DeleteSchedule(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { if (arguments == null) { diff --git a/TVServerXBMC/Commands/GetBackendName.cs b/TVServerKodi/Commands/GetBackendName.cs similarity index 84% rename from TVServerXBMC/Commands/GetBackendName.cs rename to TVServerKodi/Commands/GetBackendName.cs index 919e1f4..6db1a54 100644 --- a/TVServerXBMC/Commands/GetBackendName.cs +++ b/TVServerKodi/Commands/GetBackendName.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetBackendName : CommandHandler { @@ -13,7 +13,7 @@ public GetBackendName(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { writer.write(TVServerConnection.getBackendName()); } diff --git a/TVServerXBMC/Commands/GetCardSettings.cs b/TVServerKodi/Commands/GetCardSettings.cs similarity index 92% rename from TVServerXBMC/Commands/GetCardSettings.cs rename to TVServerKodi/Commands/GetCardSettings.cs index d242946..a073d07 100644 --- a/TVServerXBMC/Commands/GetCardSettings.cs +++ b/TVServerKodi/Commands/GetCardSettings.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetCardSettings : CommandHandler { @@ -13,7 +13,7 @@ public GetCardSettings(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { int cardID = -1; List results = new List(); diff --git a/TVServerXBMC/Commands/GetChannelCount.cs b/TVServerKodi/Commands/GetChannelCount.cs similarity index 90% rename from TVServerXBMC/Commands/GetChannelCount.cs rename to TVServerKodi/Commands/GetChannelCount.cs index 43a48fb..107fd87 100644 --- a/TVServerXBMC/Commands/GetChannelCount.cs +++ b/TVServerKodi/Commands/GetChannelCount.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetChannelCount : CommandHandler { @@ -12,7 +12,7 @@ public GetChannelCount(ConnectionHandler connection) : base(connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { String group; int count = 0; diff --git a/TVServerKodi/Commands/GetChannelThumb.cs b/TVServerKodi/Commands/GetChannelThumb.cs new file mode 100644 index 0000000..e61d96d --- /dev/null +++ b/TVServerKodi/Commands/GetChannelThumb.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using TVServerKodi; + +namespace TVServerKodi.Commands +{ + class GetChannelThumb : CommandHandler + { + private readonly string[] strThumbExt = { ".png", ".jpg", ".jpeg", ".bmp", ".gif" }; + + public GetChannelThumb(ConnectionHandler connection) : base(connection) + { + + } + + private string ToThumbFileName(string strName) + { + string strThumbName = strName; + + strThumbName.Replace(":", "_"); + strThumbName.Replace("/", "_"); + strThumbName.Replace("\\", "_"); + + return strThumbName; + } + + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) + { + + if ((arguments != null) && (arguments.Length == 2)) + { + try + { + string strChannelName = arguments[0]; + Boolean bIsRadio = Boolean.Parse(arguments[1]); + string strThumbName = "False"; + Boolean bFound = false; + + string strThumbPath = TVServerConnection.GetLogoPath(bIsRadio); + + string strThumbBaseName = ToThumbFileName(strChannelName); + + foreach (string strExt in strThumbExt) + { + strThumbName = strThumbBaseName + strExt; + if (File.Exists(strThumbPath + strThumbName)) + { + bFound = true; + break; + } + } + + if (!bFound) + { + writer.write("0|False"); + } + else + { + Byte[] thumbData = File.ReadAllBytes(strThumbPath + strThumbName); + Int32 fileLength = thumbData.Length; + Int32 thumbNameLength = strThumbName.Length; + Byte[] utf8ThumbName = System.Text.Encoding.UTF8.GetBytes(strThumbName); + Byte[] thumbNameLengthBytes = BitConverter.GetBytes(System.Net.IPAddress.HostToNetworkOrder(utf8ThumbName.Length)); + Byte[] fileLengthBytes = BitConverter.GetBytes(System.Net.IPAddress.HostToNetworkOrder(fileLength)); + + Byte[] strThumbInfo = { 0x31, 0x7C }; // ASCII: "1|" + + writer.writeBytes(strThumbInfo); + writer.writeBytes(thumbNameLengthBytes); + writer.writeBytes(utf8ThumbName); + writer.writeBytes(fileLengthBytes); + writer.writeBytes(thumbData); + + Byte[] strEnd = { 0x7C, 0x45, 0x4E, 0x44 }; // ASCII: "|END" + writer.writeBytes(strEnd); + + } + } + catch + { + writer.write("0|Error"); + } + } + else + { + getConnection().WriteLine("[ERROR]: Expected format: " + getCommandToHandle() + ":ChannelName|IsRadio"); + } + } + + public override string getCommandToHandle() + { + return "GetChannelThumb"; + } + } +} diff --git a/TVServerXBMC/Commands/GetDriveSpace.cs b/TVServerKodi/Commands/GetDriveSpace.cs similarity index 85% rename from TVServerXBMC/Commands/GetDriveSpace.cs rename to TVServerKodi/Commands/GetDriveSpace.cs index 3c9043a..10323eb 100644 --- a/TVServerXBMC/Commands/GetDriveSpace.cs +++ b/TVServerKodi/Commands/GetDriveSpace.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetDriveSpace : CommandHandler { @@ -12,7 +12,7 @@ public GetDriveSpace(ConnectionHandler connection) : base(connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { string result = TVServerConnection.GetRecordingDriveSpace(); diff --git a/TVServerXBMC/Commands/GetEPG.cs b/TVServerKodi/Commands/GetEPG.cs similarity index 95% rename from TVServerXBMC/Commands/GetEPG.cs rename to TVServerKodi/Commands/GetEPG.cs index d622372..3ca71a9 100644 --- a/TVServerXBMC/Commands/GetEPG.cs +++ b/TVServerKodi/Commands/GetEPG.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetEPG : CommandHandler { @@ -13,7 +13,7 @@ public GetEPG(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // we want to get the EPG info for that channel @@ -55,7 +55,7 @@ public override void handleCommand(string command, string[] arguments, ref TvCon + e.IdProgram.ToString() + "|" + e.IdChannel.ToString() + "|" + e.SeriesNum + "|" - + e.EpisodeNumber + "|" + + e.EpisodeNum + "|" + e.EpisodeName + "|" + e.EpisodePart + "|" + e.OriginalAirDate.ToString("u") + "|" diff --git a/TVServerXBMC/Commands/GetRecordingCount.cs b/TVServerKodi/Commands/GetRecordingCount.cs similarity index 88% rename from TVServerXBMC/Commands/GetRecordingCount.cs rename to TVServerKodi/Commands/GetRecordingCount.cs index 2d84aa0..f3e65ea 100644 --- a/TVServerXBMC/Commands/GetRecordingCount.cs +++ b/TVServerKodi/Commands/GetRecordingCount.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetRecordingCount : CommandHandler { @@ -12,7 +12,7 @@ public GetRecordingCount(ConnectionHandler connection) : base(connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // we want to list all channels in group arg[0] // String group = arguments[0]; diff --git a/TVServerXBMC/Commands/GetRecordingInfo.cs b/TVServerKodi/Commands/GetRecordingInfo.cs similarity index 93% rename from TVServerXBMC/Commands/GetRecordingInfo.cs rename to TVServerKodi/Commands/GetRecordingInfo.cs index a2ef58e..5913857 100644 --- a/TVServerXBMC/Commands/GetRecordingInfo.cs +++ b/TVServerKodi/Commands/GetRecordingInfo.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetRecordingInfo : CommandHandler { @@ -13,7 +13,7 @@ public GetRecordingInfo(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // Fetch the info for a particular recording String result; diff --git a/TVServerKodi/Commands/GetRecordingStopTime.cs b/TVServerKodi/Commands/GetRecordingStopTime.cs new file mode 100644 index 0000000..515d38e --- /dev/null +++ b/TVServerKodi/Commands/GetRecordingStopTime.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TVServerKodi; + +namespace TVServerKodi.Commands +{ + class GetRecordingStopTime : CommandHandler + { + public GetRecordingStopTime(ConnectionHandler connection) + : base(connection) + { + + } + + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) + { + if ((arguments != null) && (arguments.Length == 1)) + { + int recindex = int.Parse(arguments[0]); + + int result = TVServerConnection.GetRecordingStopTime(recindex); + Console.WriteLine("GetRecordingStopTime result : " + result.ToString()); + writer.write(result.ToString()); + } + else + { + getConnection().WriteLine("[ERROR]: Expected format: " + getCommandToHandle() + ":RecordingIndex"); + } + } + + public override string getCommandToHandle() + { + return "GetRecordingStopTime"; + } + } +} diff --git a/TVServerXBMC/Commands/GetScheduleCount.cs b/TVServerKodi/Commands/GetScheduleCount.cs similarity index 88% rename from TVServerXBMC/Commands/GetScheduleCount.cs rename to TVServerKodi/Commands/GetScheduleCount.cs index 920dfab..ecadd0e 100644 --- a/TVServerXBMC/Commands/GetScheduleCount.cs +++ b/TVServerKodi/Commands/GetScheduleCount.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetScheduleCount : CommandHandler { @@ -12,7 +12,7 @@ public GetScheduleCount(ConnectionHandler connection) : base(connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // we want to list all channels in group arg[0] // String group = arguments[0]; diff --git a/TVServerXBMC/Commands/GetScheduleInfo.cs b/TVServerKodi/Commands/GetScheduleInfo.cs similarity index 92% rename from TVServerXBMC/Commands/GetScheduleInfo.cs rename to TVServerKodi/Commands/GetScheduleInfo.cs index 13dca33..68eac94 100644 --- a/TVServerXBMC/Commands/GetScheduleInfo.cs +++ b/TVServerKodi/Commands/GetScheduleInfo.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetScheduleInfo : CommandHandler { @@ -13,7 +13,7 @@ public GetScheduleInfo(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // we want to list all recordings String result; diff --git a/TVServerXBMC/Commands/GetSignalQuality.cs b/TVServerKodi/Commands/GetSignalQuality.cs similarity index 78% rename from TVServerXBMC/Commands/GetSignalQuality.cs rename to TVServerKodi/Commands/GetSignalQuality.cs index 5bf6b07..cb4c1a2 100644 --- a/TVServerXBMC/Commands/GetSignalQuality.cs +++ b/TVServerKodi/Commands/GetSignalQuality.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetSignalQuality : CommandHandler { @@ -13,7 +13,7 @@ public GetSignalQuality(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { int cardID = -1; List results = new List(); @@ -30,10 +30,10 @@ public override void handleCommand(string command, string[] arguments, ref TvCon } TVServerController server = TVServerConnection.GetServerInterface(); - int level = server.GetSignalLevel(cardID); - int quality = server.GetSignalQuality(cardID); + ReceptionDetails details = server.GetReceptionDetails(cardID); - writer.write(level.ToString() + "|" + quality.ToString()); + server.HeartBeat(me); + writer.write(details.signalLevel.ToString() + "|" + details.signalQuality.ToString()); } catch { diff --git a/TVServerXBMC/Commands/GetTime.cs b/TVServerKodi/Commands/GetTime.cs similarity index 90% rename from TVServerXBMC/Commands/GetTime.cs rename to TVServerKodi/Commands/GetTime.cs index 24c7128..704b874 100644 --- a/TVServerXBMC/Commands/GetTime.cs +++ b/TVServerKodi/Commands/GetTime.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetTime : CommandHandler { @@ -11,7 +11,7 @@ public GetTime(ConnectionHandler connection) : base(connection) { } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { DateTime localtime = DateTime.Now; DateTime utctime = DateTime.UtcNow; diff --git a/TVServerKodi/Commands/GetUserName.cs b/TVServerKodi/Commands/GetUserName.cs new file mode 100644 index 0000000..fc832db --- /dev/null +++ b/TVServerKodi/Commands/GetUserName.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TVServerKodi; + +namespace TVServerKodi.Commands +{ + class GetUserName : CommandHandler + { + public GetUserName(ConnectionHandler connection) + : base(connection) + { + + } + + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) + { + bool timeshiftingUsers = false; + List results = new List(); + + if (arguments != null && arguments.Length == 1) + { + if (arguments[0] == "TimeshiftingUsers") + timeshiftingUsers = true; + } + + if (timeshiftingUsers) + { + results = TVServerConnection.getTimeshiftingUserNames(); + } + else + { + results.Add(me.Name); + } + + writer.writeList(results); + } + + public override string getCommandToHandle() + { + return "GetUserName"; + } + } +} diff --git a/TVServerXBMC/Commands/GetVersion.cs b/TVServerKodi/Commands/GetVersion.cs similarity index 86% rename from TVServerXBMC/Commands/GetVersion.cs rename to TVServerKodi/Commands/GetVersion.cs index 27ecfe3..1c37164 100644 --- a/TVServerXBMC/Commands/GetVersion.cs +++ b/TVServerKodi/Commands/GetVersion.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class GetVersion : CommandHandler { @@ -12,7 +12,7 @@ public GetVersion(ConnectionHandler connection) : base(connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { string VersionNr = "1.0.0"; diff --git a/TVServerXBMC/Commands/Help.cs b/TVServerKodi/Commands/Help.cs similarity index 92% rename from TVServerXBMC/Commands/Help.cs rename to TVServerKodi/Commands/Help.cs index 1156a19..21fc56f 100644 --- a/TVServerXBMC/Commands/Help.cs +++ b/TVServerKodi/Commands/Help.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class Help : CommandHandler { @@ -14,7 +14,7 @@ public Help(ConnectionHandler connection) /* * No arguments needed, will list all commands available */ - public override void handleCommand(string myCommand, string[] arguments, ref TvControl.User me) + public override void handleCommand(string myCommand, string[] arguments, ref TvControl.IUser me) { // get a list of all commands Dictionary allCommands = this.getConnection().getAllHandlers(); diff --git a/TVServerXBMC/Commands/IsRecording.cs b/TVServerKodi/Commands/IsRecording.cs similarity index 87% rename from TVServerXBMC/Commands/IsRecording.cs rename to TVServerKodi/Commands/IsRecording.cs index c05c3e6..ab59536 100644 --- a/TVServerXBMC/Commands/IsRecording.cs +++ b/TVServerKodi/Commands/IsRecording.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class IsRecording : CommandHandler { @@ -15,7 +15,7 @@ public IsRecording(ConnectionHandler connection) /* * No arguments needed */ - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { bool result = TVServerConnection.IsRecording(); Console.WriteLine("IsRecording result: " + result.ToString()); diff --git a/TVServerXBMC/Commands/IsTimeshifting.cs b/TVServerKodi/Commands/IsTimeshifting.cs similarity index 66% rename from TVServerXBMC/Commands/IsTimeshifting.cs rename to TVServerKodi/Commands/IsTimeshifting.cs index 821b913..ce875f2 100644 --- a/TVServerXBMC/Commands/IsTimeshifting.cs +++ b/TVServerKodi/Commands/IsTimeshifting.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class IsTimeshifting : CommandHandler { @@ -15,14 +15,15 @@ public IsTimeshifting(ConnectionHandler connection) /* * No arguments needed */ - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { - string rtspUrl = TVServerConnection.getTimeshiftUrl(ref me); + TimeShiftURLs timeShiftURLs = TVServerConnection.getTimeshiftURLs(ref me); bool result = true; - if (String.IsNullOrEmpty(rtspUrl)) + + if (timeShiftURLs == null || String.IsNullOrEmpty(timeShiftURLs.RTSPUrl) || String.IsNullOrEmpty(timeShiftURLs.TimeShiftFileName)) { + timeShiftURLs = new TimeShiftURLs { RTSPUrl = "", TimeShiftFileName = "" }; result = false; - rtspUrl = ""; } // results = isShifting;url;chanInfo as in ListChannels @@ -33,8 +34,8 @@ public override void handleCommand(string command, string[] arguments, ref TvCon c = TVServerConnection.getTimeshiftInfo(ref me); } - writer.write(writer.makeItemSmart(result.ToString(), rtspUrl, c)); - + writer.write(writer.makeItemSmart(result.ToString(), timeShiftURLs.RTSPUrl, timeShiftURLs.TimeShiftFileName, c)); + } public override string getCommandToHandle() diff --git a/TVServerXBMC/Commands/ListChannels.cs b/TVServerKodi/Commands/ListChannels.cs similarity index 92% rename from TVServerXBMC/Commands/ListChannels.cs rename to TVServerKodi/Commands/ListChannels.cs index 900b00b..fb68b61 100644 --- a/TVServerXBMC/Commands/ListChannels.cs +++ b/TVServerKodi/Commands/ListChannels.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class ListChannels : CommandHandler { @@ -13,7 +13,7 @@ public ListChannels(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { String group; List results = new List(); diff --git a/TVServerXBMC/Commands/ListGroups.cs b/TVServerKodi/Commands/ListGroups.cs similarity index 91% rename from TVServerXBMC/Commands/ListGroups.cs rename to TVServerKodi/Commands/ListGroups.cs index 9e3766f..321c1a5 100644 --- a/TVServerXBMC/Commands/ListGroups.cs +++ b/TVServerKodi/Commands/ListGroups.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class ListGroups : CommandHandler { @@ -10,7 +10,7 @@ public ListGroups(ConnectionHandler connection) : base(connection) { } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // this needs no arguments, and will just list all the tvgroups diff --git a/TVServerXBMC/Commands/ListRadioChannels.cs b/TVServerKodi/Commands/ListRadioChannels.cs similarity index 70% rename from TVServerXBMC/Commands/ListRadioChannels.cs rename to TVServerKodi/Commands/ListRadioChannels.cs index 59a90d6..f7ab3db 100644 --- a/TVServerXBMC/Commands/ListRadioChannels.cs +++ b/TVServerKodi/Commands/ListRadioChannels.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class ListRadioChannels : CommandHandler { @@ -12,22 +12,20 @@ public ListRadioChannels(ConnectionHandler connection) : base(connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { - String group; + List groups; - if (arguments != null) + if ((arguments != null) && (arguments[0].Length > 0)) { //we want to list all channels in group arg[0] - group = arguments[0]; + groups = new List(arguments); } else { - group = ""; + groups = new List(); } - - Console.WriteLine("Radio channels from group:" + group); - - List radiochannels = TVServerConnection.GetRadioChannels(group); + + List radiochannels = TVServerConnection.GetRadioChannels(groups); foreach (string channel in radiochannels) { diff --git a/TVServerXBMC/Commands/ListRadioGroups.cs b/TVServerKodi/Commands/ListRadioGroups.cs similarity index 91% rename from TVServerXBMC/Commands/ListRadioGroups.cs rename to TVServerKodi/Commands/ListRadioGroups.cs index 42133f6..82440a9 100644 --- a/TVServerXBMC/Commands/ListRadioGroups.cs +++ b/TVServerKodi/Commands/ListRadioGroups.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class ListRadioGroups : CommandHandler { @@ -10,7 +10,7 @@ public ListRadioGroups(ConnectionHandler connection) : base(connection) { } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // this needs no arguments, and will just list all the tvgroups diff --git a/TVServerXBMC/Commands/ListRecordedTV.cs b/TVServerKodi/Commands/ListRecordedTV.cs similarity index 94% rename from TVServerXBMC/Commands/ListRecordedTV.cs rename to TVServerKodi/Commands/ListRecordedTV.cs index 244c3a4..8805409 100644 --- a/TVServerXBMC/Commands/ListRecordedTV.cs +++ b/TVServerKodi/Commands/ListRecordedTV.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class ListRecordedTV : CommandHandler { @@ -12,7 +12,7 @@ public ListRecordedTV(ConnectionHandler connection) { } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // we want to list all recorded TV shows List results = new List(); diff --git a/TVServerXBMC/Commands/ListRecordings.cs b/TVServerKodi/Commands/ListRecordings.cs similarity index 90% rename from TVServerXBMC/Commands/ListRecordings.cs rename to TVServerKodi/Commands/ListRecordings.cs index 4d7e1f4..2e4f1f1 100644 --- a/TVServerXBMC/Commands/ListRecordings.cs +++ b/TVServerKodi/Commands/ListRecordings.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class ListRecordings : CommandHandler { @@ -13,7 +13,7 @@ public ListRecordings(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // we want to list all recordings List results = new List(); diff --git a/TVServerKodi/Commands/ListSchedules.cs b/TVServerKodi/Commands/ListSchedules.cs new file mode 100644 index 0000000..d4a72e1 --- /dev/null +++ b/TVServerKodi/Commands/ListSchedules.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TVServerKodi; + +namespace TVServerKodi.Commands +{ + class ListSchedules : CommandHandler + { + public ListSchedules(ConnectionHandler connection) + : base(connection) + { + + } + + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) + { + try + { + bool seriesSupport = false; + if (arguments != null && arguments.Length >= 1) + { + if (arguments[0].Length > 0) + { + seriesSupport = Boolean.Parse(arguments[0]); + } + } + + // we want to list all scheduled recordings + List results = new List(); + + results = TVServerConnection.GetSchedules(seriesSupport); + writer.writeList(results); + } catch { + getConnection().WriteLine("[ERROR]: Usage: " + getCommandToHandle() + ":[seriesSupport=False]" ); + } + } + + public override string getCommandToHandle() + { + return "ListSchedules"; + } + } +} diff --git a/TVServerXBMC/Commands/ListTVChannels.cs b/TVServerKodi/Commands/ListTVChannels.cs similarity index 68% rename from TVServerXBMC/Commands/ListTVChannels.cs rename to TVServerKodi/Commands/ListTVChannels.cs index b045758..63b6b10 100644 --- a/TVServerXBMC/Commands/ListTVChannels.cs +++ b/TVServerKodi/Commands/ListTVChannels.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class ListTVChannels : CommandHandler { @@ -13,20 +13,20 @@ public ListTVChannels(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { - String group; + List groups; - if (arguments != null) + if ((arguments != null) && (arguments[0].Length>0)) { //we want to list all channels in group arg[0] - group = arguments[0]; - } else { - group = ""; + groups = new List(arguments); + } + else + { + groups = new List(); } - - Console.WriteLine("TV channels from group:" + group); - List tvchannels = TVServerConnection.GetTVChannels(group); + List tvchannels = TVServerConnection.GetTVChannels(groups); foreach (string channel in tvchannels) { diff --git a/TVServerKodi/Commands/SetRecordingStopTime.cs b/TVServerKodi/Commands/SetRecordingStopTime.cs new file mode 100644 index 0000000..f352ce0 --- /dev/null +++ b/TVServerKodi/Commands/SetRecordingStopTime.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TVServerKodi; + +namespace TVServerKodi.Commands +{ + class SetRecordingStopTime : CommandHandler + { + public SetRecordingStopTime(ConnectionHandler connection) + : base(connection) + { + + } + + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) + { + if ((arguments != null) && (arguments.Length == 2)) + { + int recindex = int.Parse(arguments[0]); + int stopTime = int.Parse(arguments[1]); + + bool result = TVServerConnection.SetRecordingStopTime(recindex, stopTime); + Console.WriteLine("SetRecordingStopTime result : " + result.ToString()); + writer.write(result.ToString()); + } + else + { + getConnection().WriteLine("[ERROR]: Expected format: " + getCommandToHandle() + ":RecordingIndex|stopTime"); + } + } + + public override string getCommandToHandle() + { + return "SetRecordingStopTime"; + } + } +} diff --git a/TVServerKodi/Commands/SetRecordingTimesWatched.cs b/TVServerKodi/Commands/SetRecordingTimesWatched.cs new file mode 100644 index 0000000..ce4a55a --- /dev/null +++ b/TVServerKodi/Commands/SetRecordingTimesWatched.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TVServerKodi; + +namespace TVServerKodi.Commands +{ + class SetRecordingTimesWatched : CommandHandler + { + public SetRecordingTimesWatched(ConnectionHandler connection) + : base(connection) + { + + } + + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) + { + // we want to list all channels in group arg[0] + if ((arguments != null) && (arguments.Length == 2)) + { + int recindex = int.Parse(arguments[0]); + int count = int.Parse(arguments[1]); + + bool result = TVServerConnection.SetRecordingTimesWatched(recindex, count); + Console.WriteLine("SetRecordingTimesWatched result : " + result.ToString()); + writer.write(result.ToString()); + } + else + { + getConnection().WriteLine("[ERROR]: Expected format: " + getCommandToHandle() + ":RecordingIndex|timesWatched"); + } + } + + public override string getCommandToHandle() + { + return "SetRecordingTimesWatched"; + } + } +} diff --git a/TVServerXBMC/Commands/SetUserName.cs b/TVServerKodi/Commands/SetUserName.cs similarity index 91% rename from TVServerXBMC/Commands/SetUserName.cs rename to TVServerKodi/Commands/SetUserName.cs index c68673a..4609c0e 100644 --- a/TVServerXBMC/Commands/SetUserName.cs +++ b/TVServerKodi/Commands/SetUserName.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class SetUserName : CommandHandler { @@ -13,7 +13,7 @@ public SetUserName(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // we want to list all channels in group arg[0] if ((arguments != null) && (arguments.Length == 1)) diff --git a/TVServerXBMC/Commands/StopRecording.cs b/TVServerKodi/Commands/StopRecording.cs similarity index 92% rename from TVServerXBMC/Commands/StopRecording.cs rename to TVServerKodi/Commands/StopRecording.cs index f58dd87..48e488e 100644 --- a/TVServerXBMC/Commands/StopRecording.cs +++ b/TVServerKodi/Commands/StopRecording.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class StopRecording : CommandHandler { @@ -14,7 +14,7 @@ public StopRecording(ConnectionHandler connection) /* * 1 optional argument: id */ - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { int schedId = -1; diff --git a/TVServerXBMC/Commands/StopTimeshift.cs b/TVServerKodi/Commands/StopTimeshift.cs similarity index 90% rename from TVServerXBMC/Commands/StopTimeshift.cs rename to TVServerKodi/Commands/StopTimeshift.cs index 5a99b59..4b613d8 100644 --- a/TVServerXBMC/Commands/StopTimeshift.cs +++ b/TVServerKodi/Commands/StopTimeshift.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class StopTimeshift : CommandHandler { @@ -14,7 +14,7 @@ public StopTimeshift(ConnectionHandler connection) /* * No arguments needed */ - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { bool result = TVServerConnection.StopTimeshift(ref me); Console.WriteLine("StopTimeshift result: " + result.ToString()); diff --git a/TVServerXBMC/Commands/Test.cs b/TVServerKodi/Commands/Test.cs similarity index 92% rename from TVServerXBMC/Commands/Test.cs rename to TVServerKodi/Commands/Test.cs index 72a78ed..e579dea 100644 --- a/TVServerXBMC/Commands/Test.cs +++ b/TVServerKodi/Commands/Test.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; using TvDatabase; using TvLibrary.Interfaces; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class Test : CommandHandler { @@ -15,7 +15,7 @@ public Test(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { //TvEngine.PowerScheduler.WaitableTimer tveps; diff --git a/TVServerXBMC/Commands/TimeshiftChannel.cs b/TVServerKodi/Commands/TimeshiftChannel.cs similarity index 82% rename from TVServerXBMC/Commands/TimeshiftChannel.cs rename to TVServerKodi/Commands/TimeshiftChannel.cs index 500f370..46b93bd 100644 --- a/TVServerXBMC/Commands/TimeshiftChannel.cs +++ b/TVServerKodi/Commands/TimeshiftChannel.cs @@ -4,7 +4,7 @@ using System.Net; using System.Text.RegularExpressions; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class TimeshiftChannel : CommandHandler { @@ -18,7 +18,7 @@ public TimeshiftChannel(ConnectionHandler connection) /* * Expect arguments: ChannelID */ - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { if (arguments == null || arguments.Length < 1) { @@ -33,6 +33,8 @@ public override void handleCommand(string command, string[] arguments, ref TvCon string originalURL = ""; string result; string timeShiftFileName = ""; + Int64 timeShiftBufPos = 0; + long timeShiftBufNr = 0; if (arguments.Length >= 2) { @@ -47,7 +49,7 @@ public override void handleCommand(string command, string[] arguments, ref TvCon TVServerConnection.StopTimeshift(ref me); } - result = TVServerConnection.playChannel(chanId, resolveToIP, ref originalURL, ref me, ref timeShiftFileName); + result = TVServerConnection.playChannel(chanId, resolveToIP, ref originalURL, ref me, ref timeShiftFileName, ref timeShiftBufPos, ref timeShiftBufNr); if ( !result.StartsWith("[ERROR]") ) { if (resolveToIP == true) @@ -59,7 +61,9 @@ public override void handleCommand(string command, string[] arguments, ref TvCon result += "|"; } result += "|" + timeShiftFileName + - "|" + me.CardId.ToString(); + "|" + me.CardId.ToString() + + "|" + timeShiftBufPos.ToString() + + "|" + timeShiftBufNr.ToString(); } writer.write(result); @@ -67,7 +71,7 @@ public override void handleCommand(string command, string[] arguments, ref TvCon else { //backward compatibility TVServerConnection.StopTimeshift(ref me); - result = TVServerConnection.playChannel(chanId, resolveToIP, ref originalURL, ref me, ref timeShiftFileName); + result = TVServerConnection.playChannel(chanId, resolveToIP, ref originalURL, ref me, ref timeShiftFileName, ref timeShiftBufPos, ref timeShiftBufNr); writer.write(result); } diff --git a/TVServerXBMC/Commands/UpdateRecording.cs b/TVServerKodi/Commands/UpdateRecording.cs similarity index 92% rename from TVServerXBMC/Commands/UpdateRecording.cs rename to TVServerKodi/Commands/UpdateRecording.cs index 091c4b8..caa95ca 100644 --- a/TVServerXBMC/Commands/UpdateRecording.cs +++ b/TVServerKodi/Commands/UpdateRecording.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class UpdateRecording : CommandHandler { @@ -13,7 +13,7 @@ public UpdateRecording(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // we want to list all channels in group arg[0] if ((arguments != null) && (arguments.Length == 2)) diff --git a/TVServerXBMC/Commands/UpdateSchedule.cs b/TVServerKodi/Commands/UpdateSchedule.cs similarity index 91% rename from TVServerXBMC/Commands/UpdateSchedule.cs rename to TVServerKodi/Commands/UpdateSchedule.cs index 687eea8..5b8b440 100644 --- a/TVServerXBMC/Commands/UpdateSchedule.cs +++ b/TVServerKodi/Commands/UpdateSchedule.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { class UpdateSchedule : CommandHandler { @@ -13,7 +13,7 @@ public UpdateSchedule(ConnectionHandler connection) } - public override void handleCommand(string command, string[] arguments, ref TvControl.User me) + public override void handleCommand(string command, string[] arguments, ref TvControl.IUser me) { // we want to list all channels in group arg[0] if ((arguments != null) && (arguments.Length >= 16)) @@ -23,6 +23,7 @@ public override void handleCommand(string command, string[] arguments, ref TvCon int scheduleType = (int)TvDatabase.ScheduleRecordingType.Once; int priority = -1; // Use MediaPortal default int keepmethod = -1; // Use MediaPortal default + int program_id = -1; DateTime keepdate; int schedindex = int.Parse(arguments[0]); @@ -62,13 +63,17 @@ public override void handleCommand(string command, string[] arguments, ref TvCon preRecordInterval = Int32.Parse(arguments[25]); postRecordInterval = Int32.Parse(arguments[26]); + if (arguments.Length >= 28) + { + program_id = int.Parse(arguments[27]); + } } else { keepdate = new DateTime(2000, 01, 01, 0, 0, 0); //MediaPortal default value 2000-01-01 00:00:00 } - bool result = TVServerConnection.UpdateSchedule(schedindex, channelid, active, title, starttime, endtime, scheduleType, priority, keepmethod, keepdate, preRecordInterval, postRecordInterval); + bool result = TVServerConnection.UpdateSchedule(schedindex, channelid, active, title, starttime, endtime, scheduleType, priority, keepmethod, keepdate, preRecordInterval, postRecordInterval, program_id); Console.WriteLine("UpdateSchedule result : " + result.ToString()); writer.write(result.ToString()); } diff --git a/TVServerKodi/Common/PlatformInfo.cs b/TVServerKodi/Common/PlatformInfo.cs new file mode 100644 index 0000000..b9b2fd2 --- /dev/null +++ b/TVServerKodi/Common/PlatformInfo.cs @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2007-2012 ARGUS TV + * http://www.argus-tv.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TVServerKodi.Common +{ + public class PlatformInfo + { + /// + /// Is this an NT platform? + /// + public static bool IsWindowsNT + { + get + { + return (PlatformID.Win32NT == Environment.OSVersion.Platform); + } + } + + /// + /// Returns true if this is Windows 2000 or higher + /// + public static bool IsWindows2KUp + { + get + { + OperatingSystem os = Environment.OSVersion; + return (PlatformID.Win32NT == os.Platform && os.Version.Major >= 5); + } + } + } +} diff --git a/TVServerKodi/Common/ShareExplorer.cs b/TVServerKodi/Common/ShareExplorer.cs new file mode 100644 index 0000000..e5bb292 --- /dev/null +++ b/TVServerKodi/Common/ShareExplorer.cs @@ -0,0 +1,598 @@ +/* + * Copyright (C) 2007-2012 ARGUS TV + * http://www.argus-tv.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Management; +using System.Net; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.RegularExpressions; + +namespace TVServerKodi.Common +{ + public class ShareExplorer + { + #region Interop + + #region Constants + + private const int NO_ERROR = 0; + private const int ERROR_ACCESS_DENIED = 5; + private const int ERROR_WRONG_LEVEL = 124; + private const int ERROR_MORE_DATA = 234; + private const int ERROR_NOT_CONNECTED = 2250; + private const int UNIVERSAL_NAME_INFO_LEVEL = 1; + private const int MAX_SI50_ENTRIES = 20; + #endregion + + #region Structures + + /// Unc name + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + private struct UNIVERSAL_NAME_INFO + { + [MarshalAs(UnmanagedType.LPTStr)] + public string lpUniversalName; + } + + /// Share information, NT, level 2 + /// + /// Requires admin rights to work. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + private struct SHARE_INFO_2 + { + [MarshalAs(UnmanagedType.LPWStr)] + public string NetName; + public ShareType ShareType; + [MarshalAs(UnmanagedType.LPWStr)] + public string Remark; + public int Permissions; + public int MaxUsers; + public int CurrentUsers; + [MarshalAs(UnmanagedType.LPWStr)] + public string Path; + [MarshalAs(UnmanagedType.LPWStr)] + public string Password; + } + + /// Share information, NT, level 1 + /// + /// Fallback when no admin rights. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + private struct SHARE_INFO_1 + { + [MarshalAs(UnmanagedType.LPWStr)] + public string NetName; + public ShareType ShareType; + [MarshalAs(UnmanagedType.LPWStr)] + public string Remark; + } + + /// Share information, Win9x + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] + private struct SHARE_INFO_50 + { + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 13)] + public string NetName; + public byte bShareType; + public ushort Flags; + [MarshalAs(UnmanagedType.LPTStr)] + public string Remark; + [MarshalAs(UnmanagedType.LPTStr)] + public string Path; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)] + public string PasswordRW; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)] + public string PasswordRO; + public ShareType ShareType + { + get { return (ShareType)((int)bShareType & 0x7F); } + } + } + + /// Share information level 1, Win9x + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] + protected struct SHARE_INFO_1_9x + { + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 13)] + public string NetName; + public byte Padding; + public ushort bShareType; + [MarshalAs(UnmanagedType.LPTStr)] + public string Remark; + public ShareType ShareType + { + get { return (ShareType)((int)bShareType & 0x7FFF); } + } + } + #endregion + + #region Functions + + /// Get a UNC name + [DllImport("mpr", CharSet = CharSet.Auto)] + private static extern int WNetGetUniversalName(string lpLocalPath, int dwInfoLevel, ref UNIVERSAL_NAME_INFO lpBuffer, ref int lpBufferSize); + + /// Get a UNC name + [DllImport("mpr", CharSet = CharSet.Auto)] + private static extern int WNetGetUniversalName(string lpLocalPath, int dwInfoLevel, IntPtr lpBuffer, ref int lpBufferSize); + + /// Enumerate shares (NT) + [DllImport("netapi32", CharSet = CharSet.Unicode)] + private static extern int NetShareEnum(string lpServerName, int dwLevel, out IntPtr lpBuffer, int dwPrefMaxLen, out int entriesRead, out int totalEntries, ref int hResume); + + /// Free the buffer (NT) + [DllImport("netapi32")] + private static extern int NetApiBufferFree(IntPtr lpBuffer); + + /// Enumerate shares (9x) + [DllImport("svrapi", CharSet = CharSet.Ansi)] + private static extern int NetShareEnum([MarshalAs(UnmanagedType.LPTStr)] string lpServerName, int dwLevel, IntPtr lpBuffer, ushort cbBuffer, out ushort entriesRead, out ushort totalEntries); + #endregion + + #endregion + + #region Public Static Methods + + public static List GetShareInfo() + { + return GetShareInfo(Environment.MachineName, GetAllShareTypes()); + } + + public static List GetShareInfo(ShareType shareType) + { + IList shareTypeList = new List(); + shareTypeList.Add(shareType); + return GetShareInfo(Environment.MachineName, shareTypeList); + } + + public static List GetShareInfo(IList shareTypes) + { + return GetShareInfo(Environment.MachineName, shareTypes); + } + + public static List GetShareInfo(string serverName) + { + return GetShareInfo(serverName, GetAllShareTypes()); + } + + public static List GetShareInfo(string serverName, ShareType shareType) + { + IList shareTypeList = new List(); + shareTypeList.Add(shareType); + return GetShareInfo(serverName, shareTypeList); + } + + public static List GetShareInfo(string serverName, IList shareTypes) + { + if (!String.IsNullOrEmpty(serverName) && !PlatformInfo.IsWindows2KUp) + { + serverName = serverName.ToUpper(); + // On NT4, 9x and Me, server has to start with "\\" + if (!serverName.StartsWith(@"\\")) + { + serverName = serverName + @"\\"; + } + } + + if (PlatformInfo.IsWindowsNT) + { + return GetShareInfoNT(serverName, shareTypes); + } + return GetShareInfo9x(serverName, shareTypes); + } + + public static bool IsValidLocalFilePath(string fileName) + { + if (String.IsNullOrEmpty(fileName) || fileName.Length <= 2) + { + return false; + } + + char drive = char.ToUpper(fileName[0]); + if ('A' > drive || drive > 'Z') + { + return false; + } + else if (Path.VolumeSeparatorChar != fileName[1]) + { + return false; + } + else if (Path.DirectorySeparatorChar != fileName[2]) + { + return false; + } + return true; + } + + public static bool IsLocalShare(string shareName) + { + if (!String.IsNullOrEmpty(shareName)) + { + string shareServerName = GetServerNameFromShareName(shareName); + if (String.Compare(shareServerName, Environment.MachineName, true) == 0) + { + DirectoryInfo dirInfo = new DirectoryInfo(shareName); + if (dirInfo.Exists && dirInfo.Root != null) + { + List localShares = GetShareInfo(ShareType.Disk); + foreach (ShareInfo shareInfo in localShares) + { + if (shareInfo.Root != null) + { + if (String.Compare(shareInfo.Root.FullName, 0, dirInfo.FullName, 0, shareInfo.Root.FullName.Length, true) == 0) + { + return true; + } + } + } + } + } + } + return false; + } + + public static string GetServerNameFromShareName(string shareName) + { + if (!String.IsNullOrEmpty(shareName) && shareName.StartsWith(@"\\")) + { + string[] parts = shareName.Substring(2).Split('\\'); + if (parts.Length > 0) + { + return parts[0]; + } + } + return String.Empty; + } + + public static string GetUncPathForLocalPath(string fileName) + { + if (String.IsNullOrEmpty(fileName)) + { + return String.Empty; + } + if (fileName.StartsWith(@"\\")) + { + return fileName; + } + + fileName = Path.GetFullPath(fileName); + if (!IsValidLocalFilePath(fileName) || !Directory.Exists(fileName)) + { + return String.Empty; + } + + int nRet = 0; + UNIVERSAL_NAME_INFO rni = new UNIVERSAL_NAME_INFO(); + int bufferSize = Marshal.SizeOf(rni); + + nRet = WNetGetUniversalName(fileName, UNIVERSAL_NAME_INFO_LEVEL, ref rni, ref bufferSize); + + if (nRet == ERROR_MORE_DATA) + { + IntPtr pBuffer = Marshal.AllocHGlobal(bufferSize); ; + try + { + nRet = WNetGetUniversalName(fileName, UNIVERSAL_NAME_INFO_LEVEL, pBuffer, ref bufferSize); + if (NO_ERROR == nRet) + { + rni = (UNIVERSAL_NAME_INFO)Marshal.PtrToStructure(pBuffer, typeof(UNIVERSAL_NAME_INFO)); + } + } + finally + { + Marshal.FreeHGlobal(pBuffer); + } + } + + switch (nRet) + { + case NO_ERROR: + return rni.lpUniversalName; + + case ERROR_NOT_CONNECTED: + //Local file-name + List shareInfoList = GetShareInfo(); + if (shareInfoList != null) + { + ShareInfo shareInfo = FindBestShareInfoMatch(shareInfoList, fileName); + if (shareInfo != null) + { + // TODO : (Steph) verify what this ugly code is doing ... + string path = shareInfo.Path; + if (!String.IsNullOrEmpty(path)) + { + int index = path.Length; + if (Path.DirectorySeparatorChar != path[path.Length - 1]) + { + index++; + } + + if (index < fileName.Length) + { + fileName = fileName.Substring(index); + } + else + { + fileName = String.Empty; + } + return Path.Combine(shareInfo.ToString(), fileName); + } + } + } + return String.Empty; + + default: + return String.Empty; + } + } + + public static ShareInfo GetShareInfoForLocalPath(string fileName) + { + if (String.IsNullOrEmpty(fileName)) + { + return null; + } + + fileName = Path.GetFullPath(fileName); + if (!IsValidLocalFilePath(fileName)) + { + return null; + } + + List shareInfoList = GetShareInfo(); + if (shareInfoList != null) + { + return FindBestShareInfoMatch(shareInfoList, fileName); + } + return null; + } + + public static string TryConvertUncToLocal(string pathToConvert) + { + if (pathToConvert.StartsWith("file:", StringComparison.InvariantCultureIgnoreCase)) + { + Uri uri = new Uri(pathToConvert); + if (uri.IsUnc) + { + pathToConvert = uri.LocalPath; + } + } + if (pathToConvert.StartsWith(@"\\")) + { + try + { + // remove the "\\" from the UNC path and split the path + string path = pathToConvert.Replace(@"\\", ""); + string[] uncParts = path.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); + if (uncParts.Length >= 2) + { + if (uncParts[0] == "localhost" + || uncParts[0].Equals(Dns.GetHostName(), StringComparison.InvariantCultureIgnoreCase) + || IsLocalMachine(uncParts[0])) + { + ManagementScope scope = new ManagementScope(@"\\" + uncParts[0] + @"\root\cimv2"); + SelectQuery query = new SelectQuery("Select * From Win32_Share Where Name = '" + uncParts[1] + "'"); + + string localPath = String.Empty; + using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query)) + using (var collection = searcher.Get()) + { + foreach (ManagementObject obj in collection) + { + localPath = obj["path"].ToString(); + break; + } + } + + // Append any additional folders to the local path name + if (uncParts.Length > 2) + { + for (int i = 2; i < uncParts.Length; i++) + { + localPath = localPath.EndsWith(@"\") ? localPath + uncParts[i] : localPath + @"\" + uncParts[i]; + } + } + pathToConvert = localPath; + } + } + } + catch { } + } + return pathToConvert; + } + + #endregion + + #region Private Static Methods + + private static IList GetAllShareTypes() + { + IList shareTypes = new List(); + shareTypes.Add(ShareType.Device); + shareTypes.Add(ShareType.Device); + shareTypes.Add(ShareType.Disk); + shareTypes.Add(ShareType.IPC); + shareTypes.Add(ShareType.Printer); + shareTypes.Add(ShareType.Special); + return shareTypes; + } + + private static List GetShareInfoNT(string serverName, IList shareTypes) + { + int level = 2; + int entriesRead, totalEntries, nRet, hResume = 0; + IntPtr pBuffer = IntPtr.Zero; + List shareInfoList = new List(); + + try + { + nRet = NetShareEnum(serverName, level, out pBuffer, -1, out entriesRead, out totalEntries, ref hResume); + + if (nRet == ERROR_ACCESS_DENIED) + { + //Need admin for level 2, drop to level 1 + level = 1; + nRet = NetShareEnum(serverName, level, out pBuffer, -1, out entriesRead, out totalEntries, ref hResume); + } + + if (nRet == NO_ERROR && entriesRead > 0) + { + Type t = (level == 2) ? typeof(SHARE_INFO_2) : typeof(SHARE_INFO_1); + int offset = Marshal.SizeOf(t); + + for (int i = 0, lpItem = pBuffer.ToInt32(); i < entriesRead; i++, lpItem += offset) + { + IntPtr pItem = new IntPtr(lpItem); + if (level == 1) + { + SHARE_INFO_1 shareInfo = (SHARE_INFO_1)Marshal.PtrToStructure(pItem, t); + if (shareTypes.Contains(shareInfo.ShareType)) + { + shareInfoList.Add(new ShareInfo(serverName, shareInfo.NetName, string.Empty, shareInfo.ShareType, shareInfo.Remark)); + } + } + else + { + SHARE_INFO_2 shareInfo = (SHARE_INFO_2)Marshal.PtrToStructure(pItem, t); + if (shareTypes.Contains(shareInfo.ShareType)) + { + shareInfoList.Add(new ShareInfo(serverName, shareInfo.NetName, shareInfo.Path, shareInfo.ShareType, shareInfo.Remark)); + } + } + } + } + } + finally + { + // Clean up buffer allocated by system + if (IntPtr.Zero != pBuffer) + { + NetApiBufferFree(pBuffer); + } + } + return shareInfoList; + } + + private static List GetShareInfo9x(string serverName, IList shareTypes) + { + int level = 50; + int nRet = 0; + ushort entriesRead, totalEntries; + List shareInfoList = new List(); + + Type t = typeof(SHARE_INFO_50); + int size = Marshal.SizeOf(t); + ushort cbBuffer = (ushort)(MAX_SI50_ENTRIES * size); + //On Win9x, must allocate buffer before calling API + IntPtr pBuffer = Marshal.AllocHGlobal(cbBuffer); + + try + { + nRet = NetShareEnum(serverName, level, pBuffer, cbBuffer, out entriesRead, out totalEntries); + + if (nRet == ERROR_WRONG_LEVEL) + { + level = 1; + t = typeof(SHARE_INFO_1_9x); + size = Marshal.SizeOf(t); + nRet = NetShareEnum(serverName, level, pBuffer, cbBuffer, out entriesRead, out totalEntries); + } + + if (nRet == NO_ERROR || nRet == ERROR_MORE_DATA) + { + for (int i = 0, lpItem = pBuffer.ToInt32(); i < entriesRead; i++, lpItem += size) + { + IntPtr pItem = new IntPtr(lpItem); + + if (level == 1) + { + SHARE_INFO_1_9x shareInfo = (SHARE_INFO_1_9x)Marshal.PtrToStructure(pItem, t); + if (shareTypes.Contains(shareInfo.ShareType)) + { + shareInfoList.Add(new ShareInfo(serverName, shareInfo.NetName, string.Empty, shareInfo.ShareType, shareInfo.Remark)); + } + } + else + { + SHARE_INFO_50 shareInfo = (SHARE_INFO_50)Marshal.PtrToStructure(pItem, t); + if (shareTypes.Contains(shareInfo.ShareType)) + { + shareInfoList.Add(new ShareInfo(serverName, shareInfo.NetName, shareInfo.Path, shareInfo.ShareType, shareInfo.Remark)); + } + } + } + } + } + finally + { + //Clean up buffer + Marshal.FreeHGlobal(pBuffer); + } + return shareInfoList; + } + + private static ShareInfo FindBestShareInfoMatch(List shareInfoList, string fileName) + { + ShareInfo matched = null; + foreach (ShareInfo shareInfo in shareInfoList) + { + if (shareInfo.IsFileSystem + && shareInfo.ShareType != ShareType.Special + && shareInfo.MatchesPath(fileName)) + { + //Store first match + if (matched == null) + { + matched = shareInfo; + } + // better match ? if so keep it + else if (matched.Path.Length < shareInfo.Path.Length) + { + if (ShareType.Disk == shareInfo.ShareType || ShareType.Disk != matched.ShareType) + { + matched = shareInfo; + } + } + } + } + return matched; + } + + private static bool IsLocalMachine(string host) + { + try + { + IPAddress[] hostAddressess = Dns.GetHostAddresses(host); + IPAddress[] localAddresses = Dns.GetHostAddresses(Dns.GetHostName()); + return localAddresses.Any(la => hostAddressess.Any(ha => ha.ToString() == la.ToString())); + } + catch + { + return false; + } + } + + #endregion + } +} diff --git a/TVServerKodi/Common/ShareInfo.cs b/TVServerKodi/Common/ShareInfo.cs new file mode 100644 index 0000000..c953b93 --- /dev/null +++ b/TVServerKodi/Common/ShareInfo.cs @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2007-2012 ARGUS TV + * http://www.argus-tv.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace TVServerKodi.Common +{ + #region Share Type + + [Flags] + public enum ShareType + { + Disk = 0, + Printer = 1, + Device = 2, + IPC = 3, + Special = -2147483648, // 0x80000000, + } + #endregion + + public class ShareInfo + { + #region Private Members + + private string _serverName; + private string _netName; + private string _path; + private string _remark; + private ShareType _shareType; + #endregion + + public ShareInfo(string serverName, string netName, string path, ShareType shareType, string remark) + { + if (shareType == ShareType.Special && netName == "IPC$") + { + shareType |= ShareType.IPC; + } + _serverName = serverName; + _netName = netName; + _path = path; + _shareType = shareType; + _remark = remark; + } + + #region Properties + + public string ServerName + { + get { return _serverName; } + } + + public string NetName + { + get { return _netName; } + } + + public string Path + { + get { return _path; } + } + + public ShareType ShareType + { + get { return _shareType; } + } + + public string Remark + { + get { return _remark; } + } + + /// + /// Returns true if this is a file system share + /// + public bool IsFileSystem + { + get + { + // Shared device + if ((_shareType & ShareType.Device) != 0) + { + return false; + } + // IPC share + if ((_shareType & ShareType.IPC) != 0) + { + return false; + } + // Shared printer + if ((_shareType & ShareType.Printer) != 0) + { + return false; + } + // Standard disk share + if ((_shareType & ShareType.Special) == 0) + { + return true; + } + // Special disk share (e.g. C$) + if (ShareType.Special == _shareType && null != _netName && 0 != _netName.Length) + { + return true; + } + else + { + return false; + } + } + } + + /// + /// Get the root of a file system (disk) based share + /// + public DirectoryInfo Root + { + get + { + if (IsFileSystem) + { + if (String.IsNullOrEmpty(_serverName)) + { + if (String.IsNullOrEmpty(_path)) + { + return new DirectoryInfo(ToString()); + } + else + { + return new DirectoryInfo(_path); + } + } + else + { + return new DirectoryInfo(ToString()); + } + } + return null; + } + } + #endregion + + #region Overrides + + /// + /// Returns the path to this share + /// + /// + public override string ToString() + { + if (String.IsNullOrEmpty(_serverName)) + { + return string.Format(@"\\{0}\{1}", Environment.MachineName, _netName); + } + return string.Format(@"\\{0}\{1}", _serverName, _netName); + } + #endregion + + #region Public Methods + + /// + /// Returns true if this share matches the local path + /// + /// + /// + public bool MatchesPath(string path) + { + if (String.IsNullOrEmpty(path) || !IsFileSystem) + { + return false; + } + if (path.StartsWith(_path, StringComparison.CurrentCultureIgnoreCase)) + { + return (path.Length == _path.Length) || (path[_path.Length] == System.IO.Path.DirectorySeparatorChar); + } + return false; + } + #endregion + } +} + diff --git a/TVServerXBMC/ConnectionHandler.cs b/TVServerKodi/ConnectionHandler.cs similarity index 50% rename from TVServerXBMC/ConnectionHandler.cs rename to TVServerKodi/ConnectionHandler.cs index 3446959..ce55b75 100644 --- a/TVServerXBMC/ConnectionHandler.cs +++ b/TVServerKodi/ConnectionHandler.cs @@ -7,11 +7,11 @@ using System.Net; using System.IO; using System.Text.RegularExpressions; -using TVServerXBMC.Commands; +using TVServerKodi.Commands; using TvLibrary.Log; -using MPTvClient; +using TVServerKodi; -namespace TVServerXBMC +namespace TVServerKodi { enum ClientType { @@ -32,7 +32,7 @@ class ConnectionHandler private Mutex cmdMutex; private int clientnr = 0; private string username; - private TvControl.User me; + private TvControl.IUser me; private ClientType clientType = ClientType.unknown; //private Dictionary userlist; @@ -66,7 +66,7 @@ private void addHandlers() handlers.Add(new Help(this)); handlers.Add(new IsTimeshifting(this)); - // Added for XBMC PVR client addon: + // Added for XBMC/Kodi PVR client addon: handlers.Add(new GetVersion(this)); handlers.Add(new GetBackendName(this)); handlers.Add(new GetDriveSpace(this)); @@ -78,6 +78,7 @@ private void addHandlers() handlers.Add(new ListTVChannels(this)); handlers.Add(new ListRadioChannels(this)); handlers.Add(new ListRadioGroups(this)); + handlers.Add(new GetChannelThumb(this)); // Recording commands: handlers.Add(new GetRecordingCount(this)); handlers.Add(new ListRecordings(this)); @@ -85,6 +86,9 @@ private void addHandlers() handlers.Add(new IsRecording(this)); handlers.Add(new StopRecording(this)); handlers.Add(new GetRecordingInfo(this)); + handlers.Add(new SetRecordingTimesWatched(this)); + handlers.Add(new GetRecordingStopTime(this)); + handlers.Add(new SetRecordingStopTime(this)); // Timer/Schedule commands: handlers.Add(new GetScheduleCount(this)); handlers.Add(new ListSchedules(this)); @@ -116,73 +120,97 @@ public DataWriter getWriter() public void HandleConnection() { - NetworkStream cStream = this.client.GetStream(); - StreamReader reader = new StreamReader(cStream); - writer = new DataWriter(cStream); - - // first we get what version of the protocol - // we expect "TVServerXBMC:0-2" - String versionInfo = reader.ReadLine(); - if (versionInfo == null) return; - - // version 2 is not backards compatible - versionInfo = Uri.UnescapeDataString(versionInfo); - if (versionInfo.ToLower().Contains("telnet")) + try { - // human connection - writer.setArgumentSeparator("|"); - writer.setListSeparator(Environment.NewLine); - writer.setHumanEncoders(); + NetworkStream cStream = this.client.GetStream(); + StreamReader reader = new StreamReader(cStream); + writer = new DataWriter(cStream); + + // first we get what version of the protocol + // we expect "TVServerXBMC:0-2" + String versionInfo = reader.ReadLine(); + if (versionInfo == null) return; + + // version 2 is not backards compatible + versionInfo = Uri.UnescapeDataString(versionInfo); + if (versionInfo.ToLower().Contains("telnet")) + { + // human connection + writer.setArgumentSeparator("|"); + writer.setListSeparator(Environment.NewLine); + writer.setHumanEncoders(); - //reader side: - cmd_sep = ":"; - arg_sep = "|"; + //reader side: + cmd_sep = ":"; + arg_sep = "|"; - WriteLine("Protocol Accepted; TVServerXBMC version: " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); - Console.WriteLine("Correct protocol, telnet connection accepted!"); - Log.Debug("TVServerXBMC: telnet connection accepted!"); + WriteLine("Protocol Accepted; TVServerKodi version: " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); + Console.WriteLine("Correct protocol, telnet connection accepted!"); + Log.Debug("TVServerKodi: telnet connection accepted!"); - username = "XBMCtelnet"; - clientType = ClientType.telnet; - } - else if (Regex.IsMatch(versionInfo,"^TVServerXBMC:0-[0-3]$",RegexOptions.IgnoreCase)) - { - WriteLine("Protocol-Accept;0-3"); - Console.WriteLine("Correct protocol, connection accepted!"); - Log.Debug("TVServerXBMC: connection accepted!"); - username = "XBMCpython"; - clientType = ClientType.python; - } - else if (Regex.IsMatch(versionInfo, "^PVRclientXBMC:0-[1]$", RegexOptions.IgnoreCase)) - { - writer.setArgumentSeparator("|"); - //reader side: - cmd_sep = ":"; - arg_sep = "|"; + username = "Koditelnet"; + clientType = ClientType.telnet; + } + else if (Regex.IsMatch(versionInfo, "^TVServerXBMC:0-[0-3]$", RegexOptions.IgnoreCase)) + { + WriteLine("Protocol-Accept;0-3"); + Console.WriteLine("Correct protocol, connection accepted!"); + Log.Debug("TVServerKodi: connection accepted!"); + username = "XBMCpython"; + clientType = ClientType.python; + } + else if (Regex.IsMatch(versionInfo, "^PVRclientXBMC:0-[1]$", RegexOptions.IgnoreCase)) + { + writer.setArgumentSeparator("|"); + //reader side: + cmd_sep = ":"; + arg_sep = "|"; - WriteLine("Protocol-Accept:0|" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); - Console.WriteLine("Correct protocol, connection accepted!"); - Log.Debug("TVServerXBMC: connection accepted from XBMC PVR addon"); + WriteLine("Protocol-Accept:0|" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); + Console.WriteLine("Correct protocol, connection accepted!"); + Log.Debug("TVServerKodi: connection accepted from XBMC PVR addon"); - username = "XBMCpvrclient" + clientnr; - clientType = ClientType.pvrclient; - } - else - { - WriteLine("Unexpected Protocol"); - client.Close(); - Console.WriteLine("Unexpected protocol:" + versionInfo); - Log.Debug("TVServerXBMC: Unexpected protocol:" + versionInfo); + username = "XBMCpvrclient" + clientnr; + clientType = ClientType.pvrclient; + } + else if (Regex.IsMatch(versionInfo, "^PVRclientKodi:0-[1]$", RegexOptions.IgnoreCase)) + { + writer.setArgumentSeparator("|"); + //reader side: + cmd_sep = ":"; + arg_sep = "|"; - clientType = ClientType.unknown; - return; - } + WriteLine("Protocol-Accept:0|" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); + Console.WriteLine("Correct protocol, connection accepted!"); + Log.Debug("TVServerKodi: connection accepted from Kodi PVR addon"); - me = TVServerConnection.RequestUser(username); + username = "Kodipvrclient" + clientnr; + clientType = ClientType.pvrclient; + } + else + { + WriteLine("Unexpected Protocol"); + client.Close(); + Console.WriteLine("Unexpected protocol:" + versionInfo); + Log.Debug("TVServerKodi: Unexpected protocol:" + versionInfo); + + clientType = ClientType.unknown; + return; + } - ProcessConnection(reader); - reader.Dispose(); - cStream.Dispose(); + me = TVServerConnection.RequestUser(username); + + ProcessConnection(reader); + reader.Dispose(); + cStream.Dispose(); + } + catch (Exception e) + { + WriteLine("[ERROR]: HandleConnection failed"); + Log.Debug("TVServerKodi: HandleConnection failed"); + Log.Debug("TVServerKodi: Exception => " + e.Message); + Log.Debug("TVServerKodi: Stack trace: " + e.StackTrace); + } } public void WriteLine(String line) @@ -198,40 +226,53 @@ public void Disconnect() private void handleCommand(String command, String[] arguments) { + try + { String handleCommand = command.ToLower(); if (allHandlers.ContainsKey(handleCommand)) { + try + { cmdMutex.WaitOne(); - try - { - allHandlers[handleCommand].handleCommand(command, arguments, ref me); - } - catch { - WriteLine("[ERROR]: Command failed: " + command); - Log.Debug("TVServerXBMC: Command failed: " + command); - } + allHandlers[handleCommand].handleCommand(command, arguments, ref me); + } + catch (Exception e) + { + WriteLine("[ERROR]: Command failed: " + command); + Log.Debug("TVServerKodi: Command failed: " + command); + Log.Debug("TVServerKodi: Exception: " + command + " => " + e.Message); + Log.Debug("TVServerKodi: Stack trace: " + e.StackTrace); + } + finally + { cmdMutex.ReleaseMutex(); + } } else if (handleCommand == "quit" || handleCommand == "exit") { - Disconnect(); + Disconnect(); } else if (handleCommand == "?") { - foreach (KeyValuePair kvp in allHandlers) - { - WriteLine(kvp.Key); - Console.WriteLine("Command: " + kvp.Key); - } + foreach (KeyValuePair kvp in allHandlers) + { + WriteLine(kvp.Key); + Console.WriteLine("Command: " + kvp.Key); + } } else { - WriteLine("[ERROR]: UnknownCommand:" + command); - Console.WriteLine("[ERROR]: Unknown command : " + command); - Log.Debug("TVServerXBMC: Unknown command: " + command); + WriteLine("[ERROR]: UnknownCommand:" + command); + Console.WriteLine("[ERROR]: Unknown command : " + command); + Log.Debug("TVServerKodi: Unknown command: " + command); } - - + } + catch(Exception e) + { + WriteLine("[ERROR]: Exception:" + command + " => " + e.Message); + Log.Debug("TVServerKodi: Exception: " + command + " => " + e.Message); + Log.Debug("TVServerKodi: Stack trace: " + e.StackTrace); + } } private void ProcessConnection(StreamReader reader) @@ -261,7 +302,7 @@ private void ProcessConnection(StreamReader reader) } Console.WriteLine("Handling command; " + command); - Log.Debug("TVServerXBMC: Handling command: " + command); + Log.Debug("TVServerKodi: Handling command: " + command); handleCommand(command, arguments); } else @@ -270,25 +311,40 @@ private void ProcessConnection(StreamReader reader) } } } + catch (System.Net.Sockets.SocketException) + { + Console.WriteLine("Could not read data."); + Log.Debug("TVServerKodi: Could not read data."); + try + { + client.Close(); + reader.Close(); + } + catch (Exception) + { } + } catch (Exception e) { Console.WriteLine("Exception while processing connection : " + e.ToString()); - Log.Debug("TVServerXBMC: Exception while processing connection: " + e.ToString()); + Log.Debug("TVServerKodi: Exception while processing connection: " + e.ToString()); } + Console.WriteLine("Connection closed"); - Log.Debug("TVServerXBMC: Connection closed"); + Log.Debug("TVServerKodi: Connection closed"); if (clientType != ClientType.python) { + try + { cmdMutex.WaitOne(); - try - { - allHandlers["stoptimeshift"].handleCommand("StopTimeshift", null, ref me); - } - catch - { - } + allHandlers["stoptimeshift"].handleCommand("StopTimeshift", null, ref me); + } + catch + { } + finally + { cmdMutex.ReleaseMutex(); + } } } } diff --git a/TVServerKodi/CreateShareForm.Designer.cs b/TVServerKodi/CreateShareForm.Designer.cs new file mode 100644 index 0000000..04a909d --- /dev/null +++ b/TVServerKodi/CreateShareForm.Designer.cs @@ -0,0 +1,128 @@ +namespace ForTheRecord.RecorderTuners.MediaPortalTvServer +{ + partial class CreateShareForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this._pathLabel = new System.Windows.Forms.Label(); + this._localPathLabel = new System.Windows.Forms.Label(); + this._shareLabel = new System.Windows.Forms.Label(); + this._shareNameTextBox = new System.Windows.Forms.TextBox(); + this._okButton = new System.Windows.Forms.Button(); + this._cancelButton = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // _pathLabel + // + this._pathLabel.AutoSize = true; + this._pathLabel.Location = new System.Drawing.Point(12, 15); + this._pathLabel.Name = "_pathLabel"; + this._pathLabel.Size = new System.Drawing.Size(60, 13); + this._pathLabel.TabIndex = 0; + this._pathLabel.Text = "Local path:"; + // + // _localPathLabel + // + this._localPathLabel.AutoEllipsis = true; + this._localPathLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this._localPathLabel.Location = new System.Drawing.Point(85, 15); + this._localPathLabel.Name = "_localPathLabel"; + this._localPathLabel.Size = new System.Drawing.Size(297, 20); + this._localPathLabel.TabIndex = 1; + // + // _shareLabel + // + this._shareLabel.AutoSize = true; + this._shareLabel.Location = new System.Drawing.Point(12, 41); + this._shareLabel.Name = "_shareLabel"; + this._shareLabel.Size = new System.Drawing.Size(67, 13); + this._shareLabel.TabIndex = 2; + this._shareLabel.Text = "Share name:"; + // + // _shareNameTextBox + // + this._shareNameTextBox.Location = new System.Drawing.Point(85, 38); + this._shareNameTextBox.Name = "_shareNameTextBox"; + this._shareNameTextBox.Size = new System.Drawing.Size(297, 20); + this._shareNameTextBox.TabIndex = 3; + // + // _okButton + // + this._okButton.Location = new System.Drawing.Point(226, 72); + this._okButton.Name = "_okButton"; + this._okButton.Size = new System.Drawing.Size(75, 23); + this._okButton.TabIndex = 4; + this._okButton.Text = "OK"; + this._okButton.UseVisualStyleBackColor = true; + this._okButton.Click += new System.EventHandler(this._okButton_Click); + // + // _cancelButton + // + this._cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this._cancelButton.Location = new System.Drawing.Point(307, 72); + this._cancelButton.Name = "_cancelButton"; + this._cancelButton.Size = new System.Drawing.Size(75, 23); + this._cancelButton.TabIndex = 5; + this._cancelButton.Text = "Cancel"; + this._cancelButton.UseVisualStyleBackColor = true; + // + // CreateShareForm + // + this.AcceptButton = this._okButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this._cancelButton; + this.ClientSize = new System.Drawing.Size(394, 104); + this.Controls.Add(this._cancelButton); + this.Controls.Add(this._okButton); + this.Controls.Add(this._shareNameTextBox); + this.Controls.Add(this._shareLabel); + this.Controls.Add(this._localPathLabel); + this.Controls.Add(this._pathLabel); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "CreateShareForm"; + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Create UNC Share"; + this.Load += new System.EventHandler(this.CreateShareForm_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label _pathLabel; + private System.Windows.Forms.Label _localPathLabel; + private System.Windows.Forms.Label _shareLabel; + private System.Windows.Forms.TextBox _shareNameTextBox; + private System.Windows.Forms.Button _okButton; + private System.Windows.Forms.Button _cancelButton; + } +} \ No newline at end of file diff --git a/TVServerKodi/CreateShareForm.cs b/TVServerKodi/CreateShareForm.cs new file mode 100644 index 0000000..f984d20 --- /dev/null +++ b/TVServerKodi/CreateShareForm.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace ForTheRecord.RecorderTuners.MediaPortalTvServer +{ + public partial class CreateShareForm : Form + { + public CreateShareForm() + { + InitializeComponent(); + } + + private string _localPath; + + public string LocalPath + { + get { return _localPath; } + set { _localPath = value; } + } + + private void CreateShareForm_Load(object sender, EventArgs e) + { + _localPathLabel.Text = _localPath; + } + + private void _okButton_Click(object sender, EventArgs e) + { + if (_shareNameTextBox.Text.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0) + { + MessageBox.Show(this, "Invalid share name, don't use special characters.", null, MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + try + { + if (Common.Utility.CreateUncShare(_shareNameTextBox.Text.Trim(), _localPath)) + { + this.DialogResult = DialogResult.OK; + Close(); + } + else + { + MessageBox.Show(this, "Failed to create share, name not unique?", null, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + catch (Exception ex) + { + MessageBox.Show(this, ex.Message, null, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } +} diff --git a/TVServerKodi/CreateShareForm.resx b/TVServerKodi/CreateShareForm.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/TVServerKodi/CreateShareForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/TVServerKodi/Forms/CreateShareForm.Designer.cs b/TVServerKodi/Forms/CreateShareForm.Designer.cs new file mode 100644 index 0000000..e74da6e --- /dev/null +++ b/TVServerKodi/Forms/CreateShareForm.Designer.cs @@ -0,0 +1,124 @@ +namespace TVServerKodi.Forms +{ + partial class CreateShareForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.cancelButton = new System.Windows.Forms.Button(); + this.okButton = new System.Windows.Forms.Button(); + this.shareNameTextBox = new System.Windows.Forms.TextBox(); + this._shareLabel = new System.Windows.Forms.Label(); + this.localPathLabel = new System.Windows.Forms.Label(); + this._pathLabel = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // cancelButton + // + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.Location = new System.Drawing.Point(302, 65); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 11; + this.cancelButton.Text = "Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); + // + // okButton + // + this.okButton.Location = new System.Drawing.Point(221, 65); + this.okButton.Name = "okButton"; + this.okButton.Size = new System.Drawing.Size(75, 23); + this.okButton.TabIndex = 10; + this.okButton.Text = "OK"; + this.okButton.UseVisualStyleBackColor = true; + this.okButton.Click += new System.EventHandler(this.okButton_Click); + // + // shareNameTextBox + // + this.shareNameTextBox.Location = new System.Drawing.Point(80, 31); + this.shareNameTextBox.Name = "shareNameTextBox"; + this.shareNameTextBox.Size = new System.Drawing.Size(297, 20); + this.shareNameTextBox.TabIndex = 9; + // + // _shareLabel + // + this._shareLabel.AutoSize = true; + this._shareLabel.Location = new System.Drawing.Point(7, 34); + this._shareLabel.Name = "_shareLabel"; + this._shareLabel.Size = new System.Drawing.Size(67, 13); + this._shareLabel.TabIndex = 8; + this._shareLabel.Text = "Share name:"; + // + // localPathLabel + // + this.localPathLabel.AutoEllipsis = true; + this.localPathLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.localPathLabel.Location = new System.Drawing.Point(80, 8); + this.localPathLabel.Name = "localPathLabel"; + this.localPathLabel.Size = new System.Drawing.Size(297, 20); + this.localPathLabel.TabIndex = 7; + // + // _pathLabel + // + this._pathLabel.AutoSize = true; + this._pathLabel.Location = new System.Drawing.Point(7, 8); + this._pathLabel.Name = "_pathLabel"; + this._pathLabel.Size = new System.Drawing.Size(60, 13); + this._pathLabel.TabIndex = 6; + this._pathLabel.Text = "Local path:"; + // + // CreateShareForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(394, 104); + this.Controls.Add(this.cancelButton); + this.Controls.Add(this.okButton); + this.Controls.Add(this.shareNameTextBox); + this.Controls.Add(this._shareLabel); + this.Controls.Add(this.localPathLabel); + this.Controls.Add(this._pathLabel); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Name = "CreateShareForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Create UNC Share"; + this.Load += new System.EventHandler(this.CreateShareForm_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.Button okButton; + private System.Windows.Forms.TextBox shareNameTextBox; + private System.Windows.Forms.Label _shareLabel; + private System.Windows.Forms.Label localPathLabel; + private System.Windows.Forms.Label _pathLabel; + } +} \ No newline at end of file diff --git a/TVServerKodi/Forms/CreateShareForm.cs b/TVServerKodi/Forms/CreateShareForm.cs new file mode 100644 index 0000000..9c9dbb4 --- /dev/null +++ b/TVServerKodi/Forms/CreateShareForm.cs @@ -0,0 +1,83 @@ +/* + * TVServerXBMC plugin for Team MediaPortal's TV-Server + * Copyright (C) 2010-2012 Marcel Groothuis + * http://www.github.com/margro + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This CreateShareForm is based on the CreateShareForm from ARGUS TV + * http://www.argus-tv.com + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace TVServerKodi.Forms +{ + public partial class CreateShareForm : Form + { + public CreateShareForm() + { + InitializeComponent(); + } + + private string m_localPath; + + public string LocalPath + { + get { return m_localPath; } + set { m_localPath = value; } + } + + private void CreateShareForm_Load(object sender, EventArgs e) + { + localPathLabel.Text = m_localPath; + } + + private void okButton_Click(object sender, EventArgs e) + { + if (shareNameTextBox.Text.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0) + { + MessageBox.Show(this, "Invalid share name, don't use special characters.", null, MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + try + { + if (Utility.CreateUncShare(shareNameTextBox.Text.Trim(), m_localPath)) + { + this.DialogResult = DialogResult.OK; + Close(); + } + else + { + MessageBox.Show(this, "Failed to create share, name not unique?", null, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + catch (Exception ex) + { + MessageBox.Show(this, ex.Message, null, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void cancelButton_Click(object sender, EventArgs e) + { + Close(); + } + } +} diff --git a/TVServerKodi/Forms/CreateShareForm.resx b/TVServerKodi/Forms/CreateShareForm.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/TVServerKodi/Forms/CreateShareForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/TVServerKodi/Forms/SetupForm.Designer.cs b/TVServerKodi/Forms/SetupForm.Designer.cs new file mode 100644 index 0000000..9a3252d --- /dev/null +++ b/TVServerKodi/Forms/SetupForm.Designer.cs @@ -0,0 +1,394 @@ +namespace TVServerKodi.Forms +{ + partial class SetupForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.portNumericUpDown = new System.Windows.Forms.NumericUpDown(); + this._tcpPortLabel = new System.Windows.Forms.Label(); + this.uncPathsTabPage = new System.Windows.Forms.TabPage(); + this.refreshUncButton = new System.Windows.Forms.Button(); + this.uncTimeshiftGroupBox = new System.Windows.Forms.GroupBox(); + this.createTimeshiftShareButton = new System.Windows.Forms.Button(); + this.uncTimeshiftPathsDataGrid = new System.Windows.Forms.DataGridView(); + this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.uncTimeshiftPathsBindingSource = new System.Windows.Forms.BindingSource(this.components); + this.uncRecordingGroupBox = new System.Windows.Forms.GroupBox(); + this.createRecordingsShareButton = new System.Windows.Forms.Button(); + this.uncRecordingPathsDataGrid = new System.Windows.Forms.DataGridView(); + this.Card = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Path = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.uncRecordingPathsBindingSource = new System.Windows.Forms.BindingSource(this.components); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.groupBox1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.portNumericUpDown)).BeginInit(); + this.uncPathsTabPage.SuspendLayout(); + this.uncTimeshiftGroupBox.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.uncTimeshiftPathsDataGrid)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.uncTimeshiftPathsBindingSource)).BeginInit(); + this.uncRecordingGroupBox.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.uncRecordingPathsDataGrid)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.uncRecordingPathsBindingSource)).BeginInit(); + this.SuspendLayout(); + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.uncPathsTabPage); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(559, 400); + this.tabControl1.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.groupBox1); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(551, 374); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "Configuration"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // groupBox1 + // + this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox1.Controls.Add(this.portNumericUpDown); + this.groupBox1.Controls.Add(this._tcpPortLabel); + this.groupBox1.Location = new System.Drawing.Point(6, 6); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(539, 117); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "TVServer Kodi proxy"; + // + // portNumericUpDown + // + this.portNumericUpDown.Location = new System.Drawing.Point(64, 18); + this.portNumericUpDown.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.portNumericUpDown.Name = "portNumericUpDown"; + this.portNumericUpDown.Size = new System.Drawing.Size(60, 20); + this.portNumericUpDown.TabIndex = 15; + this.portNumericUpDown.Value = new decimal(new int[] { + 9556, + 0, + 0, + 0}); + // + // _tcpPortLabel + // + this._tcpPortLabel.AutoSize = true; + this._tcpPortLabel.Location = new System.Drawing.Point(6, 21); + this._tcpPortLabel.Name = "_tcpPortLabel"; + this._tcpPortLabel.Size = new System.Drawing.Size(52, 13); + this._tcpPortLabel.TabIndex = 14; + this._tcpPortLabel.Text = "TCP port:"; + // + // uncPathsTabPage + // + this.uncPathsTabPage.Controls.Add(this.refreshUncButton); + this.uncPathsTabPage.Controls.Add(this.uncTimeshiftGroupBox); + this.uncPathsTabPage.Controls.Add(this.uncRecordingGroupBox); + this.uncPathsTabPage.Location = new System.Drawing.Point(4, 22); + this.uncPathsTabPage.Name = "uncPathsTabPage"; + this.uncPathsTabPage.Padding = new System.Windows.Forms.Padding(3); + this.uncPathsTabPage.Size = new System.Drawing.Size(551, 374); + this.uncPathsTabPage.TabIndex = 1; + this.uncPathsTabPage.Text = "Shares"; + this.uncPathsTabPage.UseVisualStyleBackColor = true; + // + // refreshUncButton + // + this.refreshUncButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.refreshUncButton.Location = new System.Drawing.Point(470, 321); + this.refreshUncButton.Name = "refreshUncButton"; + this.refreshUncButton.Size = new System.Drawing.Size(75, 23); + this.refreshUncButton.TabIndex = 13; + this.refreshUncButton.Text = "Refresh"; + this.refreshUncButton.UseVisualStyleBackColor = true; + this.refreshUncButton.Click += new System.EventHandler(this.refreshUncButton_Click); + // + // uncTimeshiftGroupBox + // + this.uncTimeshiftGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.uncTimeshiftGroupBox.Controls.Add(this.createTimeshiftShareButton); + this.uncTimeshiftGroupBox.Controls.Add(this.uncTimeshiftPathsDataGrid); + this.uncTimeshiftGroupBox.Location = new System.Drawing.Point(6, 163); + this.uncTimeshiftGroupBox.Name = "uncTimeshiftGroupBox"; + this.uncTimeshiftGroupBox.Size = new System.Drawing.Size(538, 152); + this.uncTimeshiftGroupBox.TabIndex = 1; + this.uncTimeshiftGroupBox.TabStop = false; + this.uncTimeshiftGroupBox.Text = "UNC Timeshift Paths"; + // + // createTimeshiftShareButton + // + this.createTimeshiftShareButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.createTimeshiftShareButton.Location = new System.Drawing.Point(8, 123); + this.createTimeshiftShareButton.Name = "createTimeshiftShareButton"; + this.createTimeshiftShareButton.Size = new System.Drawing.Size(100, 23); + this.createTimeshiftShareButton.TabIndex = 13; + this.createTimeshiftShareButton.Text = "Create Share"; + this.createTimeshiftShareButton.UseVisualStyleBackColor = true; + this.createTimeshiftShareButton.Click += new System.EventHandler(this.createTimeshiftShareButton_Click); + // + // uncTimeshiftPathsDataGrid + // + this.uncTimeshiftPathsDataGrid.AllowUserToAddRows = false; + this.uncTimeshiftPathsDataGrid.AllowUserToDeleteRows = false; + this.uncTimeshiftPathsDataGrid.AllowUserToResizeRows = false; + this.uncTimeshiftPathsDataGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.uncTimeshiftPathsDataGrid.AutoGenerateColumns = false; + this.uncTimeshiftPathsDataGrid.BackgroundColor = System.Drawing.SystemColors.Window; + this.uncTimeshiftPathsDataGrid.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.uncTimeshiftPathsDataGrid.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None; + this.uncTimeshiftPathsDataGrid.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.uncTimeshiftPathsDataGrid.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + this.uncTimeshiftPathsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.uncTimeshiftPathsDataGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.dataGridViewTextBoxColumn1, + this.dataGridViewTextBoxColumn2}); + this.uncTimeshiftPathsDataGrid.DataSource = this.uncTimeshiftPathsBindingSource; + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.uncTimeshiftPathsDataGrid.DefaultCellStyle = dataGridViewCellStyle2; + this.uncTimeshiftPathsDataGrid.GridColor = System.Drawing.SystemColors.Control; + this.uncTimeshiftPathsDataGrid.Location = new System.Drawing.Point(7, 20); + this.uncTimeshiftPathsDataGrid.MultiSelect = false; + this.uncTimeshiftPathsDataGrid.Name = "uncTimeshiftPathsDataGrid"; + this.uncTimeshiftPathsDataGrid.ReadOnly = true; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.uncTimeshiftPathsDataGrid.RowHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.uncTimeshiftPathsDataGrid.RowHeadersVisible = false; + this.uncTimeshiftPathsDataGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.uncTimeshiftPathsDataGrid.Size = new System.Drawing.Size(525, 100); + this.uncTimeshiftPathsDataGrid.StandardTab = true; + this.uncTimeshiftPathsDataGrid.TabIndex = 0; + this.uncTimeshiftPathsDataGrid.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.uncTimeshiftPathsDataGrid_CellFormatting); + this.uncTimeshiftPathsDataGrid.SelectionChanged += new System.EventHandler(this.uncTimeshiftPathsDataGrid_SelectionChanged); + // + // dataGridViewTextBoxColumn1 + // + this.dataGridViewTextBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn1.DataPropertyName = "CardName"; + this.dataGridViewTextBoxColumn1.FillWeight = 30F; + this.dataGridViewTextBoxColumn1.HeaderText = "Card"; + this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; + this.dataGridViewTextBoxColumn1.ReadOnly = true; + // + // dataGridViewTextBoxColumn2 + // + this.dataGridViewTextBoxColumn2.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn2.DataPropertyName = "Message"; + this.dataGridViewTextBoxColumn2.FillWeight = 70F; + this.dataGridViewTextBoxColumn2.HeaderText = "Path"; + this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; + this.dataGridViewTextBoxColumn2.ReadOnly = true; + // + // uncRecordingGroupBox + // + this.uncRecordingGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.uncRecordingGroupBox.Controls.Add(this.createRecordingsShareButton); + this.uncRecordingGroupBox.Controls.Add(this.uncRecordingPathsDataGrid); + this.uncRecordingGroupBox.Location = new System.Drawing.Point(7, 7); + this.uncRecordingGroupBox.Name = "uncRecordingGroupBox"; + this.uncRecordingGroupBox.Size = new System.Drawing.Size(538, 152); + this.uncRecordingGroupBox.TabIndex = 0; + this.uncRecordingGroupBox.TabStop = false; + this.uncRecordingGroupBox.Text = "UNC Recording Paths"; + // + // createRecordingsShareButton + // + this.createRecordingsShareButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.createRecordingsShareButton.Location = new System.Drawing.Point(7, 123); + this.createRecordingsShareButton.Name = "createRecordingsShareButton"; + this.createRecordingsShareButton.Size = new System.Drawing.Size(100, 23); + this.createRecordingsShareButton.TabIndex = 12; + this.createRecordingsShareButton.Text = "Create Share"; + this.createRecordingsShareButton.UseVisualStyleBackColor = true; + this.createRecordingsShareButton.Click += new System.EventHandler(this.createRecordingsShareButton_Click); + // + // uncRecordingPathsDataGrid + // + this.uncRecordingPathsDataGrid.AllowUserToAddRows = false; + this.uncRecordingPathsDataGrid.AllowUserToDeleteRows = false; + this.uncRecordingPathsDataGrid.AllowUserToResizeRows = false; + this.uncRecordingPathsDataGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.uncRecordingPathsDataGrid.AutoGenerateColumns = false; + this.uncRecordingPathsDataGrid.BackgroundColor = System.Drawing.SystemColors.Window; + this.uncRecordingPathsDataGrid.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.uncRecordingPathsDataGrid.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None; + this.uncRecordingPathsDataGrid.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None; + dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.uncRecordingPathsDataGrid.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle4; + this.uncRecordingPathsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.uncRecordingPathsDataGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.Card, + this.Path}); + this.uncRecordingPathsDataGrid.DataSource = this.uncRecordingPathsBindingSource; + dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.uncRecordingPathsDataGrid.DefaultCellStyle = dataGridViewCellStyle5; + this.uncRecordingPathsDataGrid.GridColor = System.Drawing.SystemColors.Control; + this.uncRecordingPathsDataGrid.Location = new System.Drawing.Point(7, 20); + this.uncRecordingPathsDataGrid.MultiSelect = false; + this.uncRecordingPathsDataGrid.Name = "uncRecordingPathsDataGrid"; + this.uncRecordingPathsDataGrid.ReadOnly = true; + dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle6.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.uncRecordingPathsDataGrid.RowHeadersDefaultCellStyle = dataGridViewCellStyle6; + this.uncRecordingPathsDataGrid.RowHeadersVisible = false; + this.uncRecordingPathsDataGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.uncRecordingPathsDataGrid.Size = new System.Drawing.Size(525, 100); + this.uncRecordingPathsDataGrid.StandardTab = true; + this.uncRecordingPathsDataGrid.TabIndex = 0; + this.uncRecordingPathsDataGrid.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.uncRecordingPathsDataGrid_CellFormatting); + this.uncRecordingPathsDataGrid.SelectionChanged += new System.EventHandler(this.uncRecordingPathsDataGrid_SelectionChanged); + // + // Card + // + this.Card.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.Card.DataPropertyName = "CardName"; + this.Card.FillWeight = 30F; + this.Card.HeaderText = "Card"; + this.Card.Name = "Card"; + this.Card.ReadOnly = true; + // + // Path + // + this.Path.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.Path.DataPropertyName = "Message"; + this.Path.FillWeight = 70F; + this.Path.HeaderText = "Path"; + this.Path.Name = "Path"; + this.Path.ReadOnly = true; + // + // SetupForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.tabControl1); + this.Name = "SetupForm"; + this.Size = new System.Drawing.Size(559, 400); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.portNumericUpDown)).EndInit(); + this.uncPathsTabPage.ResumeLayout(false); + this.uncTimeshiftGroupBox.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.uncTimeshiftPathsDataGrid)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.uncTimeshiftPathsBindingSource)).EndInit(); + this.uncRecordingGroupBox.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.uncRecordingPathsDataGrid)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.uncRecordingPathsBindingSource)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage uncPathsTabPage; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.NumericUpDown portNumericUpDown; + private System.Windows.Forms.Label _tcpPortLabel; + private System.Windows.Forms.GroupBox uncRecordingGroupBox; + private System.Windows.Forms.DataGridView uncRecordingPathsDataGrid; + private System.Windows.Forms.DataGridViewTextBoxColumn Card; + private System.Windows.Forms.DataGridViewTextBoxColumn Path; + private System.Windows.Forms.GroupBox uncTimeshiftGroupBox; + private System.Windows.Forms.DataGridView uncTimeshiftPathsDataGrid; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2; + private System.Windows.Forms.Button createTimeshiftShareButton; + private System.Windows.Forms.Button createRecordingsShareButton; + private System.Windows.Forms.Button refreshUncButton; + private System.Windows.Forms.BindingSource uncRecordingPathsBindingSource; + private System.Windows.Forms.BindingSource uncTimeshiftPathsBindingSource; + } +} diff --git a/TVServerKodi/Forms/SetupForm.cs b/TVServerKodi/Forms/SetupForm.cs new file mode 100644 index 0000000..964856a --- /dev/null +++ b/TVServerKodi/Forms/SetupForm.cs @@ -0,0 +1,284 @@ +/* + * TVServerKodi plugin for Team MediaPortal's TV-Server + * Copyright (C) 2010-2012 Marcel Groothuis + * http://www.github.com/margro + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This SetupForm is based on the SetupForm from ARGUS TV + * http://www.argus-tv.com + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +using TvLibrary.Log; +using TvControl; + +using TVServerKodi.Common; + +namespace TVServerKodi.Forms +{ + public partial class SetupForm : SetupTv.SectionSettings + { + public SetupForm() + { + InitializeComponent(); + uncRecordingPathsBindingSource.DataSource = typeof(List); + } + + #region Properties + private TVServerKodiPlugin m_plugin; + + public TVServerKodiPlugin Plugin + { + get { return m_plugin; } + set { m_plugin = value; } + } + #endregion + + #region SetupTv.SectionSettings + + public override void OnSectionActivated() + { + Log.Info("TVServerKodi: Configuration activated"); + + m_plugin.LoadSettings(); + portNumericUpDown.Value = m_plugin.Port; + + LoadUncPaths(); + + base.OnSectionActivated(); + } + + public override void OnSectionDeActivated() + { + Log.Info("TVServerKodi: Configuration deactivated"); + + m_plugin.Port = (int) portNumericUpDown.Value; + m_plugin.SaveSettings(); + + base.OnSectionDeActivated(); + } + + #endregion + + private void LoadUncPaths() + { + Log.Info("TVServerKodi: Loading UNC paths"); + try + { + bool anyError = false; + + List pathItems = new List(); + List tsPathItems = new List(); + + List mediaPortalCards = Utility.GetAllCards(); + foreach (TvDatabase.Card card in mediaPortalCards) + { + Log.Info("Card: " + card.Name + " " + card.RecordingFolder + " " + card.TimeShiftFolder); + anyError = anyError | AddUncPathItem(pathItems, card.Name, card.RecordingFolder); + anyError = anyError | AddUncPathItem(tsPathItems, card.Name, card.TimeShiftFolder); + } + + uncRecordingPathsBindingSource.DataSource = pathItems; + uncTimeshiftPathsBindingSource.DataSource = tsPathItems; + EnableUncButtons(); + + if (anyError) + { + // MessageBox.Show(this, "You must set up at least 2 shares with full permissions to access the recordings and timeshift folders on remote Kodi clients!", null, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + Log.Info("TVServerKodi: At least one of the timeshift or recordings folders is not accessible for remote clients."); + } + } + catch (Exception ex) + { + MessageBox.Show(this, ex.Message, null, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private static bool AddUncPathItem(List pathItems, string name, string path) + { + bool hasError = true; + string message; + + string uncPath = ShareExplorer.GetUncPathForLocalPath(path); + if (!String.IsNullOrEmpty(uncPath)) + { + Log.Info("TVServerKodi: " + path + " => " + uncPath); + message = uncPath; + path = uncPath; + hasError = false; + } + else + { + message = path; + hasError = true; + } + + pathItems.Add(new UncPathItem(name, path, message, hasError)); + + return hasError; + } + + private void EnableUncButtons() + { + if (uncRecordingPathsDataGrid.SelectedRows.Count > 0) + { + UncPathItem linkItem = uncRecordingPathsDataGrid.SelectedRows[0].DataBoundItem as UncPathItem; + createRecordingsShareButton.Enabled = true; + } + else + { + createRecordingsShareButton.Enabled = false; + } + if (uncTimeshiftPathsDataGrid.SelectedRows.Count > 0) + { + UncPathItem linkItem = uncTimeshiftPathsDataGrid.SelectedRows[0].DataBoundItem as UncPathItem; + createTimeshiftShareButton.Enabled = true; + } + else + { + createTimeshiftShareButton.Enabled = false; + } + } + + private class UncPathItem + { + private string _cardName; + private string _recordingPath; + private string _message; + private bool _hasError; + + public UncPathItem(string cardName, string recordingPath, string message, bool hasError) + { + _cardName = cardName; + _recordingPath = recordingPath; + _message = message; + _hasError = hasError; + } + + public string CardName + { + get { return _cardName; } + } + + public string RecordingPath + { + get { return _recordingPath; } + } + + public string Message + { + get { return _message; } + } + + public bool HasError + { + get { return _hasError; } + } + } + + private void createRecordingsShareButton_Click(object sender, EventArgs e) + { + if (uncRecordingPathsDataGrid.SelectedRows.Count > 0) + { + ShowCreateShareForm(uncRecordingPathsDataGrid.SelectedRows[0].DataBoundItem as UncPathItem); + } + } + + private void createTimeshiftShareButton_Click(object sender, EventArgs e) + { + if (uncTimeshiftPathsDataGrid.SelectedRows.Count > 0) + { + ShowCreateShareForm(uncTimeshiftPathsDataGrid.SelectedRows[0].DataBoundItem as UncPathItem); + } + } + + private void refreshUncButton_Click(object sender, EventArgs e) + { + LoadUncPaths(); + } + + private void uncRecordingPathsDataGrid_SelectionChanged(object sender, EventArgs e) + { + EnableUncButtons(); + } + + private void uncRecordingPathsDataGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) + { + DataGridView dataGridView = sender as DataGridView; + if (e.ColumnIndex == 1 + && e.RowIndex >= 0 + && e.RowIndex < uncRecordingPathsBindingSource.Count) + { + UncPathItem linkItem = dataGridView.Rows[e.RowIndex].DataBoundItem as UncPathItem; + if (linkItem != null + && linkItem.HasError) + { + e.CellStyle.ForeColor = Color.Red; + e.CellStyle.SelectionForeColor = Color.Red; + } + else + { + e.CellStyle.ForeColor = Color.DarkGreen; + e.CellStyle.SelectionForeColor = Color.DarkGreen; + } + } + } + + private void uncTimeshiftPathsDataGrid_SelectionChanged(object sender, EventArgs e) + { + EnableUncButtons(); + } + + private void uncTimeshiftPathsDataGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) + { + DataGridView dataGridView = sender as DataGridView; + if (e.ColumnIndex == 1 + && e.RowIndex >= 0 + && e.RowIndex < uncTimeshiftPathsBindingSource.Count) + { + UncPathItem linkItem = dataGridView.Rows[e.RowIndex].DataBoundItem as UncPathItem; + if (linkItem != null + && linkItem.HasError) + { + e.CellStyle.ForeColor = Color.Red; + e.CellStyle.SelectionForeColor = Color.Red; + } + else + { + e.CellStyle.ForeColor = Color.DarkGreen; + e.CellStyle.SelectionForeColor = Color.DarkGreen; + } + } + + } + + private void ShowCreateShareForm(UncPathItem linkItem) + { + CreateShareForm form = new CreateShareForm(); + form.LocalPath = linkItem.RecordingPath; + if (form.ShowDialog(this) == DialogResult.OK) + { + LoadUncPaths(); + } + } + } +} diff --git a/TVServerKodi/Forms/SetupForm.resx b/TVServerKodi/Forms/SetupForm.resx new file mode 100644 index 0000000..01e4f92 --- /dev/null +++ b/TVServerKodi/Forms/SetupForm.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + 252, 17 + + + True + + + True + + + 17, 17 + + \ No newline at end of file diff --git a/TVServerXBMC/Gentle.config b/TVServerKodi/Gentle.config similarity index 92% rename from TVServerXBMC/Gentle.config rename to TVServerKodi/Gentle.config index 478ffc4..c16f113 100644 --- a/TVServerXBMC/Gentle.config +++ b/TVServerKodi/Gentle.config @@ -58,7 +58,8 @@ --> - + + - + diff --git a/TVServerKodi/Installer/MPEI_update_1_10.xml b/TVServerKodi/Installer/MPEI_update_1_10.xml new file mode 100644 index 0000000..a24f6e0 --- /dev/null +++ b/TVServerKodi/Installer/MPEI_update_1_10.xml @@ -0,0 +1,467 @@ + + + + + 2.0 + + + + TVServer_plugin + true + TVServer_plugin + + + + + + + + + + + + + Installer + + + 1 + 5 + 0 + 0 + + + 1 + 20 + 999 + 0 + + true + requires at least MPEI 1.5.x + MPEI + + + TvServer + + + 1 + 9 + 0 + 0 + + + 1 + 12 + 999 + 0 + + true + requires MediaPortal TVServer version 1.5.* or above + MediaPortal TVServer + + + MediaPortal + + + 1 + 1 + 6 + 27644 + + + 1 + 1 + 6 + 27644 + + false + requires MediaPortal version 1.1.6.27644 to 1.1.6.27644. + MediaPortal + + + + + + + + TVServerKodi + 81b6b5e8-b4e0-4d1c-a2e2-cb2db54844f1 + Marcel Groothuis, Prashant V + http://www.scintilla.utwente.nl/~marcelg/xbmc/tvserverxbmc.html + http://forum.xbmc.org/forumdisplay.php?fid=171 + https://dl.dropbox.com/u/7249985/xbmc/tvserverxbmc/MPEI_Update_1_10.xml + + 1 + 12 + 0 + 129 + + With this plugin you can watch Live TV, recordings, EPG and schedules in XBMC (v12.0 or above) and Kodi + + + + + +. The TVServerKodi plugin extends the MediaPortal TVServer with a dedicated RPC gateway to allow XBMC/Kodi to access and control the TVServer. + + + + + + + + + + + + + + Stable + https://dl.dropbox.com/u/7249985/xbmc/tvserverxbmc/TVServerXBMC-1.12.0.128.mpe1 + 2014-08-18T19:29:03 + xbmc, kodi, tv server plugins + ..\bin\[Name]-[Version].mpe1 + + + + + String + The icon file of the package stored online (jpg,png,bmp) + + + + Template + The file used to configure the extension. + If it has .exe extension the will be executed. + If it has .dll extension it's started like MP plugin configuration. + + + + String + Online stored screenshot urls separated by ; + + + yes + Bool + Show dialog and force to uninstall previous version when updating an extension. Should only be disabled if you are using an NSIS/MSI installer. + + + + + + + + + + + false + + + 2.0 + + + + TVServer_plugin + true + TVServer_plugin + + + + + + + + + + + + + Installer + + + 1 + 5 + 0 + 0 + + + 1 + 20 + 999 + 0 + + true + requires at least MPEI 1.5.x + MPEI + + + TvServer + + + 1 + 9 + 0 + 0 + + + 1 + 20 + 999 + 0 + + true + requires MediaPortal TVServer version 1.5.* or above + MediaPortal TVServer + + + MediaPortal + + + 1 + 1 + 6 + 27644 + + + 1 + 1 + 6 + 27644 + + false + requires MediaPortal version 1.1.6.27644 to 1.1.6.27644. + MediaPortal + + + + + + + + TVServerKodi + 81b6b5e8-b4e0-4d1c-a2e2-cb2db54844f1 + Marcel Groothuis, Prashant V + http://www.scintilla.utwente.nl/~marcelg/xbmc/tvserverxbmc.html + http://forum.xbmc.org/forumdisplay.php?fid=171 + https://dl.dropbox.com/u/7249985/xbmc/tvserverxbmc/MPEI_Update_1_10.xml + + 1 + 12 + 0 + 130 + + With this plugin you can watch Live TV, recordings, EPG and schedules in XBMC (v12.0 or above) and Kodi + + + + + +. The TVServerKodi plugin extends the MediaPortal TVServer with a dedicated RPC gateway to allow XBMC/Kodi to access and control the TVServer. + + + + + + + + + + + + + + Stable + https://dl.dropbox.com/u/7249985/xbmc/tvserverxbmc/TVServerXBMC-1.12.0.130.mpe1 + 2014-08-18T19:29:03 + xbmc, kodi, tv server plugins + ..\bin\[Name]-[Version].mpe1 + + + + + String + The icon file of the package stored online (jpg,png,bmp) + + + + Template + The file used to configure the extension. + If it has .exe extension the will be executed. + If it has .dll extension it's started like MP plugin configuration. + + + + String + Online stored screenshot urls separated by ; + + + yes + Bool + Show dialog and force to uninstall previous version when updating an extension. Should only be disabled if you are using an NSIS/MSI installer. + + + + + + + + + + + false + + + 2.0 + + + + TVServer_plugin + true + TVServer_plugin + + + + + + + + + + + + + Installer + + + 1 + 5 + 0 + 0 + + + 1 + 20 + 999 + 0 + + true + requires at least MPEI 1.5.x + MPEI + + + TvServer + + + 1 + 9 + 0 + 0 + + + 1 + 20 + 999 + 0 + + true + requires MediaPortal TVServer version 1.5.* or above + MediaPortal TVServer + + + MediaPortal + + + 1 + 1 + 6 + 27644 + + + 1 + 1 + 6 + 27644 + + false + requires MediaPortal version 1.1.6.27644 to 1.1.6.27644. + MediaPortal + + + + + + + + TVServerKodi + 81b6b5e8-b4e0-4d1c-a2e2-cb2db54844f1 + Marcel Groothuis, Prashant V + http://www.scintilla.utwente.nl/~marcelg/xbmc/tvserverxbmc.html + http://forum.xbmc.org/forumdisplay.php?fid=171 + https://dl.dropbox.com/u/7249985/xbmc/tvserverxbmc/MPEI_Update_1_10.xml + + 1 + 12 + 0 + 131 + + With this plugin you can watch Live TV, recordings, EPG and schedules in XBMC (v12.0 or above) and Kodi + + + + + +. The TVServerKodi plugin extends the MediaPortal TVServer with a dedicated RPC gateway to allow XBMC/Kodi to access and control the TVServer. + + + + + + + + + + + + + + Stable + https://dl.dropbox.com/u/7249985/xbmc/tvserverxbmc/TVServerXBMC-1.12.0.130.mpe1 + 2014-08-18T19:29:03 + xbmc, kodi, tv server plugins + ..\bin\[Name]-[Version].mpe1 + + + + + String + The icon file of the package stored online (jpg,png,bmp) + + + + Template + The file used to configure the extension. + If it has .exe extension the will be executed. + If it has .dll extension it's started like MP plugin configuration. + + + + String + Online stored screenshot urls separated by ; + + + yes + Bool + Show dialog and force to uninstall previous version when updating an extension. Should only be disabled if you are using an NSIS/MSI installer. + + + + + + + + + + + false + + + \ No newline at end of file diff --git a/TVServerKodi/Installer/TVServerKodi.xmp2 b/TVServerKodi/Installer/TVServerKodi.xmp2 new file mode 100644 index 0000000..10e7a34 --- /dev/null +++ b/TVServerKodi/Installer/TVServerKodi.xmp2 @@ -0,0 +1,282 @@ + + + 2.0 + + + + + TVServer plugin + true + TVServer plugin + + + + + AlwaysOverwrite + ..\bin\Release\TVServerKodi.dll + Installer{CopyFile}\{477da3d6-72c1-4f37-af0f-3e666d9546ba}-TVServerKodi.dll + %TvServerPlugins%\TVServerKodi.dll + + + + + + + + + + + + + Welcome to the Extension Installer for [Name] + String + + + + This will install [Name] version [Version] on your computer. +It is recommended that you close all other applications before continuing. +Click Next to continue or Cancel to exit Setup. + String + + + + + File + + + + + File + Image in upper right part + + + + + + + + Welcome Screen + NextCancel + + + + + + + String + Header title + + + + String + Description of section, shown in under section title + + + + File + Image in upper right part + + + + + + + + + + AfterPanelShow + + + + + Install Section + Next + + + + + + The Extension Installer Wizard has successfully installed [Name]. + String + + + + + File + + + + + Bool + Use radiobutton in place of combobox + + + + File + Image in upper right part + + + + + + + + Setup Complete + Finish + + + + + + + Installer + + + 1 + 5 + 0 + 0 + + + 1 + 20 + 999 + 0 + + true + requires at least MPEI 1.5.x + MPEI + + + TvServer + + + 1 + 9 + 0 + 0 + + + 1 + 20 + 999 + 0 + + true + requires MediaPortal TVServer version 1.5.* or above + MediaPortal TVServer + + + MediaPortal + + + 1 + 1 + 6 + 27644 + + + 1 + 1 + 6 + 27644 + + false + requires MediaPortal version 1.1.6.27644 to 1.1.6.27644. + MediaPortal + + + + + + + + TVServerKodi + 81b6b5e8-b4e0-4d1c-a2e2-cb2db54844f1 + Marcel Groothuis, Prashant V + http://www.scintilla.utwente.nl/~marcelg/xbmc/tvserverxbmc.html + http://forum.xbmc.org/forumdisplay.php?fid=171 + https://dl.dropbox.com/u/7249985/xbmc/tvserverxbmc/MPEI_Update_1_10.xml + + 1 + 12 + 0 + 131 + + With this plugin you can watch Live TV, recordings, EPG and schedules in XBMC (v12.0 or above) and Kodi + + + + + +. The TVServerKodi plugin extends the MediaPortal TVServer with a dedicated RPC gateway to allow XBMC/Kodi to access and control the TVServer. + + + + + + + + + + + + + + Stable + https://dl.dropbox.com/u/7249985/xbmc/tvserverxbmc/TVServerXBMC-1.12.0.130.mpe1 + 2014-08-18T19:29:03 + xbmc, kodi, tv server plugins + ..\bin\[Name]-[Version].mpe1 + + + + + File + The icon file of the package (jpg,png,bmp) + + + + String + The icon file of the package stored online (jpg,png,bmp) + + + + Template + The file used to configure the extension. + If it has .exe extension the will be executed. + If it has .dll extension it's started like MP plugin configuration. + + + + String + Online stored screenshot urls separated by ; + + + yes + Bool + Show dialog and force to uninstall previous version when updating an extension. Should only be disabled if you are using an NSIS/MSI installer. + + + + + + + + + AlwaysOverwrite + ..\bin\Release\TVServerKodi.dll + Installer{CopyFile}\{477da3d6-72c1-4f37-af0f-3e666d9546ba}-TVServerKodi.dll + %TvServerPlugins%\TVServerKodi.dll + + + + + + TVServerKodi.xmp2 + MPEI_update_1_10.xml + + + + false + \ No newline at end of file diff --git a/TVServerKodi/Listener.cs b/TVServerKodi/Listener.cs new file mode 100644 index 0000000..779d295 --- /dev/null +++ b/TVServerKodi/Listener.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Net.Sockets; +using System.Threading; +using System.Net; +using TvLibrary.Log; + +namespace TVServerKodi +{ + class Listener + { + private TcpListener tcpListener; + private int port; + private List m_clients; + private List m_communicationThreads; + private Mutex cmdMutex; + private bool stopme = false; + private Thread m_listenThread; + + public Listener() + { + this.port = 9596; + this.tcpListener = new TcpListener(IPAddress.Any, port); + } + + public Listener(int listenport) + { + this.port = listenport; + try + { + this.tcpListener = new TcpListener(IPAddress.Any, port); + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + } + } + + + public bool StartListening() + { + try + { + tcpListener.Start(); + + // start a thread to listen for clients + m_listenThread = new Thread(new ThreadStart(ListenForClients)); + m_listenThread.Start(); + + return true; + } + catch (ThreadAbortException) + { + // a thread abort, we want to end nicely + } + catch (System.Net.Sockets.SocketException e) + { + if (e.SocketErrorCode == System.Net.Sockets.SocketError.AddressAlreadyInUse) + { + Console.WriteLine("Socket error: address already in use. Check if you have other instances of the TVServerKodi running (plugin/exe)"); + Log.Error("TVServerKodi: Socket error: address already in use. Check if you have other instances of the TVServerKodi running (plugin/exe)"); + } + else + { + Log.Error("TVServerKodi: Socket error : " + e.ToString()); + Console.WriteLine(e.ToString()); + } + } + catch (Exception e) + { + Log.Error("TVServerKodi: Unexpected error in StartListening(): " + e.ToString()); + Console.WriteLine(e.ToString()); + } + + return false; + } + + public void Stop() + { + try + { + Log.Debug("TVServerKodi: tcpListener.Stop()"); + Console.WriteLine("TVServerKodi: tcpListener.Stop()"); + stopme = true; + + if (m_listenThread != null) + { + Log.Debug("TVServerKodi: Listenthread is aborting"); + m_listenThread.Abort(); + m_listenThread = null; + } + + if (m_communicationThreads.Count > 0) + { + Log.Debug("TVServerKodi: Stop all communication threads"); + foreach (Thread thread in m_communicationThreads) + { + thread.Abort(); + } + m_communicationThreads.Clear(); + m_communicationThreads = null; + } + + if (m_clients.Count > 0) + { + Log.Debug("TVServerKodi: Closing all client connections"); + foreach (TcpClient client in m_clients) + { + client.Close(); + } + + m_clients = null; + } + } + catch (Exception) + { } + } + + public void ListenForClients() + { + try + { + m_clients = new List(); + m_communicationThreads = new List(); + cmdMutex = new Mutex(); + + while (!stopme) + { + Console.WriteLine("Waiting for clients..."); + Log.Debug("TVServerKodi: Waiting for clients..."); + while (!this.tcpListener.Pending()) + { + Thread.Sleep(30); + } + + // blocks until a client has connected to the server + TcpClient client = this.tcpListener.AcceptTcpClient(); + + // Multithreaded version: + Console.WriteLine("New Connection! Starting handler thread for client." + client.Client.RemoteEndPoint.ToString()); + Log.Debug("TVServerKodi: New Connection! Starting handler thread for client." + client.Client.RemoteEndPoint.ToString()); + //___________________________ + lock (this) + { + m_clients.Add(client); + } + + ConnectionHandler handler = new ConnectionHandler(client, cmdMutex, m_clients.Count); + ThreadStart thdstHandler = new ThreadStart(handler.HandleConnection); + Thread communicationThread = new Thread(thdstHandler); + lock (this) + { + m_communicationThreads.Add(communicationThread); + } + communicationThread.Start(); + } + + tcpListener.Stop(); + } + catch (System.Threading.ThreadAbortException) + { + //Expected on a shutdown of the TVServer + } + catch (Exception e) + { + Log.Error("TVServerKodi: Unexpected error in ListenForClients(): " + e.ToString()); + Console.WriteLine(e.ToString()); + } + } + } +} diff --git a/TVServerKodi/Plugin.cs b/TVServerKodi/Plugin.cs new file mode 100644 index 0000000..ef1bd57 --- /dev/null +++ b/TVServerKodi/Plugin.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TvEngine; +using System.Threading; +using TvLibrary.Log; +using TvLibrary.Interfaces; +using TvEngine.Events; +using TVServerKodi.Forms; + +namespace TVServerKodi +{ + public class TVServerKodiPlugin : ITvServerPlugin + { + #region variables + int m_defaultServerPort = 9596; + int m_serverPort = 9596; + bool connected = false; + Listener m_listener = null; + + #endregion + + #region properties + + /// + /// returns the name of the plugin + /// + public string Name + { + get { return "TVServerKodi"; } + } + + /// + /// returns the version of the plugin + /// + public string Version + { + get + { + return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); + } + } + + /// + /// returns the author of the plugin + /// + public string Author + { + get { return "margro, Prashant V"; } + } + + /// + /// returns if the plugin should only run on the master server + /// or also on slave servers + /// + public bool MasterOnly + { + get { return true; } + } + + // properties below are TVServerKodi specific + public bool Connected + { + get + { + return connected; + } + } + + public int Port + { + get { return m_serverPort; } + set { m_serverPort = value; } + } + + #endregion + + #region IPlugin Methods + + /// + /// Starts the plugin + /// + public void Start(TvControl.IController controller) + { + // set up our remote control interface + Log.WriteFile("TVServerKodi: plugin started"); + + try + { + LoadSettings(); + + connected = TVServerConnection.Init(controller); + if (connected) + { + if (GlobalServiceProvider.Instance.IsRegistered()) + { + GlobalServiceProvider.Instance.TryGet().OnTvServerEvent += events_OnTvServerEvent; + Log.Debug("TVServerKodi: Registered OnTvServerEvent with TV Server"); + } + + connected = StartListenThread(); + } + else + { + Log.Error("TVServerKodi: TVServerConnection init failed."); + } + } + catch + { + Log.Error("TVServerKodi: TVServerConnection.Init failed!"); + Console.WriteLine("TVServerConnection.Init failed!"); + } + } + + /// + /// Stops the plugin + /// + public void Stop() + { + if (GlobalServiceProvider.Instance.IsRegistered()) + { + Log.Debug("TVServerKodi: Unregistered OnTvServerEvent with TV Server"); + GlobalServiceProvider.Instance.Get().OnTvServerEvent -= events_OnTvServerEvent; + } + + StopListenThread(); + + Log.WriteFile("TVServerKodi: plugin stopped"); + } + + private bool StartListenThread() + { + try + { + Log.Info("TVServerKodi: Start listening on port " + m_serverPort); + Console.WriteLine("TVServerKodi: Start listening on port " + m_serverPort); + + // start a thread for the listener + + m_listener = new Listener(m_serverPort); + m_listener.StartListening(); + } + catch + { + Log.Error("TVServerKodi: StartListenThread failed!"); + Console.WriteLine("StartListenThread failed!"); + } + + return false; + } + + private void StopListenThread() + { + try + { + if (m_listener != null) + { + if (connected) + TVServerConnection.CloseAll(); + + Log.Info("TVServerKodi: Stop listening"); + + m_listener.Stop(); + m_listener = null; + } + } + catch + { + Log.Error("TVServerKodi: StopListenThread failed!"); + Console.WriteLine("StopListenThread failed!"); + } + } + + /// + /// returns the setup sections for display in SetupTv + /// + public SetupTv.SectionSettings Setup + { + get + { + SetupForm setupForm = new SetupForm(); + setupForm.Plugin = this; + return setupForm; + } + } + + #endregion IPlugin Methods + + #region TvServer Events + private void events_OnTvServerEvent(object sender, EventArgs eventArgs) + { + TvEngine.Events.TvServerEventArgs args = eventArgs as TvEngine.Events.TvServerEventArgs; + + if (args == null) + return; + + Log.Debug("TVServerKodi: OnTvServerEvent: " + args.EventType.ToString()); + + if (args.EventType == TvEngine.Events.TvServerEventType.ImportEpgPrograms + && args.EpgChannel != null + && args.EpgChannel.Programs.Count > 0) + { + try + { + if (args.channel != null) + Log.Info("TVServerKodi: EPG import for channel: " + args.channel.Name); + + TvLibrary.Channels.DVBBaseChannel dvbChannel = args.EpgChannel.Channel as TvLibrary.Channels.DVBBaseChannel; + if (dvbChannel != null) + { + TvDatabase.TvBusinessLayer layer = new TvDatabase.TvBusinessLayer(); + TvDatabase.Channel mpChannel = layer.GetChannelByTuningDetail(dvbChannel.NetworkId, dvbChannel.TransportId, dvbChannel.ServiceId); + if (mpChannel != null) + { + Log.Debug("TVServerKodi: received {0} programs on {1}", args.EpgChannel.Programs.Count, mpChannel.DisplayName); + //foreach (TvLibrary.Epg.EpgProgram p in args.EpgChannel.Programs) + //{ + // Log.Info("TVServerKodi: program: " + p.StartTime.ToString() + "-" + p.EndTime.ToString()); + //} + } + } + //ImportEpgPrograms(args.EpgChannel); + } + catch (Exception ex) + { + Log.Error("TVServerKodi: ImportEpgPrograms(): {0}", ex.Message); + } + } + } + #endregion + + #region Local methods + + internal void LoadSettings() + { + try + { + TvDatabase.TvBusinessLayer layer = new TvDatabase.TvBusinessLayer(); + m_serverPort = Convert.ToInt32(layer.GetSetting("TVServerKodi.port", m_defaultServerPort.ToString()).Value); + } + catch (Exception ex) + { + m_serverPort = m_defaultServerPort; + Log.Error("TVServerKodi: LoadSettings(): {0}", ex.Message); + } + } + + internal void SaveSettings() + { + bool forceReload = false; + + try + { + TvDatabase.TvBusinessLayer layer = new TvDatabase.TvBusinessLayer(); + TvDatabase.Setting setting; + + setting = layer.GetSetting("TVServerKodi.port"); + if (Convert.ToInt32(setting.Value) != m_serverPort) + { + Log.Info("TVServerKodi: port setting changed from " + setting.Value + " to " + m_serverPort); + setting.Value = m_serverPort.ToString(); + setting.Persist(); + forceReload = true; + } + } + catch (Exception ex) + { + Log.Error("TVServerKodi: SaveSettings(): {0}", ex.Message); + } + + if (forceReload) + { + StopListenThread(); + StartListenThread(); + } + } + + #endregion + } +} diff --git a/TVServerXBMC/Program.cs b/TVServerKodi/Program.cs similarity index 63% rename from TVServerXBMC/Program.cs rename to TVServerKodi/Program.cs index 0fc7a1a..8d31c85 100644 --- a/TVServerXBMC/Program.cs +++ b/TVServerKodi/Program.cs @@ -4,7 +4,7 @@ using TvControl; -namespace TVServerXBMC.Commands +namespace TVServerKodi.Commands { // simple wrapper to let us run it as a program // allowing for much faster debugging @@ -12,11 +12,13 @@ namespace TVServerXBMC.Commands class Program { //static string hostname = "htpc"; //hostname of the TV server - //static int listenport = 9595; //local port for the MPTV XBMC server + //static int listenport = 9595; //local port for the MPTV XBMC/Kodi server static string hostname = "localhost"; - static int listenport = 9596; static bool connected = false; + static TvControl.IController controller; + static string databaseConnectionString; + static string databaseProvider; public static void Main(string[] args) { @@ -33,9 +35,11 @@ public static void Main(string[] args) } Console.WriteLine("Connected to the MediaPortal TVServer running on: '" + hostname + "'"); + controller = RemoteControl.Instance; + try { - Console.WriteLine("MediaPortal TVServer version: " + RemoteControl.Instance.GetAssemblyVersion.ToString()); + Console.WriteLine("MediaPortal TVServer version: " + controller.GetAssemblyVersion.ToString()); } catch { @@ -43,8 +47,6 @@ public static void Main(string[] args) // Display information about the EXE assembly. System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly(); - //Console.WriteLine("Assembly identity={0}" + a.FullName); - //Console.WriteLine("Codebase={0}" + a.CodeBase); // Display the set of assemblies our assemblies reference. Console.WriteLine("Referenced assemblies:"); @@ -64,14 +66,33 @@ public static void Main(string[] args) } } - XbmcServer plugin = new XbmcServer(); - plugin.Port = listenport; + try + { + controller.GetDatabaseConnectionString(out databaseConnectionString, out databaseProvider); + Console.WriteLine(databaseProvider + ":" + databaseConnectionString); + Console.WriteLine("Set Gentle framework provider to " + databaseProvider); + Console.WriteLine("Set Gentle framework provider string to " + databaseConnectionString); + Gentle.Framework.ProviderFactory.SetDefaultProvider(databaseProvider); + Gentle.Framework.ProviderFactory.SetDefaultProviderConnectionString(databaseConnectionString); + } + catch (Exception ex) + { + Console.WriteLine("An exception occurred while connecting to the database. Did you select the right backend? TVServerKodi default=MySQL; change your Gentle.conf file if you are using MSSQL."); + try + { + Console.WriteLine("The exception: " + ex.ToString()); + } + catch { } + } + + TVServerKodiPlugin plugin = new TVServerKodiPlugin(); - plugin.Start(RemoteControl.Instance); + Console.WriteLine("Starting debug version of the TVServerKodi plugin"); + plugin.Start(controller); - if(plugin.Connected) + if (plugin.Connected) { - Console.WriteLine("Running MediaPortal TV Server -> XBMC wrapper at port: " + listenport); + Console.WriteLine("Running MediaPortal TV Server -> Kodi wrapper at port: " + plugin.Port); try { while (!Console.ReadLine().Contains("quit")) @@ -92,6 +113,5 @@ public static void Main(string[] args) return; } } - } } diff --git a/TVServerXBMC/Properties/AssemblyInfo.cs b/TVServerKodi/Properties/AssemblyInfo.cs similarity index 72% rename from TVServerXBMC/Properties/AssemblyInfo.cs rename to TVServerKodi/Properties/AssemblyInfo.cs index 4266ec5..049e741 100644 --- a/TVServerXBMC/Properties/AssemblyInfo.cs +++ b/TVServerKodi/Properties/AssemblyInfo.cs @@ -1,16 +1,17 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using MediaPortal.Common.Utils; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("TVServerXBMC")] -[assembly: AssemblyDescription("MediaPortal TVServer plugin for XBMC PVR clients")] +[assembly: AssemblyTitle("TVServerKodi")] +[assembly: AssemblyDescription("MediaPortal TVServer plugin for Kodi and XBMC PVR clients")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TVServerXBMC")] -[assembly: AssemblyCopyright("Copyright © Marcel Groothuis 2010-2011")] +[assembly: AssemblyProduct("TVServerKodi")] +[assembly: AssemblyCopyright("Copyright © Marcel Groothuis 2010-2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -29,5 +30,10 @@ // Build Number // Revision // -[assembly: AssemblyVersion("1.1.3.109")] -[assembly: AssemblyFileVersion("1.1.3.109")] +[assembly: AssemblyVersion("1.14.0.133")] +[assembly: AssemblyFileVersion("1.14.0.133")] + +// Set usage and compatibility information to MediaPortal v1.3.0 beta and above +[assembly: CompatibleVersion("1.9.100.0", "1.5.0.0")] +[assembly: UsesSubsystem("TVE")] + diff --git a/TVServerKodi/References/Common.Utils.dll b/TVServerKodi/References/Common.Utils.dll new file mode 100644 index 0000000..587ec42 Binary files /dev/null and b/TVServerKodi/References/Common.Utils.dll differ diff --git a/TVServerKodi/References/Gentle.Common.dll b/TVServerKodi/References/Gentle.Common.dll new file mode 100644 index 0000000..1aa4f88 Binary files /dev/null and b/TVServerKodi/References/Gentle.Common.dll differ diff --git a/TVServerKodi/References/Gentle.Framework.dll b/TVServerKodi/References/Gentle.Framework.dll new file mode 100644 index 0000000..06d8b86 Binary files /dev/null and b/TVServerKodi/References/Gentle.Framework.dll differ diff --git a/TVServerXBMC/References/Gentle.Provider.MySQL.dll b/TVServerKodi/References/Gentle.Provider.MySQL.dll similarity index 57% rename from TVServerXBMC/References/Gentle.Provider.MySQL.dll rename to TVServerKodi/References/Gentle.Provider.MySQL.dll index 4f87d24..2bcf901 100644 Binary files a/TVServerXBMC/References/Gentle.Provider.MySQL.dll and b/TVServerKodi/References/Gentle.Provider.MySQL.dll differ diff --git a/TVServerKodi/References/Gentle.Provider.SQLServer.dll b/TVServerKodi/References/Gentle.Provider.SQLServer.dll new file mode 100644 index 0000000..6ffe2ee Binary files /dev/null and b/TVServerKodi/References/Gentle.Provider.SQLServer.dll differ diff --git a/TVServerKodi/References/Gentle.Provider.SQLite.dll b/TVServerKodi/References/Gentle.Provider.SQLite.dll new file mode 100644 index 0000000..0bc0c11 Binary files /dev/null and b/TVServerKodi/References/Gentle.Provider.SQLite.dll differ diff --git a/TVServerXBMC/References/MySql.Data.dll b/TVServerKodi/References/MySql.Data.dll similarity index 100% rename from TVServerXBMC/References/MySql.Data.dll rename to TVServerKodi/References/MySql.Data.dll diff --git a/TVServerKodi/References/PluginBase.dll b/TVServerKodi/References/PluginBase.dll new file mode 100644 index 0000000..07c8a98 Binary files /dev/null and b/TVServerKodi/References/PluginBase.dll differ diff --git a/TVServerXBMC/References/SetupControls.dll b/TVServerKodi/References/SetupControls.dll similarity index 62% rename from TVServerXBMC/References/SetupControls.dll rename to TVServerKodi/References/SetupControls.dll index a0e6da6..e9fcd7e 100644 Binary files a/TVServerXBMC/References/SetupControls.dll and b/TVServerKodi/References/SetupControls.dll differ diff --git a/TVServerKodi/References/System.Data.SQLite.DLL b/TVServerKodi/References/System.Data.SQLite.DLL new file mode 100644 index 0000000..cb73703 Binary files /dev/null and b/TVServerKodi/References/System.Data.SQLite.DLL differ diff --git a/TVServerKodi/References/TVDatabase.dll b/TVServerKodi/References/TVDatabase.dll new file mode 100644 index 0000000..1df8167 Binary files /dev/null and b/TVServerKodi/References/TVDatabase.dll differ diff --git a/TVServerKodi/References/TVLibrary.dll b/TVServerKodi/References/TVLibrary.dll new file mode 100644 index 0000000..642ec6d Binary files /dev/null and b/TVServerKodi/References/TVLibrary.dll differ diff --git a/TVServerKodi/References/TvBusinessLayer.dll b/TVServerKodi/References/TvBusinessLayer.dll new file mode 100644 index 0000000..222cafb Binary files /dev/null and b/TVServerKodi/References/TvBusinessLayer.dll differ diff --git a/TVServerKodi/References/TvControl.dll b/TVServerKodi/References/TvControl.dll new file mode 100644 index 0000000..0491c7c Binary files /dev/null and b/TVServerKodi/References/TvControl.dll differ diff --git a/TVServerKodi/References/TvLibrary.Interfaces.dll b/TVServerKodi/References/TvLibrary.Interfaces.dll new file mode 100644 index 0000000..0068bdb Binary files /dev/null and b/TVServerKodi/References/TvLibrary.Interfaces.dll differ diff --git a/TVServerKodi/References/log4net.dll b/TVServerKodi/References/log4net.dll new file mode 100644 index 0000000..06e778c Binary files /dev/null and b/TVServerKodi/References/log4net.dll differ diff --git a/TVServerXBMC/References/readme.txt b/TVServerKodi/References/readme.txt similarity index 100% rename from TVServerXBMC/References/readme.txt rename to TVServerKodi/References/readme.txt diff --git a/TVServerKodi/SetupForm.Designer.cs b/TVServerKodi/SetupForm.Designer.cs new file mode 100644 index 0000000..0286b37 --- /dev/null +++ b/TVServerKodi/SetupForm.Designer.cs @@ -0,0 +1,724 @@ +namespace ForTheRecord.RecorderTuners.MediaPortalTvServer +{ + + partial class SetupForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle10 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle11 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle12 = new System.Windows.Forms.DataGridViewCellStyle(); + this._tvSchedulerGroupBox = new System.Windows.Forms.GroupBox(); + this._connectButton = new System.Windows.Forms.Button(); + this._portNumericUpDown = new System.Windows.Forms.NumericUpDown(); + this._tcpPortLabel = new System.Windows.Forms.Label(); + this._restartTcpLabel = new System.Windows.Forms.Label(); + this._serverTextBox = new System.Windows.Forms.TextBox(); + this._pluginTcpNumericUpDown = new System.Windows.Forms.NumericUpDown(); + this._serverLabel = new System.Windows.Forms.Label(); + this._pluginTcpLabel = new System.Windows.Forms.Label(); + this._channelsPanel = new System.Windows.Forms.Panel(); + this._importChannelsButton = new System.Windows.Forms.Button(); + this._channelTypeComboBox = new System.Windows.Forms.ComboBox(); + this._linkChannelButton = new System.Windows.Forms.Button(); + this._refreshChannelsButton = new System.Windows.Forms.Button(); + this._channelsDataGridView = new System.Windows.Forms.DataGridView(); + this._tvSchedulerChannelColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this._mediaPortalChannelColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this._channelItemsBindingSource = new System.Windows.Forms.BindingSource(this.components); + this._notConnectedPanel = new System.Windows.Forms.Panel(); + this._notConnectedLabel = new System.Windows.Forms.Label(); + this._uncRecordingGroupBox = new System.Windows.Forms.GroupBox(); + this._createUncShareButton = new System.Windows.Forms.Button(); + this._uncPathsDataGridView = new System.Windows.Forms.DataGridView(); + this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this._uncPathsBindingSource = new System.Windows.Forms.BindingSource(this.components); + this._refreshUncButton = new System.Windows.Forms.Button(); + this._syncTve3EpgcheckBox = new System.Windows.Forms.CheckBox(); + this._epgGroupBox = new System.Windows.Forms.GroupBox(); + this._tabControl = new System.Windows.Forms.TabControl(); + this._configTabPage = new System.Windows.Forms.TabPage(); + this._powerGroupBox = new System.Windows.Forms.GroupBox(); + this._restartOnResumeCheckBox = new System.Windows.Forms.CheckBox(); + this._uncPathsTabPage = new System.Windows.Forms.TabPage(); + this._uncTimeshiftGroupBox = new System.Windows.Forms.GroupBox(); + this._createTimeshiftingShareButton = new System.Windows.Forms.Button(); + this._uncTimeshiftingDataGridView = new System.Windows.Forms.DataGridView(); + this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this._uncTimeshiftingBindingSource = new System.Windows.Forms.BindingSource(this.components); + this._channelsTabPage = new System.Windows.Forms.TabPage(); + this._epgOnlyLinkedChannelsRadioButton = new System.Windows.Forms.RadioButton(); + this._epgAutoCreateChannelsDvbRadioButton = new System.Windows.Forms.RadioButton(); + this._epgAutoCreateChannelsWithGroupRadioButton = new System.Windows.Forms.RadioButton(); + this._tvSchedulerGroupBox.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this._portNumericUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this._pluginTcpNumericUpDown)).BeginInit(); + this._channelsPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this._channelsDataGridView)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this._channelItemsBindingSource)).BeginInit(); + this._notConnectedPanel.SuspendLayout(); + this._uncRecordingGroupBox.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this._uncPathsDataGridView)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this._uncPathsBindingSource)).BeginInit(); + this._epgGroupBox.SuspendLayout(); + this._tabControl.SuspendLayout(); + this._configTabPage.SuspendLayout(); + this._powerGroupBox.SuspendLayout(); + this._uncPathsTabPage.SuspendLayout(); + this._uncTimeshiftGroupBox.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this._uncTimeshiftingDataGridView)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this._uncTimeshiftingBindingSource)).BeginInit(); + this._channelsTabPage.SuspendLayout(); + this.SuspendLayout(); + // + // _tvSchedulerGroupBox + // + this._tvSchedulerGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._tvSchedulerGroupBox.Controls.Add(this._connectButton); + this._tvSchedulerGroupBox.Controls.Add(this._portNumericUpDown); + this._tvSchedulerGroupBox.Controls.Add(this._tcpPortLabel); + this._tvSchedulerGroupBox.Controls.Add(this._restartTcpLabel); + this._tvSchedulerGroupBox.Controls.Add(this._serverTextBox); + this._tvSchedulerGroupBox.Controls.Add(this._pluginTcpNumericUpDown); + this._tvSchedulerGroupBox.Controls.Add(this._serverLabel); + this._tvSchedulerGroupBox.Controls.Add(this._pluginTcpLabel); + this._tvSchedulerGroupBox.Location = new System.Drawing.Point(6, 6); + this._tvSchedulerGroupBox.Name = "_tvSchedulerGroupBox"; + this._tvSchedulerGroupBox.Size = new System.Drawing.Size(580, 76); + this._tvSchedulerGroupBox.TabIndex = 0; + this._tvSchedulerGroupBox.TabStop = false; + this._tvSchedulerGroupBox.Text = "For The Record Services"; + // + // _connectButton + // + this._connectButton.Location = new System.Drawing.Point(333, 16); + this._connectButton.Name = "_connectButton"; + this._connectButton.Size = new System.Drawing.Size(110, 23); + this._connectButton.TabIndex = 14; + this._connectButton.Text = "(Re)Connect Now"; + this._connectButton.UseVisualStyleBackColor = true; + this._connectButton.Click += new System.EventHandler(this._connectButton_Click); + // + // _portNumericUpDown + // + this._portNumericUpDown.Location = new System.Drawing.Point(267, 18); + this._portNumericUpDown.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this._portNumericUpDown.Name = "_portNumericUpDown"; + this._portNumericUpDown.Size = new System.Drawing.Size(60, 20); + this._portNumericUpDown.TabIndex = 13; + // + // _tcpPortLabel + // + this._tcpPortLabel.AutoSize = true; + this._tcpPortLabel.Location = new System.Drawing.Point(209, 21); + this._tcpPortLabel.Name = "_tcpPortLabel"; + this._tcpPortLabel.Size = new System.Drawing.Size(52, 13); + this._tcpPortLabel.TabIndex = 12; + this._tcpPortLabel.Text = "TCP port:"; + // + // _restartTcpLabel + // + this._restartTcpLabel.AutoSize = true; + this._restartTcpLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this._restartTcpLabel.ForeColor = System.Drawing.Color.DimGray; + this._restartTcpLabel.Location = new System.Drawing.Point(210, 48); + this._restartTcpLabel.Name = "_restartTcpLabel"; + this._restartTcpLabel.Size = new System.Drawing.Size(240, 13); + this._restartTcpLabel.TabIndex = 17; + this._restartTcpLabel.Text = "(restart MediaPortal TVService if you change this)"; + // + // _serverTextBox + // + this._serverTextBox.Location = new System.Drawing.Point(53, 18); + this._serverTextBox.Name = "_serverTextBox"; + this._serverTextBox.Size = new System.Drawing.Size(150, 20); + this._serverTextBox.TabIndex = 11; + // + // _pluginTcpNumericUpDown + // + this._pluginTcpNumericUpDown.Location = new System.Drawing.Point(147, 45); + this._pluginTcpNumericUpDown.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this._pluginTcpNumericUpDown.Name = "_pluginTcpNumericUpDown"; + this._pluginTcpNumericUpDown.Size = new System.Drawing.Size(60, 20); + this._pluginTcpNumericUpDown.TabIndex = 16; + // + // _serverLabel + // + this._serverLabel.AutoSize = true; + this._serverLabel.Location = new System.Drawing.Point(8, 21); + this._serverLabel.Name = "_serverLabel"; + this._serverLabel.Size = new System.Drawing.Size(41, 13); + this._serverLabel.TabIndex = 10; + this._serverLabel.Text = "Server:"; + // + // _pluginTcpLabel + // + this._pluginTcpLabel.AutoSize = true; + this._pluginTcpLabel.Location = new System.Drawing.Point(8, 48); + this._pluginTcpLabel.Name = "_pluginTcpLabel"; + this._pluginTcpLabel.Size = new System.Drawing.Size(132, 13); + this._pluginTcpLabel.TabIndex = 15; + this._pluginTcpLabel.Text = "Recorder/Tuner TCP port:"; + // + // _channelsPanel + // + this._channelsPanel.Controls.Add(this._importChannelsButton); + this._channelsPanel.Controls.Add(this._channelTypeComboBox); + this._channelsPanel.Controls.Add(this._linkChannelButton); + this._channelsPanel.Controls.Add(this._refreshChannelsButton); + this._channelsPanel.Controls.Add(this._channelsDataGridView); + this._channelsPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this._channelsPanel.Location = new System.Drawing.Point(3, 3); + this._channelsPanel.Name = "_channelsPanel"; + this._channelsPanel.Size = new System.Drawing.Size(586, 368); + this._channelsPanel.TabIndex = 0; + // + // _importChannelsButton + // + this._importChannelsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this._importChannelsButton.Location = new System.Drawing.Point(355, 345); + this._importChannelsButton.Name = "_importChannelsButton"; + this._importChannelsButton.Size = new System.Drawing.Size(145, 23); + this._importChannelsButton.TabIndex = 105; + this._importChannelsButton.Text = "Create/Import Channels..."; + this._importChannelsButton.UseVisualStyleBackColor = true; + this._importChannelsButton.Click += new System.EventHandler(this._importChannelsButton_Click); + // + // _channelTypeComboBox + // + this._channelTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this._channelTypeComboBox.FormattingEnabled = true; + this._channelTypeComboBox.Items.AddRange(new object[] { + "Television Channels", + "Radio Channels"}); + this._channelTypeComboBox.Location = new System.Drawing.Point(6, 3); + this._channelTypeComboBox.Name = "_channelTypeComboBox"; + this._channelTypeComboBox.Size = new System.Drawing.Size(250, 21); + this._channelTypeComboBox.TabIndex = 104; + this._channelTypeComboBox.SelectedIndexChanged += new System.EventHandler(this._channelTypeComboBox_SelectedIndexChanged); + // + // _linkChannelButton + // + this._linkChannelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this._linkChannelButton.Location = new System.Drawing.Point(6, 345); + this._linkChannelButton.Name = "_linkChannelButton"; + this._linkChannelButton.Size = new System.Drawing.Size(110, 23); + this._linkChannelButton.TabIndex = 2; + this._linkChannelButton.Text = "Edit Channel Link"; + this._linkChannelButton.UseVisualStyleBackColor = true; + this._linkChannelButton.Click += new System.EventHandler(this._linkChannelButton_Click); + // + // _refreshChannelsButton + // + this._refreshChannelsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this._refreshChannelsButton.Location = new System.Drawing.Point(506, 345); + this._refreshChannelsButton.Name = "_refreshChannelsButton"; + this._refreshChannelsButton.Size = new System.Drawing.Size(75, 23); + this._refreshChannelsButton.TabIndex = 3; + this._refreshChannelsButton.Text = "Refresh"; + this._refreshChannelsButton.UseVisualStyleBackColor = true; + this._refreshChannelsButton.Click += new System.EventHandler(this._refreshButton_Click); + // + // _channelsDataGridView + // + this._channelsDataGridView.AllowUserToAddRows = false; + this._channelsDataGridView.AllowUserToDeleteRows = false; + this._channelsDataGridView.AllowUserToResizeRows = false; + dataGridViewCellStyle7.BackColor = System.Drawing.Color.WhiteSmoke; + dataGridViewCellStyle7.ForeColor = System.Drawing.Color.Black; + dataGridViewCellStyle7.SelectionBackColor = System.Drawing.Color.Silver; + dataGridViewCellStyle7.SelectionForeColor = System.Drawing.Color.Black; + this._channelsDataGridView.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle7; + this._channelsDataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._channelsDataGridView.AutoGenerateColumns = false; + this._channelsDataGridView.BackgroundColor = System.Drawing.Color.White; + this._channelsDataGridView.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None; + this._channelsDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing; + this._channelsDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this._tvSchedulerChannelColumn, + this._mediaPortalChannelColumn}); + this._channelsDataGridView.DataSource = this._channelItemsBindingSource; + this._channelsDataGridView.GridColor = System.Drawing.Color.White; + this._channelsDataGridView.Location = new System.Drawing.Point(6, 30); + this._channelsDataGridView.MultiSelect = false; + this._channelsDataGridView.Name = "_channelsDataGridView"; + this._channelsDataGridView.ReadOnly = true; + this._channelsDataGridView.RowHeadersVisible = false; + dataGridViewCellStyle8.BackColor = System.Drawing.Color.White; + dataGridViewCellStyle8.ForeColor = System.Drawing.Color.Black; + dataGridViewCellStyle8.SelectionBackColor = System.Drawing.Color.Silver; + dataGridViewCellStyle8.SelectionForeColor = System.Drawing.Color.Black; + this._channelsDataGridView.RowsDefaultCellStyle = dataGridViewCellStyle8; + this._channelsDataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this._channelsDataGridView.Size = new System.Drawing.Size(575, 311); + this._channelsDataGridView.StandardTab = true; + this._channelsDataGridView.TabIndex = 1; + this._channelsDataGridView.DoubleClick += new System.EventHandler(this._channelsDataGridView_DoubleClick); + this._channelsDataGridView.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this._channelsDataGridView_CellFormatting); + this._channelsDataGridView.SelectionChanged += new System.EventHandler(this._channelsDataGridView_SelectionChanged); + // + // _tvSchedulerChannelColumn + // + this._tvSchedulerChannelColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this._tvSchedulerChannelColumn.DataPropertyName = "ChannelName"; + this._tvSchedulerChannelColumn.FillWeight = 30F; + this._tvSchedulerChannelColumn.HeaderText = "Name"; + this._tvSchedulerChannelColumn.Name = "_tvSchedulerChannelColumn"; + this._tvSchedulerChannelColumn.ReadOnly = true; + // + // _mediaPortalChannelColumn + // + this._mediaPortalChannelColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this._mediaPortalChannelColumn.DataPropertyName = "Message"; + this._mediaPortalChannelColumn.FillWeight = 70F; + this._mediaPortalChannelColumn.HeaderText = "Status"; + this._mediaPortalChannelColumn.Name = "_mediaPortalChannelColumn"; + this._mediaPortalChannelColumn.ReadOnly = true; + // + // _notConnectedPanel + // + this._notConnectedPanel.Controls.Add(this._notConnectedLabel); + this._notConnectedPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this._notConnectedPanel.Location = new System.Drawing.Point(3, 3); + this._notConnectedPanel.Name = "_notConnectedPanel"; + this._notConnectedPanel.Size = new System.Drawing.Size(586, 368); + this._notConnectedPanel.TabIndex = 1; + // + // _notConnectedLabel + // + this._notConnectedLabel.AutoSize = true; + this._notConnectedLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this._notConnectedLabel.ForeColor = System.Drawing.Color.Red; + this._notConnectedLabel.Location = new System.Drawing.Point(3, 3); + this._notConnectedLabel.Name = "_notConnectedLabel"; + this._notConnectedLabel.Size = new System.Drawing.Size(354, 13); + this._notConnectedLabel.TabIndex = 0; + this._notConnectedLabel.Text = "Not connected to For The Record, check server settings in Configuration."; + // + // _uncRecordingGroupBox + // + this._uncRecordingGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._uncRecordingGroupBox.Controls.Add(this._createUncShareButton); + this._uncRecordingGroupBox.Controls.Add(this._uncPathsDataGridView); + this._uncRecordingGroupBox.Location = new System.Drawing.Point(6, 6); + this._uncRecordingGroupBox.Name = "_uncRecordingGroupBox"; + this._uncRecordingGroupBox.Size = new System.Drawing.Size(580, 152); + this._uncRecordingGroupBox.TabIndex = 1; + this._uncRecordingGroupBox.TabStop = false; + this._uncRecordingGroupBox.Text = "UNC Recording Paths"; + // + // _createUncShareButton + // + this._createUncShareButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this._createUncShareButton.Location = new System.Drawing.Point(6, 123); + this._createUncShareButton.Name = "_createUncShareButton"; + this._createUncShareButton.Size = new System.Drawing.Size(100, 23); + this._createUncShareButton.TabIndex = 11; + this._createUncShareButton.Text = "Create Share"; + this._createUncShareButton.UseVisualStyleBackColor = true; + this._createUncShareButton.Click += new System.EventHandler(this._createUncShareButton_Click); + // + // _uncPathsDataGridView + // + this._uncPathsDataGridView.AllowUserToAddRows = false; + this._uncPathsDataGridView.AllowUserToDeleteRows = false; + this._uncPathsDataGridView.AllowUserToResizeRows = false; + dataGridViewCellStyle9.BackColor = System.Drawing.Color.WhiteSmoke; + dataGridViewCellStyle9.ForeColor = System.Drawing.Color.Black; + dataGridViewCellStyle9.SelectionBackColor = System.Drawing.Color.Silver; + dataGridViewCellStyle9.SelectionForeColor = System.Drawing.Color.Black; + this._uncPathsDataGridView.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle9; + this._uncPathsDataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._uncPathsDataGridView.AutoGenerateColumns = false; + this._uncPathsDataGridView.BackgroundColor = System.Drawing.Color.White; + this._uncPathsDataGridView.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None; + this._uncPathsDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing; + this._uncPathsDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.dataGridViewTextBoxColumn1, + this.dataGridViewTextBoxColumn2}); + this._uncPathsDataGridView.DataSource = this._uncPathsBindingSource; + this._uncPathsDataGridView.GridColor = System.Drawing.Color.White; + this._uncPathsDataGridView.Location = new System.Drawing.Point(6, 19); + this._uncPathsDataGridView.MultiSelect = false; + this._uncPathsDataGridView.Name = "_uncPathsDataGridView"; + this._uncPathsDataGridView.ReadOnly = true; + this._uncPathsDataGridView.RowHeadersVisible = false; + dataGridViewCellStyle10.BackColor = System.Drawing.Color.White; + dataGridViewCellStyle10.ForeColor = System.Drawing.Color.Black; + dataGridViewCellStyle10.SelectionBackColor = System.Drawing.Color.Silver; + dataGridViewCellStyle10.SelectionForeColor = System.Drawing.Color.Black; + this._uncPathsDataGridView.RowsDefaultCellStyle = dataGridViewCellStyle10; + this._uncPathsDataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this._uncPathsDataGridView.Size = new System.Drawing.Size(568, 100); + this._uncPathsDataGridView.StandardTab = true; + this._uncPathsDataGridView.TabIndex = 10; + this._uncPathsDataGridView.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this._uncPathsDataGridView_CellFormatting); + this._uncPathsDataGridView.SelectionChanged += new System.EventHandler(this._uncPathsDataGridView_SelectionChanged); + // + // dataGridViewTextBoxColumn1 + // + this.dataGridViewTextBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn1.DataPropertyName = "CardName"; + this.dataGridViewTextBoxColumn1.FillWeight = 30F; + this.dataGridViewTextBoxColumn1.HeaderText = "Card"; + this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; + this.dataGridViewTextBoxColumn1.ReadOnly = true; + // + // dataGridViewTextBoxColumn2 + // + this.dataGridViewTextBoxColumn2.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn2.DataPropertyName = "Message"; + this.dataGridViewTextBoxColumn2.FillWeight = 70F; + this.dataGridViewTextBoxColumn2.HeaderText = "Path"; + this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; + this.dataGridViewTextBoxColumn2.ReadOnly = true; + // + // _refreshUncButton + // + this._refreshUncButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this._refreshUncButton.Location = new System.Drawing.Point(511, 322); + this._refreshUncButton.Name = "_refreshUncButton"; + this._refreshUncButton.Size = new System.Drawing.Size(75, 23); + this._refreshUncButton.TabIndex = 12; + this._refreshUncButton.Text = "Refresh"; + this._refreshUncButton.UseVisualStyleBackColor = true; + this._refreshUncButton.Click += new System.EventHandler(this._refreshUncButton_Click); + // + // _syncTve3EpgcheckBox + // + this._syncTve3EpgcheckBox.AutoSize = true; + this._syncTve3EpgcheckBox.Location = new System.Drawing.Point(11, 18); + this._syncTve3EpgcheckBox.Name = "_syncTve3EpgcheckBox"; + this._syncTve3EpgcheckBox.Size = new System.Drawing.Size(441, 17); + this._syncTve3EpgcheckBox.TabIndex = 11; + this._syncTve3EpgcheckBox.Text = "Send EPG data to For The Record (don\'t forget to turn on grabbing on the channels" + + " too)"; + this._syncTve3EpgcheckBox.UseVisualStyleBackColor = true; + this._syncTve3EpgcheckBox.CheckedChanged += new System.EventHandler(this._syncTve3EpgcheckBox_CheckedChanged); + // + // _epgGroupBox + // + this._epgGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._epgGroupBox.Controls.Add(this._epgAutoCreateChannelsWithGroupRadioButton); + this._epgGroupBox.Controls.Add(this._epgAutoCreateChannelsDvbRadioButton); + this._epgGroupBox.Controls.Add(this._epgOnlyLinkedChannelsRadioButton); + this._epgGroupBox.Controls.Add(this._syncTve3EpgcheckBox); + this._epgGroupBox.Location = new System.Drawing.Point(6, 138); + this._epgGroupBox.Name = "_epgGroupBox"; + this._epgGroupBox.Size = new System.Drawing.Size(580, 116); + this._epgGroupBox.TabIndex = 2; + this._epgGroupBox.TabStop = false; + this._epgGroupBox.Text = "DVB-EPG"; + // + // _tabControl + // + this._tabControl.Controls.Add(this._configTabPage); + this._tabControl.Controls.Add(this._uncPathsTabPage); + this._tabControl.Controls.Add(this._channelsTabPage); + this._tabControl.Dock = System.Windows.Forms.DockStyle.Fill; + this._tabControl.Location = new System.Drawing.Point(0, 0); + this._tabControl.Name = "_tabControl"; + this._tabControl.SelectedIndex = 0; + this._tabControl.Size = new System.Drawing.Size(600, 400); + this._tabControl.TabIndex = 15; + this._tabControl.SelectedIndexChanged += new System.EventHandler(this._tabControl_SelectedIndexChanged); + // + // _configTabPage + // + this._configTabPage.Controls.Add(this._powerGroupBox); + this._configTabPage.Controls.Add(this._tvSchedulerGroupBox); + this._configTabPage.Controls.Add(this._epgGroupBox); + this._configTabPage.Location = new System.Drawing.Point(4, 22); + this._configTabPage.Name = "_configTabPage"; + this._configTabPage.Padding = new System.Windows.Forms.Padding(3); + this._configTabPage.Size = new System.Drawing.Size(592, 374); + this._configTabPage.TabIndex = 0; + this._configTabPage.Text = "Configuration"; + this._configTabPage.UseVisualStyleBackColor = true; + // + // _powerGroupBox + // + this._powerGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._powerGroupBox.Controls.Add(this._restartOnResumeCheckBox); + this._powerGroupBox.Location = new System.Drawing.Point(6, 88); + this._powerGroupBox.Name = "_powerGroupBox"; + this._powerGroupBox.Size = new System.Drawing.Size(580, 44); + this._powerGroupBox.TabIndex = 3; + this._powerGroupBox.TabStop = false; + this._powerGroupBox.Text = "Power Management"; + // + // _restartOnResumeCheckBox + // + this._restartOnResumeCheckBox.AutoSize = true; + this._restartOnResumeCheckBox.Location = new System.Drawing.Point(11, 18); + this._restartOnResumeCheckBox.Name = "_restartOnResumeCheckBox"; + this._restartOnResumeCheckBox.Size = new System.Drawing.Size(317, 17); + this._restartOnResumeCheckBox.TabIndex = 16; + this._restartOnResumeCheckBox.Text = "Re-initialize TV Server when the system resumes from standby"; + this._restartOnResumeCheckBox.UseVisualStyleBackColor = true; + // + // _uncPathsTabPage + // + this._uncPathsTabPage.Controls.Add(this._uncTimeshiftGroupBox); + this._uncPathsTabPage.Controls.Add(this._refreshUncButton); + this._uncPathsTabPage.Controls.Add(this._uncRecordingGroupBox); + this._uncPathsTabPage.Location = new System.Drawing.Point(4, 22); + this._uncPathsTabPage.Name = "_uncPathsTabPage"; + this._uncPathsTabPage.Size = new System.Drawing.Size(592, 374); + this._uncPathsTabPage.TabIndex = 2; + this._uncPathsTabPage.Text = "UNC Paths"; + this._uncPathsTabPage.UseVisualStyleBackColor = true; + // + // _uncTimeshiftGroupBox + // + this._uncTimeshiftGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._uncTimeshiftGroupBox.Controls.Add(this._createTimeshiftingShareButton); + this._uncTimeshiftGroupBox.Controls.Add(this._uncTimeshiftingDataGridView); + this._uncTimeshiftGroupBox.Location = new System.Drawing.Point(6, 164); + this._uncTimeshiftGroupBox.Name = "_uncTimeshiftGroupBox"; + this._uncTimeshiftGroupBox.Size = new System.Drawing.Size(580, 152); + this._uncTimeshiftGroupBox.TabIndex = 13; + this._uncTimeshiftGroupBox.TabStop = false; + this._uncTimeshiftGroupBox.Text = "UNC Timeshift Paths"; + // + // _createTimeshiftingShareButton + // + this._createTimeshiftingShareButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this._createTimeshiftingShareButton.Location = new System.Drawing.Point(6, 123); + this._createTimeshiftingShareButton.Name = "_createTimeshiftingShareButton"; + this._createTimeshiftingShareButton.Size = new System.Drawing.Size(100, 23); + this._createTimeshiftingShareButton.TabIndex = 11; + this._createTimeshiftingShareButton.Text = "Create Share"; + this._createTimeshiftingShareButton.UseVisualStyleBackColor = true; + this._createTimeshiftingShareButton.Click += new System.EventHandler(this._createTimeshiftingShareButton_Click); + // + // _uncTimeshiftingDataGridView + // + this._uncTimeshiftingDataGridView.AllowUserToAddRows = false; + this._uncTimeshiftingDataGridView.AllowUserToDeleteRows = false; + this._uncTimeshiftingDataGridView.AllowUserToResizeRows = false; + dataGridViewCellStyle11.BackColor = System.Drawing.Color.WhiteSmoke; + dataGridViewCellStyle11.ForeColor = System.Drawing.Color.Black; + dataGridViewCellStyle11.SelectionBackColor = System.Drawing.Color.Silver; + dataGridViewCellStyle11.SelectionForeColor = System.Drawing.Color.Black; + this._uncTimeshiftingDataGridView.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle11; + this._uncTimeshiftingDataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._uncTimeshiftingDataGridView.AutoGenerateColumns = false; + this._uncTimeshiftingDataGridView.BackgroundColor = System.Drawing.Color.White; + this._uncTimeshiftingDataGridView.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None; + this._uncTimeshiftingDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing; + this._uncTimeshiftingDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.dataGridViewTextBoxColumn3, + this.dataGridViewTextBoxColumn4}); + this._uncTimeshiftingDataGridView.DataSource = this._uncTimeshiftingBindingSource; + this._uncTimeshiftingDataGridView.GridColor = System.Drawing.Color.White; + this._uncTimeshiftingDataGridView.Location = new System.Drawing.Point(6, 19); + this._uncTimeshiftingDataGridView.MultiSelect = false; + this._uncTimeshiftingDataGridView.Name = "_uncTimeshiftingDataGridView"; + this._uncTimeshiftingDataGridView.ReadOnly = true; + this._uncTimeshiftingDataGridView.RowHeadersVisible = false; + dataGridViewCellStyle12.BackColor = System.Drawing.Color.White; + dataGridViewCellStyle12.ForeColor = System.Drawing.Color.Black; + dataGridViewCellStyle12.SelectionBackColor = System.Drawing.Color.Silver; + dataGridViewCellStyle12.SelectionForeColor = System.Drawing.Color.Black; + this._uncTimeshiftingDataGridView.RowsDefaultCellStyle = dataGridViewCellStyle12; + this._uncTimeshiftingDataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this._uncTimeshiftingDataGridView.Size = new System.Drawing.Size(568, 100); + this._uncTimeshiftingDataGridView.StandardTab = true; + this._uncTimeshiftingDataGridView.TabIndex = 10; + this._uncTimeshiftingDataGridView.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this._uncPathsDataGridView_CellFormatting); + this._uncTimeshiftingDataGridView.SelectionChanged += new System.EventHandler(this._uncTimeshiftingDataGridView_SelectionChanged); + // + // dataGridViewTextBoxColumn3 + // + this.dataGridViewTextBoxColumn3.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn3.DataPropertyName = "CardName"; + this.dataGridViewTextBoxColumn3.FillWeight = 30F; + this.dataGridViewTextBoxColumn3.HeaderText = "Card"; + this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; + this.dataGridViewTextBoxColumn3.ReadOnly = true; + // + // dataGridViewTextBoxColumn4 + // + this.dataGridViewTextBoxColumn4.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn4.DataPropertyName = "Message"; + this.dataGridViewTextBoxColumn4.FillWeight = 70F; + this.dataGridViewTextBoxColumn4.HeaderText = "Path"; + this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; + this.dataGridViewTextBoxColumn4.ReadOnly = true; + // + // _channelsTabPage + // + this._channelsTabPage.Controls.Add(this._channelsPanel); + this._channelsTabPage.Controls.Add(this._notConnectedPanel); + this._channelsTabPage.Location = new System.Drawing.Point(4, 22); + this._channelsTabPage.Name = "_channelsTabPage"; + this._channelsTabPage.Padding = new System.Windows.Forms.Padding(3); + this._channelsTabPage.Size = new System.Drawing.Size(592, 374); + this._channelsTabPage.TabIndex = 1; + this._channelsTabPage.Text = "Channels"; + this._channelsTabPage.UseVisualStyleBackColor = true; + // + // _epgOnlyLinkedChannelsRadioButton + // + this._epgOnlyLinkedChannelsRadioButton.AutoSize = true; + this._epgOnlyLinkedChannelsRadioButton.Location = new System.Drawing.Point(26, 41); + this._epgOnlyLinkedChannelsRadioButton.Name = "_epgOnlyLinkedChannelsRadioButton"; + this._epgOnlyLinkedChannelsRadioButton.Size = new System.Drawing.Size(227, 17); + this._epgOnlyLinkedChannelsRadioButton.TabIndex = 12; + this._epgOnlyLinkedChannelsRadioButton.TabStop = true; + this._epgOnlyLinkedChannelsRadioButton.Text = "Only process EPG data for linked channels"; + this._epgOnlyLinkedChannelsRadioButton.UseVisualStyleBackColor = true; + // + // _epgAutoCreateChannelsDvbRadioButton + // + this._epgAutoCreateChannelsDvbRadioButton.AutoSize = true; + this._epgAutoCreateChannelsDvbRadioButton.Location = new System.Drawing.Point(26, 64); + this._epgAutoCreateChannelsDvbRadioButton.Name = "_epgAutoCreateChannelsDvbRadioButton"; + this._epgAutoCreateChannelsDvbRadioButton.Size = new System.Drawing.Size(391, 17); + this._epgAutoCreateChannelsDvbRadioButton.TabIndex = 13; + this._epgAutoCreateChannelsDvbRadioButton.TabStop = true; + this._epgAutoCreateChannelsDvbRadioButton.Text = "Automatically create and link channels in For The Record (\"DVB-EPG\" group)"; + this._epgAutoCreateChannelsDvbRadioButton.UseVisualStyleBackColor = true; + // + // _epgAutoCreateChannelsWithGroupRadioButton + // + this._epgAutoCreateChannelsWithGroupRadioButton.AutoSize = true; + this._epgAutoCreateChannelsWithGroupRadioButton.Location = new System.Drawing.Point(26, 87); + this._epgAutoCreateChannelsWithGroupRadioButton.Name = "_epgAutoCreateChannelsWithGroupRadioButton"; + this._epgAutoCreateChannelsWithGroupRadioButton.Size = new System.Drawing.Size(436, 17); + this._epgAutoCreateChannelsWithGroupRadioButton.TabIndex = 14; + this._epgAutoCreateChannelsWithGroupRadioButton.TabStop = true; + this._epgAutoCreateChannelsWithGroupRadioButton.Text = "Automatically create and link channels in For The Record (duplicate MediaPortal g" + + "roup)"; + this._epgAutoCreateChannelsWithGroupRadioButton.UseVisualStyleBackColor = true; + // + // SetupForm + // + this.Controls.Add(this._tabControl); + this.Name = "SetupForm"; + this.Size = new System.Drawing.Size(600, 400); + this._tvSchedulerGroupBox.ResumeLayout(false); + this._tvSchedulerGroupBox.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this._portNumericUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this._pluginTcpNumericUpDown)).EndInit(); + this._channelsPanel.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this._channelsDataGridView)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this._channelItemsBindingSource)).EndInit(); + this._notConnectedPanel.ResumeLayout(false); + this._notConnectedPanel.PerformLayout(); + this._uncRecordingGroupBox.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this._uncPathsDataGridView)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this._uncPathsBindingSource)).EndInit(); + this._epgGroupBox.ResumeLayout(false); + this._epgGroupBox.PerformLayout(); + this._tabControl.ResumeLayout(false); + this._configTabPage.ResumeLayout(false); + this._powerGroupBox.ResumeLayout(false); + this._powerGroupBox.PerformLayout(); + this._uncPathsTabPage.ResumeLayout(false); + this._uncTimeshiftGroupBox.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this._uncTimeshiftingDataGridView)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this._uncTimeshiftingBindingSource)).EndInit(); + this._channelsTabPage.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox _tvSchedulerGroupBox; + private System.Windows.Forms.NumericUpDown _portNumericUpDown; + private System.Windows.Forms.Label _tcpPortLabel; + private System.Windows.Forms.TextBox _serverTextBox; + private System.Windows.Forms.Label _serverLabel; + private System.Windows.Forms.Button _connectButton; + private System.Windows.Forms.DataGridView _channelsDataGridView; + private System.Windows.Forms.Panel _notConnectedPanel; + private System.Windows.Forms.Panel _channelsPanel; + private System.Windows.Forms.Label _notConnectedLabel; + private System.Windows.Forms.BindingSource _channelItemsBindingSource; + private System.Windows.Forms.GroupBox _uncRecordingGroupBox; + private System.Windows.Forms.CheckBox _syncTve3EpgcheckBox; + private System.Windows.Forms.Button _refreshChannelsButton; + private System.Windows.Forms.DataGridViewTextBoxColumn _tvSchedulerChannelColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn _mediaPortalChannelColumn; + private System.Windows.Forms.NumericUpDown _pluginTcpNumericUpDown; + private System.Windows.Forms.Label _pluginTcpLabel; + private System.Windows.Forms.Label _restartTcpLabel; + private System.Windows.Forms.GroupBox _epgGroupBox; + private System.Windows.Forms.TabControl _tabControl; + private System.Windows.Forms.TabPage _configTabPage; + private System.Windows.Forms.TabPage _channelsTabPage; + private System.Windows.Forms.DataGridView _uncPathsDataGridView; + private System.Windows.Forms.Button _refreshUncButton; + private System.Windows.Forms.BindingSource _uncPathsBindingSource; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2; + private System.Windows.Forms.Button _createUncShareButton; + private System.Windows.Forms.GroupBox _powerGroupBox; + private System.Windows.Forms.CheckBox _restartOnResumeCheckBox; + private System.Windows.Forms.Button _linkChannelButton; + private System.Windows.Forms.TabPage _uncPathsTabPage; + private System.Windows.Forms.GroupBox _uncTimeshiftGroupBox; + private System.Windows.Forms.Button _createTimeshiftingShareButton; + private System.Windows.Forms.DataGridView _uncTimeshiftingDataGridView; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4; + private System.Windows.Forms.BindingSource _uncTimeshiftingBindingSource; + private System.Windows.Forms.ComboBox _channelTypeComboBox; + private System.Windows.Forms.Button _importChannelsButton; + private System.Windows.Forms.RadioButton _epgAutoCreateChannelsWithGroupRadioButton; + private System.Windows.Forms.RadioButton _epgAutoCreateChannelsDvbRadioButton; + private System.Windows.Forms.RadioButton _epgOnlyLinkedChannelsRadioButton; + } +} diff --git a/TVServerKodi/SetupForm.cs b/TVServerKodi/SetupForm.cs new file mode 100644 index 0000000..51313af --- /dev/null +++ b/TVServerKodi/SetupForm.cs @@ -0,0 +1,516 @@ +/* + * Copyright (C) 2007-2011 For The Record + * http://www.4therecord.eu + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Text; +using System.Windows.Forms; +using System.Collections; + +using TvLibrary.Log; +using TvEngine; +using TvControl; + +using ForTheRecord.ServiceAgents; +using ForTheRecord.Entities; +using ForTheRecord.RecorderTuners.Common; +using ForTheRecord.RecorderTuners.MediaPortalTvServer.Channels; +using ForTheRecord.RecorderTuners.MediaPortalTvServer.Wizards.ImportChannels; + +namespace ForTheRecord.RecorderTuners.MediaPortalTvServer +{ + public partial class SetupForm : SetupTv.SectionSettings + { + private TvSchedulerServiceAgent _tvSchedulerAgent; + + public SetupForm() + { + InitializeComponent(); + _uncPathsBindingSource.DataSource = typeof(List); + _channelItemsBindingSource.DataSource = typeof(List); + } + + #region Properties + + private TvServerPlugin _plugin; + + public TvServerPlugin Plugin + { + get { return _plugin; } + set { _plugin = value; } + } + + #endregion + + #region SetupTv.SectionSettings + + public override void OnSectionActivated() + { + Log.Info("ForTheRecord.RecorderTuners.MediaPortalTvServer: Configuration activated"); + + _plugin.LoadSettings(); + _serverTextBox.Text = _plugin.ServerSettings.ServerName; + _portNumericUpDown.Value = _plugin.ServerSettings.Port; + + _pluginTcpNumericUpDown.Value = _plugin.RecorderTunerTcpPort; + + _restartOnResumeCheckBox.Checked = _plugin.RestartTvServerOnResume; + + _syncTve3EpgcheckBox.Checked = _plugin.EpgSyncOn; + _syncTve3EpgcheckBox_CheckedChanged(this, EventArgs.Empty); + + if (_plugin.EpgSyncAutoCreateChannels) + { + _epgAutoCreateChannelsDvbRadioButton.Checked = true; + } + else if (_plugin.EpgSyncAutoCreateChannelsWithGroup) + { + _epgAutoCreateChannelsWithGroupRadioButton.Checked = true; + } + else + { + _epgOnlyLinkedChannelsRadioButton.Checked = true; + } + + ConnectToForTheRecord(); + + base.OnSectionActivated(); + } + + public override void OnSectionDeActivated() + { + Log.Info("ForTheRecord.RecorderTuners.MediaPortalTvServer: Configuration deactivated"); + + DisconnectFromForTheRecord(); + + _plugin.RestartTvServerOnResume = _restartOnResumeCheckBox.Checked; + + _plugin.EpgSyncOn = _syncTve3EpgcheckBox.Checked; + _plugin.EpgSyncAutoCreateChannels = _epgAutoCreateChannelsDvbRadioButton.Checked; + _plugin.EpgSyncAutoCreateChannelsWithGroup = _epgAutoCreateChannelsWithGroupRadioButton.Checked; + + _plugin.RecorderTunerTcpPort = (int)_pluginTcpNumericUpDown.Value; + + _plugin.ServerSettings.ServerName = _serverTextBox.Text.Trim(); + _plugin.ServerSettings.Port = (int)_portNumericUpDown.Value; + _plugin.SaveSettings(); + + base.OnSectionDeActivated(); + } + + #endregion + + private class UncPathItem + { + private string _cardName; + private string _recordingPath; + private string _message; + private bool _hasError; + + public UncPathItem(string cardName, string recordingPath, string message, bool hasError) + { + _cardName = cardName; + _recordingPath = recordingPath; + _message = message; + _hasError = hasError; + } + + public string CardName + { + get { return _cardName; } + } + + public string RecordingPath + { + get { return _recordingPath; } + } + + public string Message + { + get { return _message; } + } + + public bool HasError + { + get { return _hasError; } + } + } + + private class LinkedChannelItem + { + private Channel _channel; + private string _message; + private Color _rowColor; + + public LinkedChannelItem(Channel channel, string message, Color rowColor) + { + _channel = channel; + _message = message; + _rowColor = rowColor; + } + + public Channel Channel + { + get { return _channel; } + } + + public string ChannelName + { + get { return _channel.DisplayName; } + } + + public string Message + { + get { return _message; } + set { _message = value; } + } + + public Color RowColor + { + get { return _rowColor; } + set { _rowColor = value; } + } + } + + private void ConnectToForTheRecord() + { + DisconnectFromForTheRecord(); + + _plugin.InitializeTvSchedulerConnection(this); + _notConnectedPanel.Visible = !_plugin.IsForTheRecordConnectionInitialized; + _channelsPanel.Visible = _plugin.IsForTheRecordConnectionInitialized; + + LoadUncPaths(); + + if (_plugin.IsForTheRecordConnectionInitialized) + { + _tvSchedulerAgent = new TvSchedulerServiceAgent(); + } + } + + private void DisconnectFromForTheRecord() + { + if (_tvSchedulerAgent != null) + { + _tvSchedulerAgent.Dispose(); + } + } + + private void _connectButton_Click(object sender, EventArgs e) + { + _plugin.ServerSettings.ServerName = _serverTextBox.Text.Trim(); + _plugin.ServerSettings.Port = (int)_portNumericUpDown.Value; + ConnectToForTheRecord(); + } + + private void _channelTypeComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + LoadChannels(); + } + + private void _refreshButton_Click(object sender, EventArgs e) + { + LoadChannels(); + } + + private void _tabControl_SelectedIndexChanged(object sender, EventArgs e) + { + if (_tabControl.SelectedTab == _channelsTabPage + && _plugin.IsForTheRecordConnectionInitialized) + { + if (_channelTypeComboBox.SelectedIndex < 0) + { + _channelTypeComboBox.SelectedIndex = (int)ChannelType.Television; + } + } + } + + private void LoadUncPaths() + { + try + { + bool anyError = false; + + List pathItems = new List(); + List tsPathItems = new List(); + + List mediaPortalCards = Utility.GetAllCards(); + foreach (TvDatabase.Card card in mediaPortalCards) + { + anyError = anyError | AddUncPathItem(pathItems, card.Name, card.RecordingFolder); + anyError = anyError | AddUncPathItem(tsPathItems, card.Name, card.TimeShiftFolder); + } + + _uncPathsBindingSource.DataSource = pathItems; + _uncTimeshiftingBindingSource.DataSource = tsPathItems; + EnableUncButtons(); + + if (anyError) + { + MessageBox.Show(this, "You must set up a share with full permissions for the core" + Environment.NewLine + "services account for all recording folders!", null, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + catch (Exception ex) + { + MessageBox.Show(this, ex.Message, null, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private static bool AddUncPathItem(List pathItems, string name, string path) + { + bool hasError = true; + string message; + + string uncPath = ShareExplorer.GetUncPathForLocalPath(path); + if (!String.IsNullOrEmpty(uncPath)) + { + message = uncPath; + path = uncPath; + hasError = false; + } + else + { + message = path; + hasError = true; + } + + pathItems.Add(new UncPathItem(name, path, message, hasError)); + + return hasError; + } + + private void LoadChannels() + { + try + { + Cursor.Current = Cursors.WaitCursor; + + ChannelType channelType = (ChannelType)_channelTypeComboBox.SelectedIndex; + List channels = new List(_tvSchedulerAgent.GetAllChannels(channelType, false)); + + ChannelLinks.RemoveObsoleteLinks(channelType, channels); + + List channelItems = new List(); + + foreach (Channel channel in channels) + { + string message; + Color rowColor; + GetLinkedMessageAndColor(channel, out message, out rowColor); + channelItems.Add(new LinkedChannelItem(channel, message, rowColor)); + } + + _channelItemsBindingSource.DataSource = channelItems; + } + catch (Exception ex) + { + MessageBox.Show(this, ex.Message, null, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + Cursor.Current = Cursors.Default; + } + } + + private void _uncPathsDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) + { + DataGridView dataGridView = sender as DataGridView; + if (e.ColumnIndex == 1 + && e.RowIndex >= 0 + && e.RowIndex < _uncPathsBindingSource.Count) + { + UncPathItem linkItem = dataGridView.Rows[e.RowIndex].DataBoundItem as UncPathItem; + if (linkItem != null + && linkItem.HasError) + { + e.CellStyle.ForeColor = Color.Red; + e.CellStyle.SelectionForeColor = Color.Red; + } + else + { + e.CellStyle.ForeColor = Color.DarkGreen; + e.CellStyle.SelectionForeColor = Color.DarkGreen; + } + } + } + + private void _channelsDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) + { + if (e.ColumnIndex == 1 + && e.RowIndex >= 0 + && e.RowIndex < _channelItemsBindingSource.Count) + { + LinkedChannelItem linkItem = _channelsDataGridView.Rows[e.RowIndex].DataBoundItem as LinkedChannelItem; + if (linkItem != null) + { + e.CellStyle.ForeColor = linkItem.RowColor; + e.CellStyle.SelectionForeColor = linkItem.RowColor; + } + } + } + + private void EnableUncButtons() + { + if (_uncPathsDataGridView.SelectedRows.Count > 0) + { + UncPathItem linkItem = _uncPathsDataGridView.SelectedRows[0].DataBoundItem as UncPathItem; + _createUncShareButton.Enabled = linkItem.HasError; + } + else + { + _createUncShareButton.Enabled = false; + } + if (_uncTimeshiftingDataGridView.SelectedRows.Count > 0) + { + UncPathItem linkItem = _uncTimeshiftingDataGridView.SelectedRows[0].DataBoundItem as UncPathItem; + _createTimeshiftingShareButton.Enabled = linkItem.HasError; + } + else + { + _createTimeshiftingShareButton.Enabled = false; + } + } + + private void EnableChannelButtons() + { + _linkChannelButton.Enabled = (_channelsDataGridView.SelectedRows.Count == 1); + } + + private void _syncTve3EpgcheckBox_CheckedChanged(object sender, EventArgs e) + { + _epgOnlyLinkedChannelsRadioButton.Enabled = _syncTve3EpgcheckBox.Checked; + _epgAutoCreateChannelsDvbRadioButton.Enabled = _syncTve3EpgcheckBox.Checked; + _epgAutoCreateChannelsWithGroupRadioButton.Enabled = _syncTve3EpgcheckBox.Checked; + } + + private void _refreshUncButton_Click(object sender, EventArgs e) + { + LoadUncPaths(); + } + + private void _uncPathsDataGridView_SelectionChanged(object sender, EventArgs e) + { + EnableUncButtons(); + } + + private void _channelsDataGridView_SelectionChanged(object sender, EventArgs e) + { + EnableChannelButtons(); + } + + private void _linkChannelButton_Click(object sender, EventArgs e) + { + if (_channelsDataGridView.SelectedRows.Count > 0) + { + LinkedChannelItem linkItem = _channelsDataGridView.SelectedRows[0].DataBoundItem as LinkedChannelItem; + CreateChannelLinkForm form = new CreateChannelLinkForm(); + form.Channel = linkItem.Channel; + if (form.ShowDialog() == DialogResult.OK) + { + ChannelLinks.Save(); + string message; + Color rowColor; + GetLinkedMessageAndColor(linkItem.Channel, out message, out rowColor); + linkItem.Message = message; + linkItem.RowColor = rowColor; + _channelItemsBindingSource.ResetBindings(false); + } + } + } + + private void _channelsDataGridView_DoubleClick(object sender, EventArgs e) + { + _linkChannelButton_Click(this, EventArgs.Empty); + } + + private void GetLinkedMessageAndColor(Channel channel, out string message, out Color rowColor) + { + bool isAutoLinked; + bool duplicateChannelsFound; + LinkedMediaPortalChannel linkedChannel = + ChannelLinks.GetLinkedMediaPortalChannel(channel, out isAutoLinked, out duplicateChannelsFound); + if (duplicateChannelsFound) + { + message = "More than one channel found, change name or link manually"; + rowColor = Color.Red; + } + else if (linkedChannel == null) + { + message = "Channel not linked, change name or link manually"; + rowColor = Color.Red; + } + else if (isAutoLinked) + { + message = "Linked (auto)"; + rowColor = Color.Black; + } + else + { + message = "Linked to " + linkedChannel.DisplayName; + rowColor = Color.DarkGreen; + } + } + + private void _uncTimeshiftingDataGridView_SelectionChanged(object sender, EventArgs e) + { + EnableUncButtons(); + } + + private void _createUncShareButton_Click(object sender, EventArgs e) + { + if (_uncPathsDataGridView.SelectedRows.Count > 0) + { + ShowCreateShareForm(_uncPathsDataGridView.SelectedRows[0].DataBoundItem as UncPathItem); + } + } + + private void _createTimeshiftingShareButton_Click(object sender, EventArgs e) + { + if (_uncTimeshiftingDataGridView.SelectedRows.Count > 0) + { + ShowCreateShareForm(_uncTimeshiftingDataGridView.SelectedRows[0].DataBoundItem as UncPathItem); + } + } + + private void ShowCreateShareForm(UncPathItem linkItem) + { + CreateShareForm form = new CreateShareForm(); + form.LocalPath = linkItem.RecordingPath; + if (form.ShowDialog(this) == DialogResult.OK) + { + LoadUncPaths(); + } + } + + private void _importChannelsButton_Click(object sender, EventArgs e) + { + ImportChannelsWizard wizardForm = new ImportChannelsWizard((ChannelType)_channelTypeComboBox.SelectedIndex); + if (wizardForm.ShowDialog(this) == DialogResult.OK) + { + LoadChannels(); + } + } + } +} diff --git a/TVServerXBMC/TV/frmMain.resx b/TVServerKodi/SetupForm.resx similarity index 63% rename from TVServerXBMC/TV/frmMain.resx rename to TVServerKodi/SetupForm.resx index e73f340..059d0d0 100644 --- a/TVServerXBMC/TV/frmMain.resx +++ b/TVServerKodi/SetupForm.resx @@ -117,29 +117,14 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 17, 17 - - - 202, 17 - - - 95, 17 - - - 311, 17 - - + True - + True - - True - - - True + + 20, 16 True @@ -147,8 +132,8 @@ True - - True + + 228, 16 True @@ -156,37 +141,7 @@ True - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True + + 413, 16 \ No newline at end of file diff --git a/TVServerXBMC/TV/ServerInterface.cs b/TVServerKodi/TV/ServerInterface.cs similarity index 57% rename from TVServerXBMC/TV/ServerInterface.cs rename to TVServerKodi/TV/ServerInterface.cs index 719c0b2..fe3648d 100644 --- a/TVServerXBMC/TV/ServerInterface.cs +++ b/TVServerKodi/TV/ServerInterface.cs @@ -9,19 +9,16 @@ using TvDatabase; using TvLibrary.Log; -namespace MPTvClient +using TVServerKodi.Common; + +namespace TVServerKodi { public class TVServerController { - IList tvgroups = null; - IList channels = null; - IList tvmappings = null; - IList radiogroups = null; - IList radiomappings = null; - IList cards = null; IController controller = null; - User me = null; - Dictionary isTimeShifting = null; + + IUser me = null; + Dictionary isTimeShifting = null; public static Dictionary userlist = null; public Exception lastException = null; @@ -30,81 +27,25 @@ public class TVServerController public TVServerController(IController controller) { this.controller = controller; - this.isTimeShifting = new Dictionary(); + this.isTimeShifting = new Dictionary(); TVServerController.userlist = new Dictionary(); } public bool Setup() { - string connStr = ""; - string provider = ""; - - try - { - controller.GetDatabaseConnectionString(out connStr, out provider); - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: An exception occurred while connecting to the database. Did you select the right backend? TVServerXBMC default=MySQL; change your Gentle.conf file if you are using MSSQL."); - Log.Error("TVServerXBMC: The exception: " + ex.ToString()); - return false; - } - - Console.WriteLine(provider + ":" + connStr); - try { - Console.WriteLine("Set Gentle framework provider to " + provider); - Console.WriteLine("Set Gentle framework provider string to " + connStr); - Gentle.Framework.ProviderFactory.SetDefaultProvider(provider); - Gentle.Framework.ProviderFactory.SetDefaultProviderConnectionString(connStr); - Console.WriteLine("New TvControl Admin user"); - me = new User("TVServerXBMC", true); - } - catch (Exception ex) - { - try - { - Console.WriteLine(ex.ToString()); - } - catch {} - lastException = ex; - return false; - } - - try - { - Console.WriteLine("Fetch card list"); - cards = Card.ListAll(); - Console.Write("Fetch TV and radio channel list"); - channels = Channel.ListAll(); - Console.WriteLine(": " + channels.Count + " channels found"); - - // TV channel groups information: - Console.Write("Fetch TV groups list"); - tvgroups = ChannelGroup.ListAll(); - Console.WriteLine(": " + tvgroups.Count + " tvgroups found"); - Console.Write("Fetch TV group mappings"); - tvmappings = GroupMap.ListAll(); - Console.WriteLine(": " + tvmappings.Count + " tvmappings found"); - - // Radio channel groups information: - Console.Write("Fetch radio groups"); - radiogroups = RadioChannelGroup.ListAll(); - Console.WriteLine(": " + radiogroups.Count + " radiogroups found"); - Console.Write("Fetch radio group mappings"); - radiomappings = RadioGroupMap.ListAll(); - Console.WriteLine(": " + channels.Count + " radiomappings found"); + // Just to check our database connection: + IList tvgroups = ChannelGroup.ListAll(); } catch(Exception ex) { Console.WriteLine(ex.Message); - Log.Error("TVServerXBMC: An exception occurred during Setup(): " + ex.Message); + Log.Error("TVServerKodi: An exception occurred during Setup(): " + ex.Message); if (ex.Source == "Gentle.Common") { - Console.WriteLine("TVServerXBMC has problems connecting to the database. Check your settings (Gentle.config)"); - Log.Error("TVServerXBMC has problems connecting to the database. Check your settings"); + Console.WriteLine("TVServerKodi has problems connecting to the database. Check your settings (Gentle.config)"); + Log.Error("TVServerKodi has problems connecting to the database. Check your settings"); } return false; @@ -119,13 +60,15 @@ public void ResetConnection() #endregion #region Control functions - public TvResult StartTimeShifting(int idChannel, ref string rtspURL, ref string remoteserver, ref User user, ref string timeshiftfilename) + public TvResult StartTimeShifting(int idChannel, ref string rtspURL, ref string remoteserver, ref IUser user, ref string timeshiftfilename, ref Int64 timeShiftBufPos, ref long timeShiftBufNr) { VirtualCard vcard; //int cardId = -1; TvResult result; remoteserver = ""; - + timeShiftBufNr = 0; + timeShiftBufPos = 0; + System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); //cardId = user.CardId; @@ -135,7 +78,7 @@ public TvResult StartTimeShifting(int idChannel, ref string rtspURL, ref string try { Console.WriteLine("Start timeshift for channel " + idChannel + " for user '" + user.Name); - Log.Info("TVServerXBMC: Start timeshift for channel " + idChannel + " for user '" + user.Name); + Log.Info("TVServerKodi: Start timeshift for channel " + idChannel + " for user '" + user.Name); //result = controller.StartTimeShifting(ref user, idChannel, out vcard, cardId != -1); //This one is faster but we need to know the card id on beforehand result = controller.StartTimeShifting(ref user, idChannel, out vcard); @@ -159,26 +102,41 @@ public TvResult StartTimeShifting(int idChannel, ref string rtspURL, ref string try { - isTimeShifting.Add(user.Name, rtspURL); + isTimeShifting.Remove(user.Name); // Remove user with old timeshift data (on new channel tuning, without stopping the timeshift) + isTimeShifting.Add(user.Name, new TimeShiftURLs { RTSPUrl = rtspURL, TimeShiftFileName = timeshiftfilename }); } catch { } Console.WriteLine("Timeshift started for channel: '" + vcard.ChannelName + "' on device '" + vcard.Name + "' card id=" + vcard.Id); - Log.Debug("TVServerXBMC: Timeshift started for channel: '" + vcard.ChannelName + "' on device '" + vcard.Name + "'"); + Log.Debug("TVServerKodi: Timeshift started for channel: '" + vcard.ChannelName + "' on device '" + vcard.Name + "'"); Console.WriteLine("TV Server returned '" + rtspURL + "' as timeshift URL and " + timeshiftfilename + " as timeshift file"); - Log.Debug("TVServerXBMC: TV Server returned '" + rtspURL + "' as timeshift URL and " + timeshiftfilename + " as timeshift file"); + Log.Debug("TVServerKodi: TV Server returned '" + rtspURL + "' as timeshift URL and " + timeshiftfilename + " as timeshift file"); Console.WriteLine("Remote server='" + remoteserver + "'"); - Log.Debug("TVServerXBMC: Remote server='" + remoteserver + "'"); + Log.Debug("TVServerKodi: Remote server='" + remoteserver + "'"); //Console.WriteLine("Streaming server IP-address: " + GetRTSPserverIP()); + try { + //Fetch video stream information (takes approx 2-5 ms): + TvLibrary.Interfaces.IVideoStream videostream = vcard.GetCurrentVideoStream(TVServerController.userlist[user.Name]); + TvLibrary.Interfaces.VideoStreamType vidtype = videostream.StreamType; + Console.WriteLine("Video stream type=" + vidtype.ToString() + " Pid=" + videostream.Pid.ToString("X") + " PcrPid=" + videostream.PcrPid.ToString("X")); + + TvLibrary.Interfaces.IAudioStream audiostream = vcard.AudioStream; + TvLibrary.Interfaces.AudioStreamType audiotype = audiostream.StreamType; + Console.WriteLine("Audio stream type=" + audiotype.ToString() + " Pid=" + audiostream.Pid.ToString("X") + " Language=" + audiostream.Language); + } + catch { } + + controller.TimeShiftGetCurrentFilePosition(ref user, ref timeShiftBufPos, ref timeShiftBufNr); + Console.WriteLine("TimeShift file pos=" + timeShiftBufPos.ToString() + " buffer id=" + timeShiftBufNr.ToString()); } else if ((result == TvResult.NoTuningDetails) || (result== TvResult.UnknownError)) { //Hmmz, maybe a webstream? StopTimeShifting(ref user); Console.WriteLine("TV Server returned: 'NoTuningDetails' or 'UnknownError'."); Console.WriteLine("Checking the availability of a webstream for this channel (id=" + idChannel.ToString() + ")"); - Log.Debug("TVServerXBMC: TV Server returned: 'NoTuningDetails' or 'UnknownError'."); - Log.Debug("TVServerXBMC: Checking the availability of a webstream for this channel (id=" + idChannel.ToString() + ")"); + Log.Debug("TVServerKodi: TV Server returned: 'NoTuningDetails' or 'UnknownError'."); + Log.Debug("TVServerKodi: Checking the availability of a webstream for this channel (id=" + idChannel.ToString() + ")"); rtspURL = GetWebStreamURL(idChannel); @@ -186,41 +144,41 @@ public TvResult StartTimeShifting(int idChannel, ref string rtspURL, ref string { result = TvResult.Succeeded; Console.WriteLine("Found a webstream: '" + rtspURL + "'"); - Log.Debug("TVServerXBMC: Found a webstream: '" + rtspURL + "'"); + Log.Debug("TVServerKodi: Found a webstream: '" + rtspURL + "'"); } else { Console.WriteLine("Unable to find tuning details or a webstream for channel (id=" + idChannel + ")"); - Log.Debug("TVServerXBMC: Unable to find tuning details or a webstream for channel (id=" + idChannel + ")"); + Log.Debug("TVServerKodi: Unable to find tuning details or a webstream for channel (id=" + idChannel + ")"); } } else { StopTimeShifting(ref user); Console.WriteLine("Failed. TvResult = " + result.ToString()); - Log.Debug("TVServerXBMC: Failed. TvResult = " + result.ToString()); + Log.Debug("TVServerKodi: Failed. TvResult = " + result.ToString()); } watch.Stop(); Console.WriteLine("StartTimeShifting took " + watch.ElapsedMilliseconds.ToString() + " ms"); - Log.Debug("TVServerXBMC: StartTimeShifting took " + watch.ElapsedMilliseconds.ToString() + " ms"); + Log.Debug("TVServerKodi: StartTimeShifting took " + watch.ElapsedMilliseconds.ToString() + " ms"); return result; } - public string GetTimeshiftUrl(ref TvControl.User me) + public TimeShiftURLs GetTimeshiftURLs(ref TvControl.IUser me) { if (IsTimeShifting(ref me)) { - string url; - if ( isTimeShifting.TryGetValue(me.Name, out url) ) - return url; + TimeShiftURLs timeShiftURLs = new TimeShiftURLs(); + if (isTimeShifting.TryGetValue(me.Name, out timeShiftURLs)) + return timeShiftURLs; } - return ""; + return null; } - public bool IsTimeShifting(ref User user) + public bool IsTimeShifting(ref IUser user) { bool result = controller.IsTimeShifting(ref user); @@ -234,7 +192,8 @@ public bool IsTimeShifting(ref User user) { //Found one... user.CardId = ss.cardId; user.IdChannel = ss.channelId; - isTimeShifting.Add(user.Name, ss.RTSPUrl); + isTimeShifting.Remove(user.Name); // Make sure that the user is not in the dictionary + isTimeShifting.Add(user.Name, new TimeShiftURLs { RTSPUrl = ss.RTSPUrl, TimeShiftFileName = ss.TimeShiftFileName }); TVServerController.userlist[user.Name].CardId = ss.cardId; TVServerController.userlist[user.Name].IdChannel = ss.channelId; return true; @@ -245,7 +204,7 @@ public bool IsTimeShifting(ref User user) } // Stop the timeshift created by User user - public bool StopTimeShifting(ref User user) + public bool StopTimeShifting(ref IUser user) { if ( !IsTimeShifting(ref user) ) return false; @@ -264,11 +223,11 @@ public bool StopTimeShifting(ref User user) return result; } - // Stop all active timeshifts created by the TVServerXBMC plugin + // Stop all active timeshifts created by the TVServerKodi plugin public bool StopTimeShifting() { - Console.WriteLine("TODO: fixme StopTimeShifting() for all TVServerXBMC users"); - Log.Debug("TVServerXBMC: TODO: fixme StopTimeShifting()"); + Console.WriteLine("TODO: fixme StopTimeShifting() for all TVServerKodi users"); + Log.Debug("TVServerKodi: TODO: fixme StopTimeShifting()"); return true; } @@ -283,7 +242,7 @@ public string GetRecordingURL(int idRecording, TvServer server, bool resolveHost // we resolve any host names, as xbox can't do NETBIOS resolution.. try { - // XBMC's ffmpeg rtsp code does not like port numbers in the url + // XBMC/Kodi's ffmpeg rtsp code does not like port numbers in the url rtspURL = rtspURL.Replace(":554", ""); // Workaround for MP TVserver bug when using default port for rtsp => returns rtsp://ip:0 rtspURL = rtspURL.Replace(":0", ""); @@ -321,15 +280,15 @@ public string GetRecordingURL(int idRecording, TvServer server, bool resolveHost if (newHost.Length == 0) { Console.WriteLine("No IPv4 adress found for '" + u.DnsSafeHost + "' failed. Returning original URL."); - Log.Debug("TVServerXBMC: No IPv4 adress found for '" + u.DnsSafeHost + "' failed. Returning original URL."); + Log.Debug("TVServerKodi: No IPv4 adress found for '" + u.DnsSafeHost + "' failed. Returning original URL."); } } catch (Exception ex) { Console.WriteLine("IP resolve for '" + u.DnsSafeHost + "' failed."); Console.WriteLine("Error: " + ex.ToString()); - Log.Debug("TVServerXBMC: IP resolve for '" + u.DnsSafeHost + "' failed."); - Log.Debug("TVServerXBMC: Error: " + ex.ToString()); + Log.Debug("TVServerKodi: IP resolve for '" + u.DnsSafeHost + "' failed."); + Log.Debug("TVServerKodi: Error: " + ex.ToString()); } } } @@ -389,7 +348,7 @@ public bool StopRecording(int schedId) { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); } return result; } @@ -397,24 +356,21 @@ public bool StopRecording(int schedId) #endregion #region Info functions - public ReceptionDetails GetReceptionDetails() + public ReceptionDetails GetReceptionDetails(int cardID) { - VirtualCard vcard; - try - { - vcard = new VirtualCard(me, RemoteControl.HostName); - } - catch (Exception ex) - { - lastException = ex; - Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); - return null; - } - ReceptionDetails details = new ReceptionDetails(); - details.signalLevel = vcard.SignalLevel; - details.signalQuality = vcard.SignalQuality; - return details; + ReceptionDetails details = new ReceptionDetails(); + try + { + details.signalLevel = controller.SignalLevel(cardID); + details.signalQuality = controller.SignalQuality(cardID); + + } + catch + { + details.signalLevel = 0; + details.signalQuality = 0; + } + return details; } public string GetBackendName() @@ -428,11 +384,14 @@ public List GetStreamingStatus() VirtualCard vcard; try { + + IList cards = Card.ListAll(); + foreach (Card card in cards) { - User user = new User(); + IUser user = new User(); user.CardId = card.IdCard; - User[] usersForCard = controller.GetUsersForCard(card.IdCard); + IUser[] usersForCard = controller.GetUsersForCard(card.IdCard); if (usersForCard == null) { StreamingStatus state = new StreamingStatus(); @@ -498,7 +457,7 @@ public List GetStreamingStatus() { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } return states; @@ -510,14 +469,17 @@ public List GetGroupNames() List lGroups = new List(); try { - foreach (ChannelGroup group in tvgroups) - lGroups.Add(group.GroupName); + IList tvgroups = ChannelGroup.ListAll(); + foreach (ChannelGroup group in tvgroups) + { + lGroups.Add(group.GroupName); + } } catch (Exception ex) { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } return lGroups; @@ -530,14 +492,17 @@ public List GetRadioGroupNames() List lGroups = new List(); try { - foreach (RadioChannelGroup group in radiogroups) - lGroups.Add(group.GroupName); + IList radiogroups = RadioChannelGroup.ListAll(); + foreach (RadioChannelGroup group in radiogroups) + { + lGroups.Add(group.GroupName); + } } catch (Exception ex) { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } return lGroups; @@ -545,62 +510,79 @@ public List GetRadioGroupNames() public int GetChannelCount(String group) { + try + { + if (group == "" || group == null) { - return channels.Count; + IList channels = Channel.ListAll(); + return channels.Count; } else { - foreach (ChannelGroup chgroup in tvgroups) + IList tvgroups = ChannelGroup.ListAll(); + foreach (ChannelGroup chgroup in tvgroups) + { + if (chgroup.GroupName == group) { - if (chgroup.GroupName == group) - { - IList maps = chgroup.ReferringGroupMap(); - return maps.Count; - } + IList maps = chgroup.ReferringGroupMap(); + return maps.Count; } + } } - - return 0; + } + catch (Exception ex) + { + Log.Error("TVServerKodi: An exception occurred in GetChannelCount(): " + ex.Message); + } + return 0; } public ChannelInfo GetChannelInfo(int chanId) { + try + { + IList channels = Channel.ListAll(); foreach (Channel chan in channels) { - if (chan.IdChannel == chanId) - { - // this is the channel we want - ChannelInfo channelInfo = new ChannelInfo(); - TvDatabase.Program epg = null; + if (chan.IdChannel == chanId) + { + // this is the channel we want + ChannelInfo channelInfo = new ChannelInfo(); + TvDatabase.Program epg = null; - channelInfo.channelID = chan.IdChannel.ToString(); - channelInfo.name = chan.DisplayName; - channelInfo.isWebStream = chan.IsWebstream(); - channelInfo.epgNow = new ProgrammInfo(); - channelInfo.epgNext = new ProgrammInfo(); + channelInfo.channelID = chan.IdChannel.ToString(); + channelInfo.name = chan.DisplayName; + channelInfo.isWebStream = chan.IsWebstream(); + channelInfo.epgNow = new ProgrammInfo(); + channelInfo.epgNext = new ProgrammInfo(); - try - { - epg = chan.CurrentProgram; - if (epg != null) - { - channelInfo.epgNow.timeInfo = epg.StartTime.ToShortTimeString() + "-" + epg.EndTime.ToShortTimeString(); - channelInfo.epgNow.description = epg.Title; - } - epg = chan.NextProgram; - if (epg != null) - { - channelInfo.epgNext.timeInfo = epg.StartTime.ToShortTimeString() + "-" + epg.EndTime.ToShortTimeString(); - channelInfo.epgNext.description = epg.Title; - } - } - catch { } - - return channelInfo; + try + { + epg = chan.CurrentProgram; + if (epg != null) + { + channelInfo.epgNow.timeInfo = epg.StartTime.ToShortTimeString() + "-" + epg.EndTime.ToShortTimeString(); + channelInfo.epgNow.description = epg.Title; + } + epg = chan.NextProgram; + if (epg != null) + { + channelInfo.epgNext.timeInfo = epg.StartTime.ToShortTimeString() + "-" + epg.EndTime.ToShortTimeString(); + channelInfo.epgNext.description = epg.Title; + } } + catch { } + + return channelInfo; + } } - return null; + } + catch (Exception ex) + { + Log.Error("TVServerKodi: An exception occurred in GetChannelInfo(): " + ex.Message); + } + return null; } public List GetChannelInfosForGroup(string groupName) @@ -608,6 +590,7 @@ public List GetChannelInfosForGroup(string groupName) List refChannelInfos = new List(); try { + IList tvgroups = ChannelGroup.ListAll(); if (tvgroups != null) { foreach (ChannelGroup group in tvgroups) @@ -642,7 +625,7 @@ public List GetChannelInfosForGroup(string groupName) catch (Exception e) { Console.WriteLine("Error while obtaining the EPG for channel " + channelInfo.channelID + ": " + e.ToString()); - Log.Error("TVServerXBMC: Error while obtaining the EPG for channel " + channelInfo.channelID + ": " + e.ToString()); + Log.Error("TVServerKodi: Error while obtaining the EPG for channel " + channelInfo.channelID + ": " + e.ToString()); } //Get the tuning details @@ -671,76 +654,143 @@ public List GetChannelInfosForGroup(string groupName) { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } return refChannelInfos; } - public List GetTVChannels(string groupName) + public List GetTVChannels(List groupNames) { try { - if (tvgroups != null) - { - List tvchannels = new List(); + List tvchannels = new List(); + HashSet uniqueChannels = new HashSet(); - if (groupName.Length == 0) - groupName = "All Channels"; + if (groupNames.Count > 0) + { + IList tvGroups = ChannelGroup.ListAll(); - foreach (ChannelGroup group in tvgroups) + if (tvGroups != null) { - if (group.GroupName == groupName) + foreach (ChannelGroup group in tvGroups) { - IList maps = group.ReferringGroupMap(); - foreach (GroupMap map in maps) + if (groupNames.Contains(group.GroupName)) { - Channel chan = map.ReferencedChannel(); + IList maps = group.ReferringGroupMap(); + foreach (GroupMap map in maps) + { + Channel chan = map.ReferencedChannel(); - if (chan == null) continue; + if (chan == null) + continue; - string tvchannel; - int channelNumber = 0; + uniqueChannels.Add(chan); + } + } + } + } + else + { + Console.WriteLine("TVServerKodi: GetTVChannels: no tv groups?"); + Log.Error("TVServerKodi: GetTVChannels: no tv groups?"); + return null; + } + } + else + { + IList channels = Channel.ListAll(); - //Determine the channel number given by the provider using this channel's tuning details - IList tuningdetails = chan.ReferringTuningDetail(); + foreach (Channel chan in channels) + { + if (chan.IsTv) + uniqueChannels.Add(chan); + } + } - foreach (TuningDetail tuningdetail in tuningdetails) - { - //For now, just take the first one: - channelNumber = tuningdetail.ChannelNumber; - break; - } + foreach (Channel chan in uniqueChannels) + { + string tvchannel; + int channelNumber = 10000; + bool freetoair = false; + int majorChannel = -1; + int minorChannel = -1; - //XBMC side: - //uid, number, name, callsign, iconpath, isencrypted, - //isradio, ishidden, isrecording, bouquet, multifeed, - //stream_url; + try + { + channelNumber = chan.ChannelNumber; + } + catch + { + } - //[0] = channel uid - //[1] = channel number - //[2] = channel name - tvchannel = chan.IdChannel + "|" + channelNumber + "|" + chan.DisplayName + "|"; - //[3] = isencrypted - tvchannel += (chan.FreeToAir ? "0" : "1"); + //Determine the channel number given by the provider using this channel's tuning details + IList tuningdetails = chan.ReferringTuningDetail(); - tvchannels.Add(tvchannel); + try + { + foreach (TuningDetail tuningdetail in tuningdetails) + { + freetoair = freetoair || tuningdetail.FreeToAir; + if (tuningdetail.ChannelType == 1) // ATSC + { + if (tuningdetail.MajorChannel != -1) + majorChannel = tuningdetail.MajorChannel; + if (tuningdetail.MinorChannel != -1) + minorChannel = tuningdetail.MinorChannel; + } + if ((channelNumber == 10000) && (tuningdetail.ChannelNumber > 0)) + { + channelNumber = tuningdetail.ChannelNumber; + break; } } } + catch + { + } - return tvchannels; + //Kodi side: + //uid, number, name, callsign, iconpath, isencrypted, + //isradio, ishidden, isrecording, bouquet, multifeed, + //stream_url; + + //[0] = channel uid + //[1] = channel number + //[2] = channel name + tvchannel = chan.IdChannel + "|" + channelNumber + "|" + chan.DisplayName + "|"; + //[3] = isencrypted + tvchannel += (freetoair ? "0" : "1"); + //[4] = iswebstream + //[5] = webstream url + if (chan.IsWebstream()) + { + tvchannel += "|1|"; + Channel webChannel = chan; + tvchannel += GetWebStreamURL(ref webChannel) + "|"; + } + else + { + tvchannel += "|0||"; + } + //[6] = visibleinguide + tvchannel += (chan.VisibleInGuide ? "1" : "0") + "|"; + //[7] = ATSC majorchannel + //[8] = ATSC minorchannel + tvchannel += majorChannel + "|" + minorChannel; + + tvchannels.Add(tvchannel); } - return null; + + return tvchannels; } catch (Exception ex) { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } - } public List getRadioChannels(string groupName) @@ -751,6 +801,8 @@ public List getRadioChannels(string groupName) if (groupName == "") { TvDatabase.Program epg; + + IList channels = Channel.ListAll(); foreach (Channel chan in channels) { if (!chan.IsRadio) @@ -778,6 +830,7 @@ public List getRadioChannels(string groupName) } else { + IList radiogroups = RadioChannelGroup.ListAll(); foreach (RadioChannelGroup group in radiogroups) { if (group.GroupName == groupName) @@ -818,80 +871,138 @@ public List getRadioChannels(string groupName) { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } return radioChannels; } - public List GetRadioChannels(string groupName) + public List GetRadioChannels(List groupNames) { try { - if (radiogroups != null) - { - List radiochannels = new List(); + List radiochannels = new List(); + HashSet uniqueChannels = new HashSet(); - if (groupName.Length == 0) - groupName = "All Channels"; + if (groupNames.Count > 0) + { + IList radioGroups = RadioChannelGroup.ListAll(); - foreach (RadioChannelGroup group in radiogroups) + if (radioGroups != null) { - if (group.GroupName == groupName) + foreach (RadioChannelGroup group in radioGroups) { - IList maps = group.ReferringRadioGroupMap(); - foreach (RadioGroupMap map in maps) + if (groupNames.Contains(group.GroupName)) { - Channel chan = map.ReferencedChannel(); - - if (chan == null) continue; - string radiochannel; - int channelNumber = 0; + IList maps = group.ReferringRadioGroupMap(); + foreach (RadioGroupMap map in maps) + { + Channel chan = map.ReferencedChannel(); - //Determine the channel number given by the provider using this channel's tuning details - IList tuningdetails = chan.ReferringTuningDetail(); + if (chan == null) + continue; - foreach (TuningDetail tuningdetail in tuningdetails) - { - //For now, just take the first one: - channelNumber = tuningdetail.ChannelNumber; - break; + uniqueChannels.Add(chan); } + } + } + } + else + { + Console.WriteLine("TVServerKodi: GetRadioChannels: no radio groups?"); + Log.Error("TVServerKodi: GetRadioChannels: no radio groups?"); + return null; + } + } + else + { + IList channels = Channel.ListAll(); - //[0] = channel uid - //[1] = channel number - //[2] = channel name - radiochannel = chan.IdChannel + "|" + channelNumber + "|" + chan.DisplayName + "|"; - //[3] = isencrypted - radiochannel += (chan.FreeToAir ? "0" : "1"); - //[4] = iswebstream - //[5] = webstream url - if (chan.IsWebstream()) - { - radiochannel += "|1|"; - radiochannel += GetWebStreamURL(ref chan); - } - else - { - radiochannel += "|0|"; - } + foreach (Channel chan in channels) + { + if (chan.IsRadio) + uniqueChannels.Add(chan); + } + } - radiochannels.Add(radiochannel); + foreach (Channel chan in uniqueChannels) + { + string radiochannel; + int channelNumber = 10000; + bool freetoair = false; + int majorChannel = -1; + int minorChannel = -1; + try + { + channelNumber = chan.ChannelNumber; + } + catch + { + } + + try + { + //Determine the channel number given by the provider using this channel's tuning details + IList tuningdetails = chan.ReferringTuningDetail(); + + foreach (TuningDetail tuningdetail in tuningdetails) + { + freetoair = freetoair || tuningdetail.FreeToAir; + if (tuningdetail.ChannelType == 1) // ATSC + { + if (tuningdetail.MajorChannel != -1) + majorChannel = tuningdetail.MajorChannel; + if (tuningdetail.MinorChannel != -1) + minorChannel = tuningdetail.MinorChannel; + } + if ((channelNumber == 10000) && (tuningdetail.ChannelNumber > 0)) + { + channelNumber = tuningdetail.ChannelNumber; + break; } } } + catch + { + } - return radiochannels; + //XBMC side: + //[0] = channel uid + //[1] = channel number + //[2] = channel name + radiochannel = chan.IdChannel + "|" + channelNumber + "|" + chan.DisplayName + "|"; + //[3] = isencrypted + radiochannel += (freetoair ? "0" : "1"); + //[4] = iswebstream + //[5] = webstream url + if (chan.IsWebstream()) + { + radiochannel += "|1|"; + Channel webChannel = chan; + radiochannel += GetWebStreamURL(ref webChannel) + "|"; + } + else + { + radiochannel += "|0||"; + } + //[6] = visibleinguide + radiochannel += (chan.VisibleInGuide ? "1" : "0") + "|"; + //[7] = ATSC majorchannel + //[8] = ATSC minorchannel + radiochannel += majorChannel + "|" + minorChannel; + + radiochannels.Add(radiochannel); } - return null; + + return radiochannels; } catch (Exception ex) { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } } @@ -955,7 +1066,7 @@ public List getRecordings() { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } return recInfos; @@ -971,76 +1082,89 @@ public List GetRecordings(bool resolveHostnames, ref string OriginalURL) foreach (Recording rec in recordings) { - string recording; - string channelname; - string rtspURL = GetRecordingURL(rec.IdRecording, server, resolveHostnames, ref OriginalURL);//server.GetStreamUrlForFileName(rec.IdRecording); - - //XBMC pvr side: - //index, channelname, lifetime, priority, start time, duration - //title, subtitle, description, stream_url, directory - - //[0] index / mediaportal recording id - //[1] start time - //[2] end time - //[3] channel name - //[4] title - //[5] description - //[6] stream_url (resolved hostname if resolveHostnames = True) - //[7] filename (we can bypass rtsp streaming when XBMC and the TV server are on the same machine) - //[8] keepUntilDate (DateTime) - //[9] original unresolved stream_url if resolveHostnames = True, otherwise this field is missing - //[10] episodeName (string) - //[11] seriesNumber (string) - //[12] episodeNumber (string) - //[13] episodePart (string) - //[14] scheduleID (int) - //[15] keepUntil (int) - //[16] keepUntilDate (DateTime) - try { - channelname = rec.ReferencedChannel().DisplayName; - } - catch - { // Occurs for example when a recording is pointing to a channel - // that is deleted in the meantime - channelname = rec.IdChannel.ToString(); - } - - recording = rec.IdRecording.ToString() + "|" // 0 - + rec.StartTime.ToString("u") + "|" // 1 - + rec.EndTime.ToString("u") + "|" // 2 - + channelname.Replace("|", "") + "|" // 3 - + rec.Title.Replace("|","") + "|" // 4 - + rec.Description.Replace("|", "") + "|" // 5 - + rtspURL + "|" // 6 - + rec.FileName + "|" // 7 - + rec.KeepUntilDate.ToString("u") + "|"; // 8 - - if (resolveHostnames) - { - recording += OriginalURL + "|"; // 9 - } - else - { - recording += rtspURL + "|"; - } + string recording; + string channelname; + string rtspURL = GetRecordingURL(rec.IdRecording, server, resolveHostnames, ref OriginalURL);//server.GetStreamUrlForFileName(rec.IdRecording); + + //XBMC pvr side: + //index, channelname, lifetime, priority, start time, duration + //title, subtitle, description, stream_url, directory + + //[0] index / mediaportal recording id + //[1] start time + //[2] end time + //[3] channel name + //[4] title + //[5] description + //[6] stream_url (resolved hostname if resolveHostnames = True) + //[7] filename (we can bypass rtsp streaming when XBMC and the TV server are on the same machine) + //[8] keepUntilDate (DateTime) + //[9] original unresolved stream_url if resolveHostnames = True, otherwise this field is missing + //[10] keepUntil (int) + //[11] episodeName (string) + //[12] episodeNumber (string) + //[13] episodePart (string) + //[14] seriesNumber (string) + //[15] scheduleID (int) + //[16] Genre (string) + //[17] channel id (int) + //[18] isrecording (bool) + //[19] timesWatched (int) + //[20] stopTime (int) - recording += rec.KeepUntil.ToString() + "|" // 10 - + rec.EpisodeName.Replace("|", "") + "|" // 11 - + rec.EpisodeNum + "|" // 12 - + rec.EpisodePart + "|" // 13 - + rec.SeriesNum + "|" // 14 - + rec.Idschedule.ToString(); // 15 + try + { + channelname = rec.ReferencedChannel().DisplayName; + } + catch + { // Occurs for example when a recording is pointing to a channel + // that is deleted in the meantime + channelname = rec.IdChannel.ToString(); + } + recording = rec.IdRecording.ToString() + "|" // 0 + + rec.StartTime.ToString("u") + "|" // 1 + + rec.EndTime.ToString("u") + "|" // 2 + + channelname.Replace("|", "") + "|" // 3 + + rec.Title.Replace("|", "") + "|" // 4 + + rec.Description.Replace("|", "") + "|" // 5 + + rtspURL + "|" // 6 + + rec.FileName + "|" // 7 + + rec.KeepUntilDate.ToString("u") + "|"; // 8 + + if (resolveHostnames) + { + recording += OriginalURL + "|"; // 9 + } + else + { + recording += rtspURL + "|"; + } - reclist.Add(recording); + recording += rec.KeepUntil.ToString() + "|" // 10 + + rec.EpisodeName.Replace("|", "") + "|" // 11 + + rec.EpisodeNum + "|" // 12 + + rec.EpisodePart + "|" // 13 + + rec.SeriesNum + "|" // 14 + + rec.Idschedule.ToString() + "|" // 15 + + rec.Genre + "|" // 16 + + rec.IdChannel.ToString() + "|" // 17 + + rec.IsRecording.ToString() + "|" // 18 + + rec.TimesWatched.ToString() + "|" // 19 + + rec.StopTime.ToString(); // 20 + + reclist.Add(recording); + } + catch (Exception) + { } } } catch (Exception ex) { lastException = ex; Console.Write("Exception in GetRecordings() " + ex.Message); - Log.Debug("TVServerXBMC: Exception in GetRecordings() " + ex.Message); + Log.Debug("TVServerKodi: Exception in GetRecordings() " + ex.Message); return null; } return reclist; @@ -1073,7 +1197,7 @@ public List GetRecordedTV() { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } return recInfos; @@ -1135,7 +1259,7 @@ public String GetRecordingInfo(int recId, bool withRTSPurl) { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return result; } return result; @@ -1161,7 +1285,7 @@ public List getSchedules() sched.startTime = schedule.StartTime; sched.endTime = schedule.EndTime; sched.channelID = schedule.IdChannel; - sched.channelName = schedule.ReferencedChannel().Name; + sched.channelName = schedule.ReferencedChannel().DisplayName; sched.description = schedule.ProgramName; ScheduleRecordingType stype = (ScheduleRecordingType)schedule.ScheduleType; sched.type = stype.ToString(); @@ -1175,13 +1299,43 @@ public List getSchedules() { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } return schedInfos; } + private string FormatSchedule(string strSchedId, string strStartTime, string strEndTime, + string strIdChannel, string strchannelname, string strProgramName, Schedule sched, + string strIsRecording, string stridProgram, DateTime Canceled, int iParentSchedule, + string strGenre, string strProgramDescription) + { + string schedule; + schedule = strSchedId + "|" + + strStartTime + "|" + + strEndTime + "|" + + strIdChannel + "|" + + strchannelname + "|" + + strProgramName + "|" + + sched.ScheduleType.ToString() + "|" + + sched.Priority.ToString() + "|" + + sched.IsDone().ToString() + "|" + + sched.IsManual.ToString() + "|" + + sched.Directory + "|" + + sched.KeepMethod.ToString() + "|" + + sched.KeepDate.ToString("u") + "|" + + sched.PreRecordInterval.ToString() + "|" + + sched.PostRecordInterval.ToString() + "|" + + Canceled.ToString("u") + "|" + + sched.Series.ToString() + "|" + + strIsRecording + "|" + + stridProgram + "|" + + iParentSchedule.ToString() + "|" + + strGenre + "|" + + strProgramDescription; + return schedule; + } - public List GetSchedules() + public List GetSchedules(bool kodiHasSeriesSupport = false) { List schedlist = new List(); try @@ -1191,6 +1345,16 @@ public List GetSchedules() { String schedule; String channelname; + String strIsRecording = "False"; + String strStartTime; + String strEndTime; + String strSchedId; + String strIdChannel; + String strProgramName; + int idProgram = 0; + + if (sched.IdParentSchedule != -1) //If it has a parent it's a recording of a series we won't use this. + continue; //XBMC pvr side: // @@ -1212,6 +1376,10 @@ public List GetSchedules() //[15] canceled //[16] series //[17] isrecording (TODO) + //[18] idProgram + //[19] parent schedule id + //[20] genre of the program + //[21] program description try { channelname = sched.ReferencedChannel().DisplayName; @@ -1222,33 +1390,95 @@ public List GetSchedules() channelname = sched.IdChannel.ToString(); } - schedule = sched.IdSchedule.ToString() + "|" - + sched.StartTime.ToString("u") + "|" - + sched.EndTime.ToString("u") + "|" - + sched.IdChannel.ToString() + "|" - + channelname.Replace("|", "") + "|" - + sched.ProgramName.Replace("|", "") + "|" - + sched.ScheduleType.ToString() + "|" - + sched.Priority.ToString() + "|" - + sched.IsDone().ToString() + "|" - + sched.IsManual.ToString() + "|" - + sched.Directory + "|" - + sched.KeepMethod.ToString() + "|" - + sched.KeepDate.ToString("u") + "|" - + sched.PreRecordInterval.ToString() + "|" - + sched.PreRecordInterval.ToString() + "|" - + sched.Canceled.ToString("u") + "|" - + sched.Series.ToString() + "|" - + "False"; + try + { + strSchedId = sched.IdSchedule.ToString(); + strStartTime = sched.StartTime.ToString("u"); + strEndTime = sched.EndTime.ToString("u"); + strIdChannel = sched.IdChannel.ToString(); + strProgramName = sched.ProgramName; + + IList progs = Schedule.GetProgramsForSchedule(sched); + IList canceled_progs = sched.ReferringCanceledSchedule(); + + if (kodiHasSeriesSupport == true && sched.ScheduleType != 0 /* Once */) + { + // return also the real schedule and not only the underlying programs + schedule = FormatSchedule(strSchedId, strStartTime, strEndTime, strIdChannel, channelname.Replace("|", ""), + strProgramName.Replace("|", ""), sched, strIsRecording, idProgram.ToString(), sched.Canceled, sched.IdParentSchedule, "", ""); + schedlist.Add(schedule); + } + + foreach (Program pr in progs) + { + DateTime dtCanceled = sched.Canceled; + int parentSchedule; + + if (kodiHasSeriesSupport && sched.ScheduleType != 0 /* Once */) + { + // add the programs for this schedule as sub-timers in Kodi + parentSchedule = sched.IdSchedule; + } + else + { + parentSchedule = sched.IdParentSchedule; + } + + strStartTime = pr.StartTime.ToString("u"); + strEndTime = pr.EndTime.ToString("u"); + strIdChannel = pr.IdChannel.ToString(); + strProgramName = pr.Title; + if (pr.EpisodeName.Length > 0) + strProgramName += " - " + pr.EpisodeName; + if (pr.IsRecording) + strIsRecording = "True"; + else strIsRecording = "False"; + idProgram = pr.IdProgram; + + // Check if this program is in the CanceledSchedule list + foreach (CanceledSchedule cs in canceled_progs) + { + if (cs.CancelDateTime == pr.StartTime) + { + dtCanceled = cs.CancelDateTime; + break; + } + } + + schedule = FormatSchedule(strSchedId, strStartTime, strEndTime, strIdChannel, channelname.Replace("|", ""), + strProgramName.Replace("|", ""), sched, strIsRecording, idProgram.ToString(), dtCanceled, parentSchedule, pr.Genre, pr.Description); + schedlist.Add(schedule); + } + + if (progs.Count == 0) + { + if ((ScheduleRecordingType)sched.ScheduleType != (ScheduleRecordingType.Once)) + { + continue; //This timer does not resolve to a program. Do not return it until we have a state for it in XBMC. + } + else //If the schedule did not resolve to any program, typical when creating an Instant Recording from XBMC and the name does not match a program name. + { + VirtualCard card; + TvControl.TvServer tv = new TvServer(); + if (tv.IsRecordingSchedule(sched.IdSchedule, out card)) + strIsRecording = "True"; + idProgram = -1; + schedule = FormatSchedule(strSchedId, strStartTime, strEndTime, strIdChannel, channelname.Replace("|", ""), + strProgramName.Replace("|", ""), sched, strIsRecording, idProgram.ToString(), sched.Canceled, sched.IdParentSchedule, "", ""); + schedlist.Add(schedule); + } + } + } + catch + { } - schedlist.Add(schedule); } } catch (Exception ex) { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); return null; } return schedlist; @@ -1299,14 +1529,14 @@ public String GetScheduleInfo(int index) else { Console.Write("Error retrieving Schedule info for schedule id=%i.", index); - Log.Error("TVServerXBMC: Error retrieving Schedule info for schedule id=%i.", index); + Log.Error("TVServerKodi: Error retrieving Schedule info for schedule id=%i.", index); } } catch (Exception ex) { lastException = ex; Console.WriteLine(ex.ToString()); - Log.Error("TVServerXBMC: " + ex.ToString()); + Log.Error("TVServerKodi: " + ex.ToString()); } return schedInfo; } @@ -1314,7 +1544,14 @@ public String GetScheduleInfo(int index) private string GetDateTimeString() { string provider = Gentle.Framework.ProviderFactory.GetDefaultProvider().Name.ToLower(); - if (provider == "mysql") return "yyyy-MM-dd HH:mm:ss"; + switch (provider) + { + case "mysql": + case "sqlite": + return "yyyy-MM-dd HH:mm:ss"; + default: + break; + } return "yyyyMMdd HH:mm:ss"; } public List GetEPGForChannel(string idChannel, DateTime startTime, DateTime endTime) @@ -1347,7 +1584,7 @@ public List GetEPGForChannel(string idChannel, DateTime startTime, Date catch(Exception e) { Console.WriteLine("Error while obtaining the EPG for channel " + idChannel + ": " + e.Message); - Log.Debug("TVServerXBMC: Error while obtaining the EPG for channel " + idChannel + ": " + e.Message); + Log.Debug("TVServerKodi: Error while obtaining the EPG for channel " + idChannel + ": " + e.Message); } return null; } @@ -1405,7 +1642,7 @@ public bool AddSchedule(int channelId, String programName, DateTime startTime, D } } - public bool UpdateSchedule(int scheduleindex, int channelId, int active, String programName, DateTime startTime, DateTime endTime, int scheduleType, Int32 priority, Int32 keepmethod, DateTime keepdate, Int32 preRecordInterval, Int32 postRecordInterval) + public bool UpdateSchedule(int scheduleindex, int channelId, int active, String programName, DateTime startTime, DateTime endTime, int scheduleType, Int32 priority, Int32 keepmethod, DateTime keepdate, Int32 preRecordInterval, Int32 postRecordInterval, Int32 programId) { try { @@ -1413,6 +1650,58 @@ public bool UpdateSchedule(int scheduleindex, int channelId, int active, String Schedule updatedSchedule = Schedule.Retrieve(scheduleindex); DateTime defaultCanceled = new DateTime(2000, 01, 01, 0, 0, 0); //Active + // Note that Kodi 16.x returns once for a program below a series schedule... + if ((programId != -1) && (scheduleType != (int)TvDatabase.ScheduleRecordingType.Once || updatedSchedule.ScheduleType != (int)TvDatabase.ScheduleRecordingType.Once)) + { + // Series schedule, retrieve the canceled programs list + Program program = Program.Retrieve(programId); + + //program. + + IList canceledSched = updatedSchedule.ReferringCanceledSchedule(); + + if (active == 1) + { + // Check if this schedule is deactivated and remove it from the CanceledSchedule list + foreach (CanceledSchedule cs in canceledSched) + { + if (cs.CancelDateTime == program.StartTime) + { + cs.Remove(); + break; + } + } + } + else + { + Boolean found = false; + // Add this schedule to the CanceledSchedule list if not already in the list + foreach (CanceledSchedule cs in canceledSched) + { + if (cs.CancelDateTime == program.StartTime) + { + found = true; + break; + } + } + + if (!found) + { + CanceledSchedule newCs = new CanceledSchedule(scheduleindex, program.IdChannel, program.StartTime); + newCs.Persist(); + } + } + + // if (!found) + // { + // Program.ProgramState + // } + //} + return true; + } + + + updatedSchedule.ProgramName = programName; updatedSchedule.StartTime = startTime; updatedSchedule.EndTime = endTime; @@ -1483,6 +1772,60 @@ public bool UpdateRecording(int recordingindex, String recordingName) } } + public bool SetRecordingTimesWatched(int recordingindex, int timesWatched) + { + try + { + Recording recording = Recording.Retrieve(recordingindex); + + if (recording.TimesWatched < timesWatched) + recording.TimesWatched = timesWatched; + else + { + // some other client already updated the counter, so just do a +1 here + recording.TimesWatched++; + } + recording.Persist(); + + return true; + } + catch + { + return false; + } + } + + public int GetRecordingStopTime(int recordingindex) + { + try + { + Recording recording = Recording.Retrieve(recordingindex); + + return recording.StopTime; + } + catch + { + return -1; + } + } + + public bool SetRecordingStopTime(int recordingindex, int stopTime) + { + try + { + Recording recording = Recording.Retrieve(recordingindex); + + recording.StopTime = stopTime; + recording.Persist(); + + return true; + } + catch + { + return false; + } + } + public TvControl.User RequestUser(string username) { // Re-use an existing TvControl.User with the same name, @@ -1499,36 +1842,46 @@ public TvControl.User RequestUser(string username) public string GetRecordingDriveSpace() { string result = "0|0"; + Int32 disktotal = 0; + Int32 diskused = 0; + List processedDrives = new List(); try { TvBusinessLayer layer = new TvBusinessLayer(); //Int32.Parse(layer.GetSetting("preRecordInterval", "5").Value); + IList cards = Card.ListAll(); + + System.IO.DriveInfo[] local_allDrives = System.IO.DriveInfo.GetDrives(); foreach (Card card in cards) { - Int32 disktotal = 0; - Int32 diskused = 0; - - string rec_drive = card.RecordingFolder.Substring(0, 3); - System.IO.DriveInfo[] local_allDrives = System.IO.DriveInfo.GetDrives(); - foreach (System.IO.DriveInfo local_Drive in local_allDrives) + if (card.RecordingFolder.Length > 0) { - if (local_Drive.Name == rec_drive) + string rec_drive = card.RecordingFolder.Substring(0, 3); + + if (!processedDrives.Exists(drive => drive == rec_drive)) { - disktotal = (Int32) (local_Drive.TotalSize / (1024)); // in kb - diskused = (Int32)((local_Drive.TotalSize-local_Drive.TotalFreeSpace) / (1024)); // in kb + foreach (System.IO.DriveInfo local_Drive in local_allDrives) + { + if (local_Drive.Name == rec_drive) + { + processedDrives.Add(rec_drive); + disktotal += (Int32)(local_Drive.TotalSize / (1024)); // in kb + diskused += (Int32)((local_Drive.TotalSize - local_Drive.TotalFreeSpace) / (1024)); // in kb + break; + } + } } } - - result = disktotal.ToString() + "|" + diskused.ToString(); } + result = disktotal.ToString() + "|" + diskused.ToString(); } catch (Exception e) { Console.WriteLine("Error while obtaining the GetRecordingDriveSpace: " + e.Message); - Log.Debug("TVServerXBMC: Error while obtaining the GetRecordingDriveSpace: " + e.Message); + Log.Debug("TVServerKodi: Error while obtaining the GetRecordingDriveSpace: " + e.Message); } return result; @@ -1540,49 +1893,64 @@ public List GetCardSettings(int cardID) List cardSettingsList = new List(); try { + IList cards = Card.ListAll(); + foreach (Card card in cards) { if ((cardID == -1) || (cardID == card.IdCard)) { - result = card.IdCard.ToString() + "|" - + card.DevicePath + "|" - + card.Name + "|" - + card.Priority.ToString() + "|" - + card.GrabEPG.ToString() + "|" - + card.LastEpgGrab.ToString("u") + "|" - + card.RecordingFolder + "|" - + card.IdServer.ToString() + "|" - + card.Enabled.ToString() + "|" - + card.CamType.ToString() + "|" - + card.TimeShiftFolder.ToString() + "|" - + card.RecordingFormat.ToString() + "|" - + card.DecryptLimit.ToString() + "|" - + card.PreloadCard.ToString() + "|" - + card.CAM.ToString() + "|" - + card.netProvider.ToString() + "|" - + ""; // card.StopGraph.ToString() for version 1.2.x - cardSettingsList.Add(result); + try + { + result = card.IdCard.ToString() + "|" + + card.DevicePath.Replace('|', ' ') + "|" + + card.Name.Replace('|',' ') + "|" + + card.Priority.ToString() + "|" + + card.GrabEPG.ToString() + "|" + + card.LastEpgGrab.ToString("u") + "|" + + card.RecordingFolder + "|" + + card.IdServer.ToString() + "|" + + card.Enabled.ToString() + "|" + + card.CamType.ToString() + "|" + + card.TimeShiftFolder.ToString() + "|" + + card.RecordingFormat.ToString() + "|" + + card.DecryptLimit.ToString() + "|" + + card.PreloadCard.ToString() + "|" + + card.CAM.ToString() + "|" + + card.netProvider.ToString() + "|" + + card.StopGraph.ToString() + "|" + + ShareExplorer.GetUncPathForLocalPath(card.RecordingFolder) + "|" + + ShareExplorer.GetUncPathForLocalPath(card.TimeShiftFolder); + cardSettingsList.Add(result); + } + catch (Exception e) + { + Console.WriteLine("GetCardSettings: " + e.Message); + Log.Debug("TVServerKodi: Error while obtaining the GetCardSettings for card '" + card.Name + "': " + e.Message); + } } } } catch (Exception e) { Console.WriteLine("GetCardSettings: " + e.Message); - Log.Debug("TVServerXBMC: Error while obtaining the GetCardSettings: " + e.Message); + Log.Debug("TVServerKodi: Error while obtaining the GetCardSettings: " + e.Message); } return cardSettingsList; } - public int GetSignalQuality(int cardID) + public void HeartBeat(IUser user) { - return controller.SignalLevel(cardID); + try + { + RemoteControl.Instance.HeartBeat(user); + } + catch (Exception e) + { + Log.Error("TVServerKodi: failed sending HeartBeat signal to server. ({0})", e.Message); + } } - public int GetSignalLevel(int cardID) - { - return controller.SignalLevel(cardID); - } #endregion } } diff --git a/TVServerKodi/TV/Utility.cs b/TVServerKodi/TV/Utility.cs new file mode 100644 index 0000000..f44dfbf --- /dev/null +++ b/TVServerKodi/TV/Utility.cs @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2010-2012 Marcel Groothuis + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; +using System.Management; +using System.Security.Principal; + +using TvDatabase; + +namespace TVServerKodi +{ + internal static class Utility + { + public static List GetAllCards() + { + List cards = new List(); + IList mediaPortalCards = TvDatabase.Card.ListAll(); + foreach (TvDatabase.Card card in mediaPortalCards) + { + if (card.Enabled + && !card.DevicePath.Equals("(builtin)", StringComparison.CurrentCultureIgnoreCase)) + { + cards.Add(card); + } + } + return cards; + } + + public static bool CreateUncShare(string shareName, string localPath) + { + ManagementScope scope = new System.Management.ManagementScope(@"root\CIMV2"); + scope.Connect(); + + using (ManagementClass managementClass = new ManagementClass(scope, new ManagementPath("Win32_Share"), (ObjectGetOptions) null)) + { + SecurityIdentifier securityIdentifier = new SecurityIdentifier(WellKnownSidType.WorldSid, (SecurityIdentifier) null); + byte[] binaryForm = new byte[securityIdentifier.BinaryLength]; + securityIdentifier.GetBinaryForm(binaryForm, 0); + + using (ManagementObject wmiTrustee = new ManagementClass(scope, new ManagementPath("Win32_Trustee"), (ObjectGetOptions) null).CreateInstance()) + { + wmiTrustee["SID"] = (object) binaryForm; + using (ManagementObject wmiACE = new ManagementClass(scope, new ManagementPath("Win32_ACE"), (ObjectGetOptions) null).CreateInstance()) + { + wmiACE["AccessMask"] = 131241; //READ_CONTROL | FILE_READ | FILE_TRAVERSE | FILE_READ_EA | FILE_LIST_DIRECTORY + wmiACE["AceFlags"] = 3; //OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE + wmiACE["AceType"] = 0; //ACCESS_ALLOWED + wmiACE["Trustee"] = wmiTrustee; + using (ManagementObject wmiSecurityDescriptor = new ManagementClass(scope, new ManagementPath("Win32_SecurityDescriptor"), (ObjectGetOptions) null).CreateInstance()) + { + wmiSecurityDescriptor["ControlFlags"] = 4; + wmiSecurityDescriptor["DACL"] = new ManagementObject[] { wmiACE }; + using (ManagementBaseObject inParamsCreate = managementClass.GetMethodParameters("Create")) + { + inParamsCreate["Access"] = wmiSecurityDescriptor; + inParamsCreate["Path"] = localPath; + inParamsCreate["Name"] = shareName; + inParamsCreate["Type"] = 0; + inParamsCreate["Description"] = "TVServerXBMC share"; + using (ManagementBaseObject outParams = managementClass.InvokeMethod("Create", inParamsCreate, (InvokeMethodOptions) null)) + return ((int) (uint) outParams["returnValue"] == 0); + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/TVServerXBMC/TV/Utils.cs b/TVServerKodi/TV/Utils.cs similarity index 94% rename from TVServerXBMC/TV/Utils.cs rename to TVServerKodi/TV/Utils.cs index d00eb09..f3b174c 100644 --- a/TVServerXBMC/TV/Utils.cs +++ b/TVServerKodi/TV/Utils.cs @@ -3,7 +3,7 @@ using System.Text; using Microsoft.Win32; -namespace MPTvClient +namespace TVServerKodi { public class ReceptionDetails { @@ -22,6 +22,11 @@ public class StreamingStatus public string TimeShiftFileName; public string userName; } + public class TimeShiftURLs + { + public string RTSPUrl; + public string TimeShiftFileName; + } public class ProgrammInfo { public string timeInfo; diff --git a/TVServerXBMC/TVServerConnection.cs b/TVServerKodi/TVServerConnection.cs similarity index 83% rename from TVServerXBMC/TVServerConnection.cs rename to TVServerKodi/TVServerConnection.cs index 6777746..d67bf46 100644 --- a/TVServerXBMC/TVServerConnection.cs +++ b/TVServerKodi/TVServerConnection.cs @@ -1,13 +1,13 @@ using System; using System.Collections.Generic; using System.Text; -using MPTvClient; +using TVServerKodi; using TvControl; using System.Net; using TvLibrary.Log; using TvDatabase; -namespace TVServerXBMC +namespace TVServerKodi { class TVServerConnection { @@ -77,15 +77,15 @@ public static List getChannels(String group) return refChannelInfos; } - public static List GetTVChannels(String group) + public static List GetTVChannels(List groups) { - List result = serverIntf.GetTVChannels(group); + List result = serverIntf.GetTVChannels(groups); return result; } - public static List GetRadioChannels(String group) + public static List GetRadioChannels(List groups) { - List result = serverIntf.GetRadioChannels(group); + List result = serverIntf.GetRadioChannels(groups); return result; } @@ -146,6 +146,21 @@ public static string getRecordingInfo(int recordingId, bool withRTSPurl) return serverIntf.GetRecordingInfo(recordingId, withRTSPurl); } + public static bool SetRecordingTimesWatched(int recordingId, int timesWatched) + { + return serverIntf.SetRecordingTimesWatched(recordingId, timesWatched); + } + + public static int GetRecordingStopTime(int recordingId) + { + return serverIntf.GetRecordingStopTime(recordingId); + } + + public static bool SetRecordingStopTime(int recordingId, int stopTime) + { + return serverIntf.SetRecordingStopTime(recordingId, stopTime); + } + // get the amount of schedules recordings public static int getScheduleCount() { @@ -159,9 +174,9 @@ public static List getSchedules() return schedules; } - public static List GetSchedules() + public static List GetSchedules(bool seriesSupport = false) { - return serverIntf.GetSchedules(); + return serverIntf.GetSchedules(seriesSupport); } public static String GetScheduleInfo(int index) @@ -179,7 +194,7 @@ public static bool DeleteSchedule(int schedId) * \param OriginalURL is the URL given to us by the TVServer * \return value is the URL with resolved hostnames, */ - public static String playChannel(int chanId, bool resolveHostnames, ref string OriginalURL, ref TvControl.User me, ref string timeShiftFileName) + public static String playChannel(int chanId, bool resolveHostnames, ref string OriginalURL, ref TvControl.IUser me, ref string timeShiftFileName, ref Int64 timeShiftBufPos, ref long timeShiftBufNr) { string rtspURL = ""; string remoteserver = ""; @@ -187,7 +202,7 @@ public static String playChannel(int chanId, bool resolveHostnames, ref string O //serverIntf.StopTimeShifting(ref me); timeshiftChannel.Remove(me.Name); - TvResult result = serverIntf.StartTimeShifting(chanId, ref rtspURL, ref remoteserver, ref me, ref timeShiftFileName); + TvResult result = serverIntf.StartTimeShifting(chanId, ref rtspURL, ref remoteserver, ref me, ref timeShiftFileName, ref timeShiftBufPos, ref timeShiftBufNr); if (result != TvResult.Succeeded) { @@ -235,7 +250,7 @@ public static String playChannel(int chanId, bool resolveHostnames, ref string O if (newHost.Length == 0) { - Log.Debug("TVServerXBMC: No IPv4 adress found for '" + u.DnsSafeHost + "' failed. Returning original URL."); + Log.Debug("TVServerKodi: No IPv4 adress found for '" + u.DnsSafeHost + "' failed. Returning original URL."); Console.WriteLine("No IPv4 adress found for '" + u.DnsSafeHost + "' failed. Returning original URL."); } } @@ -243,8 +258,8 @@ public static String playChannel(int chanId, bool resolveHostnames, ref string O { Console.WriteLine("IP resolve for '" + u.DnsSafeHost + "' failed."); Console.WriteLine("Error: " + ex.ToString()); - Log.Debug("TVServerXBMC: IP resolve for '" + u.DnsSafeHost + "' failed."); - Log.Debug("TVServerXBMC: Error: " + ex.ToString()); + Log.Debug("TVServerKodi: IP resolve for '" + u.DnsSafeHost + "' failed."); + Log.Debug("TVServerKodi: Error: " + ex.ToString()); } } } @@ -260,7 +275,7 @@ public static String playChannel(int chanId, bool resolveHostnames, ref string O } - Log.Debug("TVServerXBMC: PlayChannel " + chanId.ToString() + " => URL=" + rtspURL); + Log.Debug("TVServerKodi: PlayChannel " + chanId.ToString() + " => URL=" + rtspURL); //Console.WriteLine("PlayChannel result : " + rtspURL); return rtspURL; } @@ -271,19 +286,19 @@ public static List getEpg(int chanId, DateTime startTime, DateTime endT return epgs; } - public static bool StopTimeshift(ref TvControl.User me) + public static bool StopTimeshift(ref TvControl.IUser me) { bool result = serverIntf.StopTimeShifting(ref me); timeshiftUrl = null; return result; } - public static string getTimeshiftUrl(ref TvControl.User me) + public static TimeShiftURLs getTimeshiftURLs(ref TvControl.IUser me) { - return serverIntf.GetTimeshiftUrl(ref me); + return serverIntf.GetTimeshiftURLs(ref me); } - public static ChannelInfo getTimeshiftInfo(ref TvControl.User me) + public static ChannelInfo getTimeshiftInfo(ref TvControl.IUser me) { int channelnr = 0; if (timeshiftChannel.TryGetValue(me.Name, out channelnr) ) @@ -296,7 +311,11 @@ public static ChannelInfo getTimeshiftInfo(ref TvControl.User me) return null; } - + + public static List getTimeshiftingUserNames() + { + return new List(timeshiftChannel.Keys); + } public static bool DeleteRecordedTV(int recId) { @@ -316,9 +335,9 @@ public static bool AddSchedule(int channelId, String programName, DateTime start return serverIntf.AddSchedule(channelId, programName, startTime, endTime, scheduleType, priority, keepmethod, keepdate, preRecordInterval, postRecordInterval); } - public static bool UpdateSchedule(int scheduleindex, int channelId, int active, String programName, DateTime startTime, DateTime endTime, int scheduleType, Int32 priority, Int32 keepmethod, DateTime keepdate, Int32 preRecordInterval, Int32 postRecordInterval) + public static bool UpdateSchedule(int scheduleindex, int channelId, int active, String programName, DateTime startTime, DateTime endTime, int scheduleType, Int32 priority, Int32 keepmethod, DateTime keepdate, Int32 preRecordInterval, Int32 postRecordInterval, Int32 program_id) { - return serverIntf.UpdateSchedule(scheduleindex, channelId, active, programName, startTime, endTime, scheduleType, priority, keepmethod, keepdate, preRecordInterval, postRecordInterval); + return serverIntf.UpdateSchedule(scheduleindex, channelId, active, programName, startTime, endTime, scheduleType, priority, keepmethod, keepdate, preRecordInterval, postRecordInterval, program_id); } public static void disconnect() @@ -353,5 +372,19 @@ public static TVServerController GetServerInterface() { return serverIntf; } + + public static string GetLogoPath(Boolean bIsRadio) + { + if (bIsRadio) + { + return String.Format(@"{0}\Team MediaPortal\MediaPortal\thumbs\Radio\", + System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData)); + } + else + { + return String.Format(@"{0}\Team MediaPortal\MediaPortal\thumbs\TV\Logos\", + System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData)); + } + } } } diff --git a/TVServerXBMC/TVServerXBMC.csproj b/TVServerKodi/TVServerKodi.csproj similarity index 66% rename from TVServerXBMC/TVServerXBMC.csproj rename to TVServerKodi/TVServerKodi.csproj index 818013b..789d183 100644 --- a/TVServerXBMC/TVServerXBMC.csproj +++ b/TVServerKodi/TVServerKodi.csproj @@ -1,21 +1,39 @@ - + + Debug AnyCPU 9.0.30729 2.0 {CE292E6A-53E2-459D-8C87-673073182152} - Exe + Library Properties - TVServerXBMC - TVServerXBMC + TVServerKodi + TVServerKodi - 2.0 + 3.5 + v4.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true true @@ -26,6 +44,7 @@ prompt 4 x86 + AllRules.ruleset pdbonly @@ -35,11 +54,16 @@ prompt 4 x86 + AllRules.ruleset + + + + @@ -72,6 +96,21 @@ + + + + + Form + + + CreateShareForm.cs + + + UserControl + + + SetupForm.cs + @@ -79,26 +118,22 @@ - - Form - - - frmMain.cs - + + Always - - frmMain.cs - Designer - + + False + References\Common.Utils.dll + False References\Gentle.Common.dll @@ -111,6 +146,9 @@ False References\Gentle.Provider.MySQL.dll + + References\Gentle.Provider.SQLite.dll + False References\Gentle.Provider.SQLServer.dll @@ -127,16 +165,20 @@ False References\PluginBase.dll - - False - References\PowerScheduler.Interfaces.dll - False References\SetupControls.dll + + 3.5 + + + + + + False References\TvBusinessLayer.dll @@ -158,6 +200,31 @@ References\TvLibrary.Interfaces.dll + + + CreateShareForm.cs + + + SetupForm.cs + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + +