enforced file system
This commit is contained in:
parent
bdd4cf2472
commit
6066497a67
26 changed files with 143 additions and 76 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Yavsc.Abstract.FileSystem
|
namespace Yavsc.Abstract.FileSystem
|
||||||
{
|
{
|
||||||
|
|
@ -6,20 +7,35 @@ namespace Yavsc.Abstract.FileSystem
|
||||||
{
|
{
|
||||||
public static bool IsValidYavscPath(this string path)
|
public static bool IsValidYavscPath(this string path)
|
||||||
{
|
{
|
||||||
if (path == null) return true;
|
if (string.IsNullOrEmpty(path)) return true;
|
||||||
foreach (var name in path.Split('/'))
|
foreach (var name in path.Split('/'))
|
||||||
{
|
{
|
||||||
if (!IsValidDirectoryName(name) || name.Equals("..") || name.Equals("."))
|
if (!IsValidDirectoryName(name) || name.Equals("..") || name.Equals("."))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (path[path.Length]==FileSystemConstants.RemoteDirectorySeparator) return false;
|
if (path[path.Length-1]==FileSystemConstants.RemoteDirectorySeparator) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public static bool IsValidDirectoryName(this string name)
|
public static bool IsValidDirectoryName(this string name)
|
||||||
{
|
{
|
||||||
return !name.Any(c => !FileSystemConstants.ValidFileNameChars.Contains(c));
|
return !name.Any(c => !FileSystemConstants.ValidFileNameChars.Contains(c));
|
||||||
}
|
}
|
||||||
|
// Ensure this path is canonical,
|
||||||
|
// No "dirto/./this", neither "dirt/to/that/"
|
||||||
|
// no .. and each char must be listed as valid in constants
|
||||||
|
|
||||||
|
public static string FilterFileName(string fileName)
|
||||||
|
{
|
||||||
|
if (fileName==null) return null;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
foreach (var c in fileName)
|
||||||
|
{
|
||||||
|
if (FileSystemConstants.ValidFileNameChars.Contains(c))
|
||||||
|
sb.Append(c);
|
||||||
|
else sb.Append('_');
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FileSystemConstants
|
public static class FileSystemConstants
|
||||||
|
|
|
||||||
8
Yavsc.Abstract/FileSystem/IDirectoryShortInfo.cs
Normal file
8
Yavsc.Abstract/FileSystem/IDirectoryShortInfo.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace Yavsc.Abstract.FileSystem {
|
||||||
|
|
||||||
|
public interface IDirectoryShortInfo
|
||||||
|
{
|
||||||
|
string Name { get; set; }
|
||||||
|
bool IsEmpty { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Yavsc.Abstract/FileSystem/IFileRecieved.Info.cs
Normal file
15
Yavsc.Abstract/FileSystem/IFileRecieved.Info.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
namespace Yavsc.Abstract.FileSystem
|
||||||
|
{
|
||||||
|
public interface IFileRecievedInfo
|
||||||
|
{
|
||||||
|
string MimeType { get; set; }
|
||||||
|
|
||||||
|
string DestDir { get; set; }
|
||||||
|
|
||||||
|
string FileName { get; set; }
|
||||||
|
|
||||||
|
bool Overriden { get; set; }
|
||||||
|
|
||||||
|
bool QuotaOffensed { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,15 +7,21 @@ namespace Yavsc.ViewModels.UserFiles
|
||||||
{
|
{
|
||||||
public class UserDirectoryInfo
|
public class UserDirectoryInfo
|
||||||
{
|
{
|
||||||
public string UserName { get; private set; }
|
public string UserName { get; set; }
|
||||||
public string SubPath { get; private set; }
|
public string SubPath { get; set; }
|
||||||
public RemoteFileInfo [] Files {
|
public RemoteFileInfo [] Files {
|
||||||
get; private set;
|
get; set;
|
||||||
}
|
}
|
||||||
public string [] SubDirectories {
|
public DirectoryShortInfo [] SubDirectories {
|
||||||
get; private set;
|
get; set;
|
||||||
}
|
}
|
||||||
private DirectoryInfo dInfo;
|
private DirectoryInfo dInfo;
|
||||||
|
|
||||||
|
// for deserialization
|
||||||
|
public UserDirectoryInfo()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
public UserDirectoryInfo(string userReposPath, string username, string path)
|
public UserDirectoryInfo(string userReposPath, string username, string path)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(username))
|
if (string.IsNullOrWhiteSpace(username))
|
||||||
|
|
@ -35,7 +41,12 @@ namespace Yavsc.ViewModels.UserFiles
|
||||||
( entry => new RemoteFileInfo { Name = entry.Name, Size = entry.Length,
|
( entry => new RemoteFileInfo { Name = entry.Name, Size = entry.Length,
|
||||||
CreationTime = entry.CreationTime, LastModified = entry.LastWriteTime }).ToArray();
|
CreationTime = entry.CreationTime, LastModified = entry.LastWriteTime }).ToArray();
|
||||||
SubDirectories = dInfo.GetDirectories().Select
|
SubDirectories = dInfo.GetDirectories().Select
|
||||||
( d=> d.Name ).ToArray();
|
( d=> new DirectoryShortInfo { Name= d.Name, IsEmpty=false } ).ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DirectoryShortInfo: IDirectoryShortInfo {
|
||||||
|
public string Name { get; set; }
|
||||||
|
public bool IsEmpty { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,23 @@
|
||||||
CONFIG=Release
|
CONFIG=Release
|
||||||
VERSION=1.0.2
|
VERSION=1.0.5-rc4
|
||||||
PRJNAME=Yavsc.Abstract
|
PRJNAME=Yavsc.Abstract
|
||||||
PKGFILENAME=$(PRJNAME).$(VERSION).nupkg
|
PKGFILENAME=$(PRJNAME).$(VERSION).nupkg
|
||||||
DESTPATH=.
|
DESTPATH=.
|
||||||
PACKAGE=$(DESTPATH)/$(PKGFILENAME)
|
PACKAGE=$(DESTPATH)/$(PKGFILENAME)
|
||||||
|
BINARY=bin/$(CONFIG)/net45/Yavsc.Abstract.dll
|
||||||
|
NUGETSOURCE=$(HOME)/Nupkgs/
|
||||||
|
|
||||||
$(PACKAGE):
|
$(PACKAGE): $(BINARY)
|
||||||
nuget pack $(PRJNAME).nuspec -Version $(VERSION)
|
nuget pack $(PRJNAME).nuspec -Version $(VERSION) -Properties config=$(CONFIG)
|
||||||
|
|
||||||
publish: $(PACKAGE)
|
|
||||||
cp $(PACKAGE) ~/Nupkgs
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm $(PACKAGE)
|
rm $(PACKAGE)
|
||||||
|
|
||||||
|
$(BINARY): project.lock.json
|
||||||
|
dnu build --configuration $(CONFIG)
|
||||||
|
|
||||||
|
project.lock.json: project.json
|
||||||
|
dnu restore
|
||||||
|
|
||||||
|
deploy: $(PACKAGE)
|
||||||
|
cp $(PACKAGE) $(NUGETSOURCE)
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,15 @@ using System.Reflection;
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("Yavsc.Client")]
|
[assembly: AssemblyTitle("Yavsc.Abstract")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("Yavsc shared objects")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("Yavsc.Client")]
|
[assembly: AssemblyProduct("Yavsc.Abstract")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
[assembly: AssemblyCopyright("Copyright © 2014-2018")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: NeutralResourcesLanguage("en")]
|
[assembly: NeutralResourcesLanguage("fr")]
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
// Version information for an assembly consists of the following four values:
|
||||||
//
|
//
|
||||||
|
|
@ -24,5 +24,5 @@ using System.Reflection;
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.0.0.0")]
|
[assembly: AssemblyVersion("1.0.5.*")]
|
||||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
[assembly: AssemblyFileVersion("1.0.5.2")]
|
||||||
|
|
|
||||||
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.0.nupkg
Normal file
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.0.nupkg
Normal file
Binary file not shown.
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.3.nupkg
Normal file
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.3.nupkg
Normal file
Binary file not shown.
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.4.nupkg
Normal file
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.4.nupkg
Normal file
Binary file not shown.
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.5-rc1.nupkg
Normal file
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.5-rc1.nupkg
Normal file
Binary file not shown.
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.5-rc2.nupkg
Normal file
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.5-rc2.nupkg
Normal file
Binary file not shown.
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.5-rc3.nupkg
Normal file
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.5-rc3.nupkg
Normal file
Binary file not shown.
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.5-rc4.nupkg
Normal file
BIN
Yavsc.Abstract/Yavsc.Abstract.1.0.5-rc4.nupkg
Normal file
Binary file not shown.
|
|
@ -18,6 +18,6 @@
|
||||||
<tags>yavsc</tags>
|
<tags>yavsc</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="bin/Release/net451/Yavsc.Abstract.dll" target="lib/portable-net45+win8+wp8+wpa81+Xamarin.Mac+MonoAndroid10+MonoTouch10+Xamarin.iOS10" />
|
<file src="bin/$config$/net451/Yavsc.Abstract.dll" target="lib/portable-net45+win8+wp8+wpa81+Xamarin.Mac+MonoAndroid10+MonoTouch10+Xamarin.iOS10" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "1.0.2",
|
"version": "1.0.5",
|
||||||
"description": "Yavsc Client Api",
|
"description": "Yavsc Client Api",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Paul Schneider"
|
"Paul Schneider"
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,11 @@ using Yavsc.Models;
|
||||||
namespace Yavsc.ApiControllers
|
namespace Yavsc.ApiControllers
|
||||||
{
|
{
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Yavsc.Abstract.FileSystem;
|
using Yavsc.Abstract.FileSystem;
|
||||||
using Yavsc.Exceptions;
|
using Yavsc.Exceptions;
|
||||||
|
using Yavsc.Models.FileSystem;
|
||||||
|
|
||||||
public class FSQuotaException : Exception {
|
public class FSQuotaException : Exception {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -21,12 +24,16 @@ namespace Yavsc.ApiControllers
|
||||||
{
|
{
|
||||||
ApplicationDbContext dbContext;
|
ApplicationDbContext dbContext;
|
||||||
private IAuthorizationService AuthorizationService;
|
private IAuthorizationService AuthorizationService;
|
||||||
|
private ILogger logger;
|
||||||
|
|
||||||
public FileSystemApiController(ApplicationDbContext context,
|
public FileSystemApiController(ApplicationDbContext context,
|
||||||
IAuthorizationService authorizationService)
|
IAuthorizationService authorizationService,
|
||||||
|
ILoggerFactory loggerFactory)
|
||||||
|
|
||||||
{
|
{
|
||||||
AuthorizationService = authorizationService;
|
AuthorizationService = authorizationService;
|
||||||
dbContext = context;
|
dbContext = context;
|
||||||
|
logger = loggerFactory.CreateLogger<FileSystemApiController>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet()]
|
[HttpGet()]
|
||||||
|
|
@ -46,11 +53,11 @@ namespace Yavsc.ApiControllers
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IEnumerable<IActionResult> Post(string subdir="", string names = null)
|
public IActionResult Post(string subdir="", string names = null)
|
||||||
{
|
{
|
||||||
string root = null;
|
string root = null;
|
||||||
string [] destinationFileNames = names?.Split('/');
|
string [] destinationFileNames = names?.Split('/');
|
||||||
|
List<FileRecievedInfo> received = new List<FileRecievedInfo>();
|
||||||
InvalidPathException pathex = null;
|
InvalidPathException pathex = null;
|
||||||
try {
|
try {
|
||||||
root = User.InitPostToFileSystem(subdir);
|
root = User.InitPostToFileSystem(subdir);
|
||||||
|
|
@ -58,20 +65,26 @@ namespace Yavsc.ApiControllers
|
||||||
pathex = ex;
|
pathex = ex;
|
||||||
}
|
}
|
||||||
if (pathex!=null)
|
if (pathex!=null)
|
||||||
yield return new BadRequestObjectResult(pathex);
|
return new BadRequestObjectResult(pathex);
|
||||||
|
var uid = User.GetUserId();
|
||||||
var user = dbContext.Users.Single(
|
var user = dbContext.Users.Single(
|
||||||
u => u.Id == User.GetUserId()
|
u => u.Id == uid
|
||||||
);
|
);
|
||||||
int i=0;
|
int i=0;
|
||||||
|
logger.LogInformation($"Recieving {Request.Form.Files.Count} files.");
|
||||||
foreach (var f in Request.Form.Files)
|
foreach (var f in Request.Form.Files)
|
||||||
{
|
{
|
||||||
var destFileName = destinationFileNames?.Length >i ? destinationFileNames[i] : null;
|
var destFileName = destinationFileNames?.Length >i ? destinationFileNames[i] : null;
|
||||||
|
|
||||||
var item = user.ReceiveUserFile(root, f, destFileName);
|
var item = user.ReceiveUserFile(root, f, destFileName);
|
||||||
dbContext.SaveChanges(User.GetUserId());
|
dbContext.SaveChanges(User.GetUserId());
|
||||||
yield return Ok(item);
|
received.Add(item);
|
||||||
|
logger.LogInformation($"Recieved '{item.FileName}'.");
|
||||||
|
if (item.QuotaOffensed)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
};
|
};
|
||||||
|
return Ok(received);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,8 @@ using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Mime;
|
using System.Net.Mime;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Yavsc.Abstract.FileSystem;
|
using Yavsc.Abstract.FileSystem;
|
||||||
|
|
@ -31,22 +29,7 @@ namespace Yavsc.Helpers
|
||||||
return di;
|
return di;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure this path is canonical,
|
|
||||||
// No "dirto/./this", neither "dirt/to/that/"
|
|
||||||
// no .. and each char must be listed as valid in constants
|
|
||||||
|
|
||||||
public static string FilterFileName(string fileName)
|
|
||||||
{
|
|
||||||
if (fileName==null) return null;
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
foreach (var c in fileName)
|
|
||||||
{
|
|
||||||
if (FileSystemConstants.ValidFileNameChars.Contains(c))
|
|
||||||
sb.Append(c);
|
|
||||||
else sb.Append('_');
|
|
||||||
}
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
public static string InitPostToFileSystem(
|
public static string InitPostToFileSystem(
|
||||||
this ClaimsPrincipal user,
|
this ClaimsPrincipal user,
|
||||||
string subpath)
|
string subpath)
|
||||||
|
|
@ -81,10 +64,14 @@ namespace Yavsc.Helpers
|
||||||
var item = new FileRecievedInfo();
|
var item = new FileRecievedInfo();
|
||||||
// form-data; name="file"; filename="capt0008.jpg"
|
// form-data; name="file"; filename="capt0008.jpg"
|
||||||
ContentDisposition contentDisposition = new ContentDisposition(f.ContentDisposition);
|
ContentDisposition contentDisposition = new ContentDisposition(f.ContentDisposition);
|
||||||
item.FileName = FilterFileName (destFileName ?? contentDisposition.FileName);
|
item.FileName = Yavsc.Abstract.FileSystem.FileSystemHelpers.FilterFileName (destFileName ?? contentDisposition.FileName);
|
||||||
item.MimeType = contentDisposition.DispositionType;
|
item.MimeType = contentDisposition.DispositionType;
|
||||||
var fi = new FileInfo(Path.Combine(root, item.FileName));
|
var fi = new FileInfo(Path.Combine(root, item.FileName));
|
||||||
if (fi.Exists) item.Overriden = true;
|
if (fi.Exists)
|
||||||
|
{
|
||||||
|
item.Overriden = true;
|
||||||
|
usage -= fi.Length;
|
||||||
|
}
|
||||||
using (var dest = fi.OpenWrite())
|
using (var dest = fi.OpenWrite())
|
||||||
{
|
{
|
||||||
using (var org = f.OpenReadStream())
|
using (var org = f.OpenReadStream())
|
||||||
|
|
@ -92,7 +79,7 @@ namespace Yavsc.Helpers
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
long len = org.Length;
|
long len = org.Length;
|
||||||
if (len > (user.DiskQuota - usage)) {
|
if (len > (user.DiskQuota - usage)) {
|
||||||
|
item.QuotaOffensed = true;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
usage += len;
|
usage += len;
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,23 @@
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
using Yavsc.Abstract.FileSystem;
|
||||||
|
|
||||||
namespace Yavsc.Models.FileSystem
|
namespace Yavsc.Models.FileSystem
|
||||||
{
|
{
|
||||||
public class FileRecievedInfo
|
public class FileRecievedInfo : IFileRecievedInfo
|
||||||
|
{
|
||||||
|
public FileRecievedInfo()
|
||||||
{
|
{
|
||||||
public string MimeType { get; set; }
|
QuotaOffensed = Overriden = false;
|
||||||
public string DestDir { get; set; }
|
MimeType = DestDir = FileName = null;
|
||||||
public string FileName { get; set; }
|
|
||||||
public bool Overriden { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string MimeType { get; set; }
|
||||||
|
public string DestDir { get; set; }
|
||||||
|
public string FileName { get; set; }
|
||||||
|
public bool Overriden { get; set; }
|
||||||
|
|
||||||
|
public bool QuotaOffensed { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +28,8 @@ namespace Yavsc
|
||||||
{
|
{
|
||||||
FileProvider = new PhysicalFileProvider(UserFilesDirName),
|
FileProvider = new PhysicalFileProvider(UserFilesDirName),
|
||||||
RequestPath = new PathString(Constants.UserFilesPath),
|
RequestPath = new PathString(Constants.UserFilesPath),
|
||||||
EnableDirectoryBrowsing = env.IsDevelopment()
|
EnableDirectoryBrowsing = env.IsDevelopment(),
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
UserFilesOptions.EnableDefaultFiles=true;
|
UserFilesOptions.EnableDefaultFiles=true;
|
||||||
|
|
|
||||||
|
|
@ -67,21 +67,17 @@
|
||||||
<div class="row @trclass">
|
<div class="row @trclass">
|
||||||
<div class="col-xs-10">
|
<div class="col-xs-10">
|
||||||
<a asp-action="Title" asp-route-id="@title" >
|
<a asp-action="Title" asp-route-id="@title" >
|
||||||
<markdown>@first.Title</markdown>
|
<h3 markdown="@first.Title"></h3>
|
||||||
@if (first.Photo==null) { }
|
@if (first.Photo==null) { }
|
||||||
else {<img src="@first.Photo" class="blogphoto" alt="@first.Title">}
|
else {<img src="@first.Photo" class="blogphoto" alt="@first.Title">}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<markdown>@((first.Content?.Length > 120) ? first.Content.Substring(0, 120) + " ..." : first.Content)</markdown>
|
<div class="smalltext" markdown="@((first.Content?.Length > 256) ? first.Content.Substring(0, 256) + "..." : first.Content)"></div>
|
||||||
<span style="font-size:x-small;">(@first.Author.UserName </span>,
|
<div class="smalltext"> @first.Author.UserName ,
|
||||||
<span style="font-size:xx-small;">
|
(posté le @first.DateCreated.ToString("dddd d MMM yyyy à H:mm")
|
||||||
posté le @first.DateCreated.ToString("dddd d MMM yyyy à H:mm")
|
|
||||||
@if ((first.DateModified - first.DateCreated).Minutes > 0){
|
@if ((first.DateModified - first.DateCreated).Minutes > 0){
|
||||||
@:- Modifié le @first.DateModified.ToString("dddd d MMM yyyy à H:mm",System.Globalization.CultureInfo.CurrentUICulture)
|
@:- Modifié le @first.DateModified.ToString("dddd d MMM yyyy à H:mm",System.Globalization.CultureInfo.CurrentUICulture)
|
||||||
})
|
})</div>
|
||||||
</span>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-2">
|
<div class="col-xs-2">
|
||||||
<ul class="actiongroup">
|
<ul class="actiongroup">
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
<img src="@item.Photo" class="blogphoto"></a>
|
<img src="@item.Photo" class="blogphoto"></a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<markdown>@((item.Content?.Length > 120) ? item.Content.Substring(0, 122) + " ..." : item.Content)</markdown>
|
<markdown>@((item.Content?.Length > 256) ? item.Content.Substring(0, 256) + " ..." : item.Content)</markdown>
|
||||||
<span style="font-size:x-small;">(@item.Author.UserName </span>,
|
<span style="font-size:x-small;">(@item.Author.UserName </span>,
|
||||||
<span style="font-size:xx-small;">
|
<span style="font-size:xx-small;">
|
||||||
posté le @item.DateCreated.ToString("dddd d MMM yyyy à H:mm")
|
posté le @item.DateCreated.ToString("dddd d MMM yyyy à H:mm")
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@
|
||||||
@if (Model.DiskQuota>0)
|
@if (Model.DiskQuota>0)
|
||||||
{
|
{
|
||||||
<text>
|
<text>
|
||||||
@((Model.DiskUsage/Model.DiskQuota).ToString("%#0")) :
|
@(((double)Model.DiskUsage/Model.DiskQuota).ToString("%#0")) :
|
||||||
</text>
|
</text>
|
||||||
}
|
}
|
||||||
<text>
|
<text>
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
<div class="dirinfo">
|
<div class="dirinfo">
|
||||||
<strong>@Model.UserName / @Model.SubPath</strong>
|
<strong>@Model.UserName / @Model.SubPath</strong>
|
||||||
<div class="subdirs">
|
<div class="subdirs">
|
||||||
@foreach (string subdir in Model.SubDirectories) {
|
@foreach (var subdir in Model.SubDirectories) {
|
||||||
<a href="@subdir" class="subdir">@subdir</a>
|
<a href="@subdir" class="subdir">@subdir.Name</a>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@
|
||||||
"System.Json": "4.0.20126.16343",
|
"System.Json": "4.0.20126.16343",
|
||||||
"Yavsc.Abstract": {
|
"Yavsc.Abstract": {
|
||||||
"type": "build",
|
"type": "build",
|
||||||
"version": "1.0.2"
|
"version": "1.0.5"
|
||||||
},
|
},
|
||||||
"Extensions.AspNet.Authentication.Instagram": "1.0.0-t150809211713",
|
"Extensions.AspNet.Authentication.Instagram": "1.0.0-t150809211713",
|
||||||
"Microsoft.AspNet.Http.Extensions": "1.0.0-rc1-final",
|
"Microsoft.AspNet.Http.Extensions": "1.0.0-rc1-final",
|
||||||
|
|
@ -166,4 +166,4 @@
|
||||||
"postpublish": "echo after publish"
|
"postpublish": "echo after publish"
|
||||||
},
|
},
|
||||||
"embed": "Views/**/*.cshtml"
|
"embed": "Views/**/*.cshtml"
|
||||||
}
|
}
|
||||||
|
|
@ -2823,7 +2823,7 @@
|
||||||
"lib/WebGrease.dll": {}
|
"lib/WebGrease.dll": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Yavsc.Abstract/1.0.2": {
|
"Yavsc.Abstract/1.0.5": {
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"framework": ".NETFramework,Version=v4.5.1",
|
"framework": ".NETFramework,Version=v4.5.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -5656,7 +5656,7 @@
|
||||||
"lib/WebGrease.dll": {}
|
"lib/WebGrease.dll": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Yavsc.Abstract/1.0.2": {
|
"Yavsc.Abstract/1.0.5": {
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"framework": ".NETFramework,Version=v4.5.1",
|
"framework": ".NETFramework,Version=v4.5.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -8489,7 +8489,7 @@
|
||||||
"lib/WebGrease.dll": {}
|
"lib/WebGrease.dll": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Yavsc.Abstract/1.0.2": {
|
"Yavsc.Abstract/1.0.5": {
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"framework": ".NETFramework,Version=v4.5.1",
|
"framework": ".NETFramework,Version=v4.5.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -8503,7 +8503,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"libraries": {
|
"libraries": {
|
||||||
"Yavsc.Abstract/1.0.2": {
|
"Yavsc.Abstract/1.0.5": {
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"path": "../Yavsc.Abstract/project.json"
|
"path": "../Yavsc.Abstract/project.json"
|
||||||
},
|
},
|
||||||
|
|
@ -11437,7 +11437,7 @@
|
||||||
"Microsoft.AspNet.Mvc.Formatters.Json >= 6.0.0-rc1-final",
|
"Microsoft.AspNet.Mvc.Formatters.Json >= 6.0.0-rc1-final",
|
||||||
"Microsoft.AspNet.OWin >= 1.0.0-rc1-final",
|
"Microsoft.AspNet.OWin >= 1.0.0-rc1-final",
|
||||||
"System.Json >= 4.0.20126.16343",
|
"System.Json >= 4.0.20126.16343",
|
||||||
"Yavsc.Abstract >= 1.0.2",
|
"Yavsc.Abstract >= 1.0.5",
|
||||||
"Extensions.AspNet.Authentication.Instagram >= 1.0.0-t150809211713",
|
"Extensions.AspNet.Authentication.Instagram >= 1.0.0-t150809211713",
|
||||||
"Microsoft.AspNet.Http.Extensions >= 1.0.0-rc1-final",
|
"Microsoft.AspNet.Http.Extensions >= 1.0.0-rc1-final",
|
||||||
"Microsoft.DiaSymReader.Native >= 1.5.0",
|
"Microsoft.DiaSymReader.Native >= 1.5.0",
|
||||||
|
|
|
||||||
|
|
@ -390,6 +390,10 @@ p.small {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.smalltext {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
h1,
|
h1,
|
||||||
h2,
|
h2,
|
||||||
h3,
|
h3,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue