Moved the http server to it's own assembly. added comments and made other minor re-organizations.

This commit is contained in:
LukePulverenti Luke Pulverenti luke pulverenti
2012-07-19 22:22:44 -04:00
parent 6fbd5cf464
commit 80b3ad7bd2
67 changed files with 806 additions and 964 deletions

View File

@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Model.Entities;
using System.IO;
using System.Linq;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Events
{
/// <summary>
/// This is an EventArgs object used when resolving a Path into a BaseItem
/// </summary>
public class ItemResolveEventArgs : PreBeginResolveEventArgs
{
public IEnumerable<KeyValuePair<string, FileAttributes>> FileSystemChildren { get; set; }
@@ -57,6 +59,11 @@ namespace MediaBrowser.Controller.Events
}
}
/// <summary>
/// This is an EventArgs object used before we begin resolving a Path into a BaseItem
/// File system children have not been collected yet, but consuming events will
/// have a chance to cancel resolution based on the Path, Parent and FileAttributes
/// </summary>
public class PreBeginResolveEventArgs : EventArgs
{
public string Path { get; set; }

View File

@@ -24,9 +24,9 @@ namespace MediaBrowser.Controller.IO
pathsToWatch.Add(rootFolder.Path);
foreach (Folder folder in rootFolder.FolderChildren)
foreach (Folder folder in rootFolder.Children.OfType<Folder>())
{
foreach (Folder subFolder in folder.FolderChildren)
foreach (Folder subFolder in folder.Children.OfType<Folder>())
{
if (Path.IsPathRooted(subFolder.Path))
{

View File

@@ -5,6 +5,9 @@ using System.Text;
namespace MediaBrowser.Controller.IO
{
/// <summary>
/// Contains helpers to interact with shortcut files (.lnk)
/// </summary>
public static class Shortcut
{
#region Signitures were imported from http://pinvoke.net

View File

@@ -7,7 +7,6 @@ using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Common.Json;
using MediaBrowser.Common.Logging;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.IO;
@@ -16,6 +15,7 @@ using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Users;
using MediaBrowser.Net;
namespace MediaBrowser.Controller
{
@@ -79,7 +79,7 @@ namespace MediaBrowser.Controller
ReloadHttpServer();
ReloadPlugins();
LoadPlugins();
// Get users from users folder
// Load root media folder
@@ -94,7 +94,7 @@ namespace MediaBrowser.Controller
Logger.LoggerInstance.LogSeverity = Configuration.LogSeverity;
}
private void ReloadPlugins()
private void LoadPlugins()
{
// Find plugins
Plugins = PluginController.GetAllPlugins();
@@ -261,7 +261,7 @@ namespace MediaBrowser.Controller
/// </summary>
public IEnumerable<BaseItem> GetParentalAllowedChildren(Folder folder, Guid userId)
{
return folder.Children.ToList().Where(i => IsParentalAllowed(i, userId));
return folder.Children.Where(i => IsParentalAllowed(i, userId));
}
/// <summary>
@@ -307,7 +307,7 @@ namespace MediaBrowser.Controller
{
DateTime now = DateTime.Now;
return GetParentalAllowedRecursiveChildren(parent, userId).Where(i => (now - i.DateCreated).TotalDays < Configuration.RecentItemDays);
return GetParentalAllowedRecursiveChildren(parent, userId).Where(i => !(i is Folder) && (now - i.DateCreated).TotalDays < Configuration.RecentItemDays);
}
/// <summary>
@@ -330,6 +330,11 @@ namespace MediaBrowser.Controller
{
return GetParentalAllowedRecursiveChildren(parent, userId).Where(i =>
{
if (i is Folder)
{
return false;
}
var userdata = GetUserItemData(userId, i.Id);
return userdata != null && userdata.PlaybackPosition.Ticks > 0;
@@ -359,5 +364,116 @@ namespace MediaBrowser.Controller
{
return GetParentalAllowedRecursiveChildren(parent, userId).Where(f => f.People != null && f.People.Any(s => s.Name.Equals(personName, StringComparison.OrdinalIgnoreCase)));
}
/// <summary>
/// Gets all studios from all recursive children of a folder
/// The CategoryInfo class is used to keep track of the number of times each studio appears
/// </summary>
public IEnumerable<CategoryInfo> GetAllStudios(Folder parent, Guid userId)
{
Dictionary<string, int> data = new Dictionary<string, int>();
// Get all the allowed recursive children
IEnumerable<BaseItem> allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId);
foreach (var item in allItems)
{
// Add each studio from the item to the data dictionary
// If the studio already exists, increment the count
if (item.Studios == null)
{
continue;
}
foreach (string val in item.Studios)
{
if (!data.ContainsKey(val))
{
data.Add(val, 1);
}
else
{
data[val]++;
}
}
}
// Now go through the dictionary and create a Category for each studio
List<CategoryInfo> list = new List<CategoryInfo>();
foreach (string key in data.Keys)
{
// Get the original entity so that we can also supply the PrimaryImagePath
Studio entity = Kernel.Instance.ItemController.GetStudio(key);
if (entity != null)
{
list.Add(new CategoryInfo()
{
Name = entity.Name,
ItemCount = data[key],
PrimaryImagePath = entity.PrimaryImagePath
});
}
}
return list;
}
/// <summary>
/// Gets all genres from all recursive children of a folder
/// The CategoryInfo class is used to keep track of the number of times each genres appears
/// </summary>
public IEnumerable<CategoryInfo> GetAllGenres(Folder parent, Guid userId)
{
Dictionary<string, int> data = new Dictionary<string, int>();
// Get all the allowed recursive children
IEnumerable<BaseItem> allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId);
foreach (var item in allItems)
{
// Add each genre from the item to the data dictionary
// If the genre already exists, increment the count
if (item.Genres == null)
{
continue;
}
foreach (string val in item.Genres)
{
if (!data.ContainsKey(val))
{
data.Add(val, 1);
}
else
{
data[val]++;
}
}
}
// Now go through the dictionary and create a Category for each genre
List<CategoryInfo> list = new List<CategoryInfo>();
foreach (string key in data.Keys)
{
// Get the original entity so that we can also supply the PrimaryImagePath
Genre entity = Kernel.Instance.ItemController.GetGenre(key);
if (entity != null)
{
list.Add(new CategoryInfo()
{
Name = entity.Name,
ItemCount = data[key],
PrimaryImagePath = entity.PrimaryImagePath
});
}
}
return list;
}
}
}

View File

@@ -323,6 +323,12 @@ namespace MediaBrowser.Controller.Library
return null;
}
public Genre GetGenre(string name)
{
// not yet implemented
return null;
}
public Year GetYear(int value)
{
// not yet implemented

View File

@@ -66,6 +66,10 @@
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Net\MediaBrowser.Net.csproj">
<Project>{5da08d1c-0d52-4b1b-aa66-e4a171d938f6}</Project>
<Name>MediaBrowser.Net</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View File

@@ -8,6 +8,8 @@ namespace MediaBrowser.Controller.Resolvers
{
protected override Audio Resolve(ItemResolveEventArgs args)
{
// Return audio if the path is a file and has a matching extension
if (!args.IsFolder)
{
if (IsAudioFile(args.Path))

View File

@@ -15,6 +15,9 @@ namespace MediaBrowser.Controller.Resolvers
return null;
}
/// <summary>
/// Sets initial values on the newly resolved item
/// </summary>
protected virtual void SetItemValues(T item, ItemResolveEventArgs args)
{
// If the subclass didn't specify this
@@ -23,6 +26,7 @@ namespace MediaBrowser.Controller.Resolvers
item.Path = args.Path;
}
// If the subclass didn't specify this
if (args.Parent != null)
{
item.Parent = args.Parent;
@@ -40,9 +44,14 @@ namespace MediaBrowser.Controller.Resolvers
if (item != null)
{
// Set initial values on the newly resolved item
SetItemValues(item, args);
// Make sure the item has a name
EnsureName(item);
// Make sure DateCreated and DateModified have values
EnsureDates(item);
}
@@ -59,6 +68,9 @@ namespace MediaBrowser.Controller.Resolvers
}
/// <summary>
/// Ensures DateCreated and DateModified have values
/// </summary>
private void EnsureDates(T item)
{
// If the subclass didn't supply dates, add them here
@@ -73,6 +85,9 @@ namespace MediaBrowser.Controller.Resolvers
}
}
/// <summary>
/// Fills in image paths based on files win the folder
/// </summary>
protected virtual void PopulateImages(T item, ItemResolveEventArgs args)
{
List<string> backdropFiles = new List<string>();
@@ -88,6 +103,7 @@ namespace MediaBrowser.Controller.Resolvers
string ext = Path.GetExtension(filePath);
// Only support png and jpg files
if (!ext.EndsWith("png", StringComparison.OrdinalIgnoreCase) && !ext.EndsWith("jpg", StringComparison.OrdinalIgnoreCase))
{
continue;
@@ -137,6 +153,9 @@ namespace MediaBrowser.Controller.Resolvers
}
}
/// <summary>
/// Weed this to keep a list of resolvers, since Resolvers are built with generics
/// </summary>
public interface IBaseItemResolver
{
BaseItem ResolvePath(ItemResolveEventArgs args);

View File

@@ -29,6 +29,7 @@ namespace MediaBrowser.Controller.Resolvers
item.IsRoot = args.Parent == null;
// Read data from folder.xml, if it exists
PopulateFolderMetadata(item, args);
}

View File

@@ -1,20 +1,26 @@
using System.IO;
using System.Collections.Generic;
using System.IO;
using MediaBrowser.Controller.Events;
using MediaBrowser.Model.Entities;
using System.Linq;
using System.Collections.Generic;
namespace MediaBrowser.Controller.Resolvers
{
/// <summary>
/// Resolves a Path into a Video
/// </summary>
public class VideoResolver : BaseVideoResolver<Video>
{
}
/// <summary>
/// Resolves a Path into a Video or Video subclass
/// </summary>
public abstract class BaseVideoResolver<T> : BaseItemResolver<T>
where T : Video, new()
{
protected override T Resolve(ItemResolveEventArgs args)
{
// If the path is a file check for a matching extensions
if (!args.IsFolder)
{
if (IsVideoFile(args.Path))
@@ -29,6 +35,7 @@ namespace MediaBrowser.Controller.Resolvers
else
{
// If the path is a folder, check if it's bluray or dvd
T item = ResolveFromFolderName(args.Path);
if (item != null)
@@ -36,6 +43,7 @@ namespace MediaBrowser.Controller.Resolvers
return item;
}
// Also check the subfolders for bluray or dvd
foreach (KeyValuePair<string, FileAttributes> folder in args.FileSystemChildren)
{
if (!folder.Value.HasFlag(FileAttributes.Directory))

View File

@@ -6,8 +6,14 @@ using MediaBrowser.Model.Users;
namespace MediaBrowser.Controller
{
/// <summary>
/// Manages users within the system
/// </summary>
public class UserController
{
/// <summary>
/// Gets or sets the path to folder that contains data for all the users
/// </summary>
public string UsersPath { get; set; }
public UserController(string usersPath)
@@ -15,6 +21,9 @@ namespace MediaBrowser.Controller
UsersPath = usersPath;
}
/// <summary>
/// Gets all users within the system
/// </summary>
public IEnumerable<User> GetAllUsers()
{
if (!Directory.Exists(UsersPath))
@@ -37,6 +46,9 @@ namespace MediaBrowser.Controller
return list;
}
/// <summary>
/// Gets a User from it's directory
/// </summary>
private User GetFromDirectory(string path)
{
string file = Path.Combine(path, "user.js");
@@ -44,17 +56,28 @@ namespace MediaBrowser.Controller
return JsonSerializer.DeserializeFromFile<User>(file);
}
public void CreateUser(User user)
/// <summary>
/// Creates a User with a given name
/// </summary>
public User CreateUser(string name)
{
user.Id = Guid.NewGuid();
var now = DateTime.Now;
user.DateCreated = user.DateModified = DateTime.Now;
User user = new User()
{
Name = name,
Id = Guid.NewGuid(),
DateCreated = now,
DateModified = now
};
string userFolder = Path.Combine(UsersPath, user.Id.ToString());
user.Path = Path.Combine(UsersPath, user.Id.ToString());
Directory.CreateDirectory(userFolder);
Directory.CreateDirectory(user.Path);
JsonSerializer.SerializeToFile(user, Path.Combine(userFolder, "user.js"));
JsonSerializer.SerializeToFile(user, Path.Combine(user.Path, "user.js"));
return user;
}
}
}

View File

@@ -7,15 +7,23 @@ using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Xml
{
public class BaseItemXmlParser<T>
/// <summary>
/// Provides a base class for parsing metadata xml
/// </summary>
public abstract class BaseItemXmlParser<T>
where T : BaseItem, new()
{
/// <summary>
/// Fetches metadata for an item from one xml file
/// </summary>
public virtual void Fetch(T item, string metadataFile)
{
// Use XmlReader for best performance
using (XmlReader reader = XmlReader.Create(metadataFile))
{
reader.MoveToContent();
// Loop through each element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
@@ -25,7 +33,7 @@ namespace MediaBrowser.Controller.Xml
}
}
// If dates weren't supplied in metadata, use values from the file
// If dates weren't supplied in metadata, use values from the xml file
if (item.DateCreated == DateTime.MinValue)
{
item.DateCreated = File.GetCreationTime(metadataFile);
@@ -37,10 +45,14 @@ namespace MediaBrowser.Controller.Xml
}
}
/// <summary>
/// Fetches metadata from one Xml Element
/// </summary>
protected virtual void FetchDataFromXmlNode(XmlReader reader, T item)
{
switch (reader.Name)
{
// DateCreated
case "Added":
DateTime added;
if (DateTime.TryParse(reader.ReadElementContentAsString() ?? string.Empty, out added))
@@ -49,6 +61,7 @@ namespace MediaBrowser.Controller.Xml
}
break;
// DisplayMediaType
case "Type":
{
item.DisplayMediaType = reader.ReadElementContentAsString() ?? string.Empty;
@@ -69,6 +82,7 @@ namespace MediaBrowser.Controller.Xml
break;
}
// TODO: Do we still need this?
case "banner":
item.BannerImagePath = reader.ReadElementContentAsString() ?? string.Empty;
break;
@@ -172,7 +186,7 @@ namespace MediaBrowser.Controller.Xml
string rating = reader.ReadElementContentAsString();
if (!string.IsNullOrEmpty(rating))
if (!string.IsNullOrWhiteSpace(rating))
{
float val;
@@ -428,7 +442,7 @@ namespace MediaBrowser.Controller.Xml
{
string genre = reader.ReadElementContentAsString();
if (!string.IsNullOrEmpty(genre))
if (!string.IsNullOrWhiteSpace(genre))
{
list.Add(genre);
}
@@ -461,7 +475,7 @@ namespace MediaBrowser.Controller.Xml
{
string genre = reader.ReadElementContentAsString();
if (!string.IsNullOrEmpty(genre))
if (!string.IsNullOrWhiteSpace(genre))
{
list.Add(genre);
}
@@ -522,7 +536,7 @@ namespace MediaBrowser.Controller.Xml
{
string studio = reader.ReadElementContentAsString();
if (!string.IsNullOrEmpty(studio))
if (!string.IsNullOrWhiteSpace(studio))
{
list.Add(studio);
}
@@ -555,7 +569,7 @@ namespace MediaBrowser.Controller.Xml
int rating = 7;
if (!string.IsNullOrEmpty(ratingString))
if (!string.IsNullOrWhiteSpace(ratingString))
{
int.TryParse(ratingString, out rating);
}
@@ -646,7 +660,7 @@ namespace MediaBrowser.Controller.Xml
{
value = (value ?? string.Empty).Trim(deliminator);
return string.IsNullOrEmpty(value) ? new string[] { } : value.Split(deliminator);
return string.IsNullOrWhiteSpace(value) ? new string[] { } : value.Split(deliminator);
}
}
}

View File

@@ -2,6 +2,10 @@
namespace MediaBrowser.Controller.Xml
{
/// <summary>
/// Fetches metadata fro a folder.
/// Since folder.xml contains no folder-specific values, no overrides are needed
/// </summary>
public class FolderXmlParser : BaseItemXmlParser<Folder>
{
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Xml;
namespace MediaBrowser.Controller.Xml
@@ -8,13 +7,16 @@ namespace MediaBrowser.Controller.Xml
{
private static CultureInfo _usCulture = new CultureInfo("en-US");
/// <summary>
/// Reads a float from the current element of an XmlReader
/// </summary>
public static float ReadFloatSafe(this XmlReader reader)
{
string valueString = reader.ReadElementContentAsString();
float value = 0;
if (!string.IsNullOrEmpty(valueString))
if (!string.IsNullOrWhiteSpace(valueString))
{
// float.TryParse is local aware, so it can be probamatic, force us culture
float.TryParse(valueString, NumberStyles.AllowDecimalPoint, _usCulture, out value);
@@ -23,13 +25,16 @@ namespace MediaBrowser.Controller.Xml
return value;
}
/// <summary>
/// Reads an int from the current element of an XmlReader
/// </summary>
public static int ReadIntSafe(this XmlReader reader)
{
string valueString = reader.ReadElementContentAsString();
int value = 0;
if (!string.IsNullOrEmpty(valueString))
if (!string.IsNullOrWhiteSpace(valueString))
{
int.TryParse(valueString, out value);