1
0
mirror of https://git.teknik.io/Teknikode/Teknik.git synced 2023-08-02 14:16:22 +02:00

Moved transpaerency to the new status page, and separated each section into a tab.

This commit is contained in:
Uncled1023 2017-02-19 00:12:51 -08:00
parent d425b42694
commit b967bc07d6
39 changed files with 628 additions and 638 deletions

View File

@ -8,7 +8,7 @@ using System.Net;
using System.Net.Mail;
using System.Reflection;
using System.Text;
using Teknik.Areas.Transparency.Models;
using Teknik.Areas.Status.Models;
using Teknik.Areas.Upload.Models;
using Teknik.Areas.Users.Models;
using Teknik.Areas.Users.Utility;

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using Teknik.Areas.Status.Models;
using Teknik.Areas.Status.ViewModels;
using Teknik.Attributes;
using Teknik.Controllers;
@ -24,12 +25,13 @@ namespace Teknik.Areas.Status.Controllers
[AllowAnonymous]
public ActionResult Index()
{
ViewBag.Title = "Status Information - " + Config.Title;
ViewBag.Title = "System Status - " + Config.Title;
ViewBag.Description = "Current status information for the server and resources.";
StatusViewModel model = new StatusViewModel();
// Load initial status info
#region Statistics
Upload.Models.Upload upload = db.Uploads.OrderByDescending(u => u.UploadId).FirstOrDefault();
model.UploadCount = (upload != null) ? upload.UploadId : 0;
model.UploadSize = (upload != null) ? db.Uploads.Sum(u => (long)u.ContentLength) : 0;
@ -45,6 +47,116 @@ namespace Teknik.Areas.Status.Controllers
Vault.Models.Vault vault = db.Vaults.OrderByDescending(v => v.VaultId).FirstOrDefault();
model.VaultCount = (url != null) ? vault.VaultId : 0;
#endregion
// Get Transaction Inforomation
#region Transactions
DateTime curTime = DateTime.Now;
var billSums = db.Transactions.OfType<Bill>().GroupBy(b => new { b.Currency, b.DateSent.Month, b.DateSent.Year}).Select(b => new { month = b.Key.Month, year = b.Key.Year, currency = b.Key.Currency, total = b.Sum(c => c.Amount) }).ToList();
foreach (var sum in billSums)
{
decimal exchangeRate = CurrencyHelper.GetExchangeRate(sum.currency);
decimal realValue = sum.total * exchangeRate;
model.Transactions.TotalBills += realValue;
model.Transactions.TotalNet += realValue;
if (curTime.Month == sum.month && curTime.Year == sum.year)
{
model.Transactions.CurrentMonthBills += Math.Abs(realValue);
}
}
var oneSums = db.Transactions.OfType<OneTime>().GroupBy(b => new { b.Currency, b.DateSent.Month, b.DateSent.Year }).Select(b => new { month = b.Key.Month, year = b.Key.Year, currency = b.Key.Currency, total = b.Sum(c => c.Amount) }).ToList();
foreach (var sum in oneSums)
{
decimal exchangeRate = CurrencyHelper.GetExchangeRate(sum.currency);
decimal realValue = sum.total * exchangeRate;
model.Transactions.TotalOneTimes += realValue;
model.Transactions.TotalNet += realValue;
if (curTime.Month == sum.month && curTime.Year == sum.year)
{
model.Transactions.CurrentMonthBills += Math.Abs(realValue);
}
}
var donationSums = db.Transactions.OfType<Donation>().GroupBy(b => new { b.Currency, b.DateSent.Month, b.DateSent.Year }).Select(b => new { month = b.Key.Month, year = b.Key.Year, currency = b.Key.Currency, total = b.Sum(c => c.Amount) }).ToList();
foreach (var sum in donationSums)
{
decimal exchangeRate = CurrencyHelper.GetExchangeRate(sum.currency);
decimal realValue = sum.total * exchangeRate;
model.Transactions.TotalDonations += realValue;
model.Transactions.TotalNet += realValue;
if (curTime.Month == sum.month && curTime.Year == sum.year)
{
model.Transactions.CurrentMonthIncome += Math.Abs(realValue);
}
}
List<Bill> bills = db.Transactions.OfType<Bill>().OrderByDescending(b => b.DateSent).ToList();
if (bills != null)
{
foreach (Bill bill in bills)
{
BillViewModel billModel = new BillViewModel();
billModel.Amount = bill.Amount;
billModel.Currency = bill.Currency;
billModel.Reason = bill.Reason;
billModel.DateSent = bill.DateSent;
billModel.Recipient = bill.Recipient;
model.Transactions.Bills.Add(billModel);
}
}
List<OneTime> oneTimes = db.Transactions.OfType<OneTime>().OrderByDescending(b => b.DateSent).ToList();
if (oneTimes != null)
{
foreach (OneTime oneTime in oneTimes)
{
OneTimeViewModel oneTimeModel = new OneTimeViewModel();
oneTimeModel.Amount = oneTime.Amount;
oneTimeModel.Currency = oneTime.Currency;
oneTimeModel.Reason = oneTime.Reason;
oneTimeModel.DateSent = oneTime.DateSent;
oneTimeModel.Recipient = oneTime.Recipient;
model.Transactions.OneTimes.Add(oneTimeModel);
}
}
List<Donation> donations = db.Transactions.OfType<Donation>().OrderByDescending(b => b.DateSent).ToList();
if (donations != null)
{
foreach (Donation donation in donations)
{
DonationViewModel donationModel = new DonationViewModel();
donationModel.Amount = donation.Amount;
donationModel.Currency = donation.Currency;
donationModel.Reason = donation.Reason;
donationModel.DateSent = donation.DateSent;
donationModel.Sender = donation.Sender;
model.Transactions.Donations.Add(donationModel);
}
}
#endregion
// Takedown information
#region Takedowns
List<Takedown> takedowns = db.Takedowns.OrderByDescending(b => b.DateRequested).ToList();
if (takedowns != null)
{
foreach (Takedown takedown in takedowns)
{
TakedownViewModel takedownModel = new TakedownViewModel();
takedownModel.Requester = takedown.Requester;
takedownModel.RequesterContact = takedown.RequesterContact;
takedownModel.Reason = takedown.Reason;
takedownModel.ActionTaken = takedown.ActionTaken;
takedownModel.DateRequested = takedown.DateRequested;
takedownModel.DateActionTaken = takedown.DateActionTaken;
model.Takedowns.Add(takedownModel);
}
}
#endregion
return View(model);
}

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Teknik.Areas.Transparency.Models
namespace Teknik.Areas.Status.Models
{
public class Bill : Transaction
{

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Teknik.Areas.Transparency.Models
namespace Teknik.Areas.Status.Models
{
public class Donation : Transaction
{

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Teknik.Areas.Transparency.Models
namespace Teknik.Areas.Status.Models
{
public class OneTime : Transaction
{

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Teknik.Areas.Transparency.Models
namespace Teknik.Areas.Status.Models
{
public class Takedown
{

View File

@ -3,16 +3,17 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teknik.Utilities;
namespace Teknik.Areas.Transparency.Models
namespace Teknik.Areas.Status.Models
{
public class Transaction
{
public int TransactionId { get; set; }
public double Amount { get; set; }
public decimal Amount { get; set; }
public string Currency { get; set; }
public CurrencyType Currency { get; set; }
public string Reason { get; set; }

View File

@ -3,6 +3,11 @@ var memUsageChart;
var networkUsageChart;
$(document).ready(function () {
$('#bills-section').collapse('hide');
$('#oneTime-section').collapse('hide');
$('#donations-section').collapse('hide');
$('#takedowns-section').collapse('hide');
/* ----------------------------------------
CPU Usage
-----------------------------------------*/
@ -22,11 +27,13 @@ $(document).ready(function () {
},
yAxis: {
title: {
text: 'Percentage %'
text: 'Percentage'
},
max: 100,
min: 0,
format: '{value}',
labels: {
format: '{value}%'
},
plotLines: [{
value: 0,
width: 1,
@ -38,6 +45,9 @@ $(document).ready(function () {
crosshairs: true,
pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.y:.2f}%</b><br/>'
},
credits: {
enabled: false
},
series: [
{
name: 'Total',
@ -98,6 +108,9 @@ $(document).ready(function () {
return '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + yVal + '</b><br/>';
}
},
credits: {
enabled: false
},
series: [
{
name: 'Total',
@ -156,6 +169,9 @@ $(document).ready(function () {
return '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + yVal + '</b><br/>';
}
},
credits: {
enabled: false
},
series: [
{
name: 'Sent',
@ -173,7 +189,9 @@ $(document).ready(function () {
-----------------------------------------*/
visitChart = new Highcharts.chart({
chart: {
renderTo: 'visitor-chart'
renderTo: 'visitor-chart',
type: 'line',
marginRight: 10
},
title: {
text: 'Daily Visitors'
@ -199,6 +217,9 @@ $(document).ready(function () {
headerFormat: '<span style="font-size: 10px">{point.key:%B %e, %Y}</span><br/>',
pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.y}</b><br/>'
},
credits: {
enabled: false
},
series: [
{
name: 'All Visitors',
@ -260,8 +281,9 @@ $(document).ready(function () {
url: getVisitorDataURL,
success: function (response) {
if (response.result) {
visitChart.series[0].setData(response.result.totalVisitors);
visitChart.series[1].setData(response.result.uniqueVisitors);
visitChart.series[0].setData(response.result.totalVisitors, false);
visitChart.series[1].setData(response.result.uniqueVisitors, false);
visitChart.redraw();
}
else {
var err = response;
@ -274,4 +296,9 @@ $(document).ready(function () {
}
});
}
// Resize the chart when viewing the tab (initial width is wrong due to chart being hidden)
$('a[href="#site-stats"]').on('shown.bs.tab', function (e) {
visitChart.setSize($('#visitor-chart').width(), $('#visitor-chart').height());
})
});

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.ViewModels;
namespace Teknik.Areas.Status.ViewModels
{
public class BillViewModel : TransactionViewModel
{
public string Recipient { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.ViewModels;
namespace Teknik.Areas.Status.ViewModels
{
public class DonationViewModel : TransactionViewModel
{
public string Sender { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.ViewModels;
namespace Teknik.Areas.Status.ViewModels
{
public class OneTimeViewModel : TransactionViewModel
{
public string Recipient { get; set; }
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.Areas.Status.Models;
using Teknik.Models;
using Teknik.ViewModels;
@ -21,6 +22,10 @@ namespace Teknik.Areas.Status.ViewModels
public int VaultCount { get; set; }
public TransactionsViewModel Transactions { get; set; }
public List<TakedownViewModel> Takedowns { get; set; }
public StatusViewModel()
{
UploadCount = 0;
@ -29,6 +34,8 @@ namespace Teknik.Areas.Status.ViewModels
UserCount = 0;
ShortenedUrlCount = 0;
VaultCount = 0;
Transactions = new TransactionsViewModel();
Takedowns = new List<TakedownViewModel>();
}
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.ViewModels;
namespace Teknik.Areas.Status.ViewModels
{
public class TakedownViewModel : ViewModelBase
{
public string Requester { get; set; }
public string RequesterContact { get; set; }
public string Reason { get; set; }
public string ActionTaken { get; set; }
public DateTime DateRequested { get; set; }
public DateTime DateActionTaken { get; set; }
public virtual ICollection<Upload.Models.Upload> Attachments { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.Areas.Status.Models;
using Teknik.Utilities;
using Teknik.ViewModels;
namespace Teknik.Areas.Status.ViewModels
{
public class TransactionViewModel : ViewModelBase
{
public decimal Amount { get; set; }
public CurrencyType Currency { get; set; }
public string Reason { get; set; }
public DateTime DateSent { get; set; }
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.ViewModels;
namespace Teknik.Areas.Status.ViewModels
{
public class TransactionsViewModel : ViewModelBase
{
public decimal CurrentMonthBills { get; set; }
public decimal CurrentMonthIncome { get; set; }
public decimal TotalBills { get; set; }
public decimal TotalOneTimes { get; set; }
public decimal TotalDonations { get; set; }
public decimal TotalNet { get; set; }
public List<BillViewModel> Bills { get; set; }
public List<OneTimeViewModel> OneTimes { get; set; }
public List<DonationViewModel> Donations { get; set; }
public TransactionsViewModel()
{
TotalBills = 0;
TotalOneTimes = 0;
TotalDonations = 0;
TotalNet = 0;
Bills = new List<BillViewModel>();
OneTimes = new List<OneTimeViewModel>();
Donations = new List<DonationViewModel>();
}
}
}

View File

@ -0,0 +1,35 @@
@model List<Teknik.Areas.Status.ViewModels.BillViewModel>
@using Teknik.Areas.Status.ViewModels
@if (Model != null && Model.Any())
{
<div class="row">
<div class="col-sm-12">
<h3>Bills</h3>
<div class="row">
<div class="col-sm-12">
<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#bills-section">View Bills</button>
</div>
</div>
<br />
<div id="bills-section" class="collapse in">
<table class="table table-condensed table-bordered table-hover">
<tr>
<th><strong>Date</strong></th>
<th><strong>Amount</strong></th>
<th><strong>Description</strong></th>
</tr>
@foreach (BillViewModel bill in Model)
{
<tr>
<td>@bill.DateSent.ToString("MMMM dd, yyyy")</td>
<td>@bill.Amount <var>@bill.Currency.ToString()</var></td>
<td>@bill.Reason</td>
</tr>
}
</table>
</div>
</div>
</div>
}

View File

@ -0,0 +1,37 @@
@model List<Teknik.Areas.Status.ViewModels.DonationViewModel>
@using Teknik.Areas.Status.ViewModels
@if (Model != null && Model.Any())
{
<div class="row">
<div class="col-sm-12">
<h3>Donations</h3>
<div class="row">
<div class="col-sm-12">
<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#donations-section">View Donations</button>
</div>
</div>
<br />
<div id="donations-section" class="collapse in">
<table class="table table-condensed table-bordered table-hover">
<tr>
<th><strong>Date</strong></th>
<th><strong>Amount</strong></th>
<th><strong>Donor</strong></th>
<th><strong>Reason for Donation</strong></th>
</tr>
@foreach (DonationViewModel donation in Model)
{
<tr>
<td>@donation.DateSent.ToString("MMMM dd, yyyy")</td>
<td>@donation.Amount <var>@donation.Currency.ToString()</var></td>
<td>@donation.Sender</td>
<td>@donation.Reason</td>
</tr>
}
</table>
</div>
</div>
</div>
}

View File

@ -1,7 +1,7 @@
@model Teknik.Areas.Status.ViewModels.StatusViewModel
@using Teknik.Utilities
@using Newtonsoft.Json
@using Teknik.Areas.Status.Models
@Scripts.Render("~/bundles/signalr")
@Scripts.Render("~/signalr/hubs")
@ -20,9 +20,16 @@
<div class="container">
@if (Model.Config.StatusConfig.Enabled)
{
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<h2 class="text-center"><b>Realtime Usage</b></h2>
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#realtime-stats" role="tab" data-toggle="tab">Realtime Server Usage</a></li>
<li role="presentation"><a href="#site-stats" role="tab" data-toggle="tab">Site Statistics</a></li>
<li role="presentation"><a href="#transactions" role="tab" data-toggle="tab">Transactions</a></li>
<li role="presentation"><a href="#takedowns" role="tab" data-toggle="tab">Takedowns</a></li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="realtime-stats">
<h2 class="text-center"><b>Realtime Server Usage</b></h2>
<hr>
<div class="row">
<div class="col-sm-12">
@ -40,11 +47,8 @@
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<br />
<h2 class="text-center"><b>Statistics</b></h2>
<div role="tabpanel" class="tab-pane" id="site-stats">
<h2 class="text-center"><b>Site Statistics</b></h2>
<hr>
@if (Model.Config.PiwikConfig.Enabled)
{
@ -53,7 +57,6 @@
<div id="visitor-chart"></div>
</div>
</div>
<br />
}
<div class="row">
<div class="col-sm-3 text-center">
@ -80,6 +83,13 @@
<p>Number of Users: @Model.UserCount</p>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="transactions">
@Html.Partial("~/Areas/Status/Views/Status/Transactions.cshtml", Model.Transactions)
</div>
<div role="tabpanel" class="tab-pane" id="takedowns">
@Html.Partial("~/Areas/Status/Views/Status/Takedowns.cshtml", Model.Takedowns)
</div>
</div>
}

View File

@ -0,0 +1,35 @@
@model List<Teknik.Areas.Status.ViewModels.OneTimeViewModel>
@using Teknik.Areas.Status.ViewModels
@if (Model != null && Model.Any())
{
<div class="row">
<div class="col-sm-12">
<h3>One Time Payments</h3>
<div class="row">
<div class="col-sm-12">
<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#oneTime-section">View Payments</button>
</div>
</div>
<br />
<div id="oneTime-section" class="collapse in">
<table class="table table-condensed table-bordered table-hover">
<tr>
<th><strong>Date</strong></th>
<th><strong>Amount</strong></th>
<th><strong>Reason for Payment</strong></th>
</tr>
@foreach (OneTimeViewModel oneTime in Model)
{
<tr>
<td>@oneTime.DateSent.ToString("MMMM dd, yyyy")</td>
<td>@oneTime.Amount <var>@oneTime.Currency.ToString()</var></td>
<td>@oneTime.Reason</td>
</tr>
}
</table>
</div>
</div>
</div>
}

View File

@ -0,0 +1,37 @@
@model List<Teknik.Areas.Status.ViewModels.TakedownViewModel>
@using Teknik.Areas.Status.ViewModels
@if (Model != null && Model.Any())
{
<div class="row">
<div class="col-sm-12">
<h2 class="text-center"><b>Takedowns</b></h2>
<hr>
@if (Model != null && Model.Any())
{
<table class="table table-hover table-bordered table-condensed">
<tr>
<th><strong>Requester</strong></th>
<th><strong>Contact</strong></th>
<th><strong>Date Requested</strong></th>
<th><strong>Date Of Action</strong></th>
<th><strong>Reason</strong></th>
<th><strong>Action Taken</strong></th>
</tr>
@foreach (TakedownViewModel takedown in Model)
{
<tr>
<td>@takedown.Requester</td>
<td>@takedown.RequesterContact</td>
<td>@takedown.DateRequested.ToString("MMMM dd, yyyy")</td>
<td>@takedown.DateActionTaken.ToString("MMMM dd, yyyy")</td>
<td>@takedown.Reason</td>
<td>@takedown.ActionTaken</td>
</tr>
}
</table>
}
</div>
</div>
}

View File

@ -0,0 +1,60 @@
@model Teknik.Areas.Status.ViewModels.TransactionsViewModel
@using Teknik.Areas.Status.ViewModels
@{
decimal totalBills = Model.CurrentMonthBills;
decimal totalIncome = Model.CurrentMonthIncome;
int incomePercentage = 100;
if (totalIncome != 0 && totalBills != 0)
{
incomePercentage = (int)Math.Max((Math.Floor(totalBills / totalIncome) * 100), 100);
}
string processStyle = "progress-bar progress-bar-success";
if (incomePercentage < 100)
{
processStyle += " progress-bar-striped";
}
}
<div class="row">
<div class="col-sm-12">
<h2 class="text-center"><b>Transactions</b></h2>
<hr>
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<h3 class="text-center">Monthly Donation Target</h3>
<div class="progress">
<div class="@processStyle" role="progressbar" style="width: @incomePercentage%"></div>
</div>
<div class="row">
<div class="col-sm-12 text-center">$@totalIncome Donated / $@totalBills Bills</div>
</div>
</div>
</div>
<h3 class="text-center">Transaction Totals</h3>
<div class="row">
<div class="col-sm-3 text-center">
<h4>Donations</h4>
<p>$@Math.Round(Model.TotalDonations, 2)</p>
</div>
<div class="col-sm-3 text-center">
<h4>Bills</h4>
<p>$@Math.Round(Model.TotalBills, 2)</p>
</div>
<div class="col-sm-3 text-center">
<h4>One-Time Payments</h4>
<p>$@Math.Round(Model.TotalOneTimes, 2)</p>
</div>
<div class="col-sm-3 text-center">
<h4>Net Profit</h4>
<p>$@Math.Round(Model.TotalNet, 2)</p>
</div>
</div>
</div>
</div>
@Html.Partial("~/Areas/Status/Views/Status/Bills.cshtml", Model.Bills)
@Html.Partial("~/Areas/Status/Views/Status/OneTimes.cshtml", Model.OneTimes)
@Html.Partial("~/Areas/Status/Views/Status/Donations.cshtml", Model.Donations)

View File

@ -1,130 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teknik.Areas.Transparency.Models;
using Teknik.Areas.Transparency.ViewModels;
using Teknik.Attributes;
using Teknik.Controllers;
using Teknik.Filters;
using Teknik.Models;
using Teknik.Piwik;
namespace Teknik.Areas.Transparency.Controllers
{
[TeknikAuthorize]
public class TransparencyController : DefaultController
{
private TeknikEntities db = new TeknikEntities();
[TrackPageView]
[AllowAnonymous]
public ActionResult Index()
{
ViewBag.Title = "Transparency - " + Config.Title;
ViewBag.Description = "Teknik transparency and statistics.";
TransparencyViewModel model = new TransparencyViewModel();
if (Config.TransparencyConfig.Enabled)
{
model.TotalNet = new Dictionary<string, double>();
var billSums = db.Transactions.OfType<Bill>().GroupBy(b => b.Currency).Select(b => new { currency = b.Key, total = b.Sum(c => c.Amount) }).ToList();
model.TotalBills = new Dictionary<string, double>();
foreach (var sum in billSums)
{
model.TotalBills.Add(sum.currency, sum.total);
if (model.TotalNet.ContainsKey(sum.currency))
{
model.TotalNet[sum.currency] += sum.total;
}
else
{
model.TotalNet.Add(sum.currency, sum.total);
}
}
var oneSums = db.Transactions.OfType<OneTime>().GroupBy(b => b.Currency).Select(b => new { currency = b.Key, total = b.Sum(c => c.Amount) }).ToList();
model.TotalOneTimes = new Dictionary<string, double>();
foreach (var sum in oneSums)
{
model.TotalOneTimes.Add(sum.currency, sum.total);
if (model.TotalNet.ContainsKey(sum.currency))
{
model.TotalNet[sum.currency] += sum.total;
}
else
{
model.TotalNet.Add(sum.currency, sum.total);
}
}
var donationSums = db.Transactions.OfType<Donation>().GroupBy(b => b.Currency).Select(b => new { currency = b.Key, total = b.Sum(c => c.Amount) }).ToList();
model.TotalDonations = new Dictionary<string, double>();
foreach (var sum in donationSums)
{
model.TotalDonations.Add(sum.currency, sum.total);
if (model.TotalNet.ContainsKey(sum.currency))
{
model.TotalNet[sum.currency] += sum.total;
}
else
{
model.TotalNet.Add(sum.currency, sum.total);
}
}
List<Bill> bills = db.Transactions.OfType<Bill>().OrderByDescending(b => b.DateSent).ToList();
model.Bills = (bills != null) ? bills : new List<Bill>();
List<OneTime> oneTimes = db.Transactions.OfType<OneTime>().OrderByDescending(b => b.DateSent).ToList();
model.OneTimes = (oneTimes != null) ? oneTimes : new List<OneTime>();
List<Donation> donations = db.Transactions.OfType<Donation>().OrderByDescending(b => b.DateSent).ToList();
model.Donations = (donations != null) ? donations : new List<Donation>();
List<Takedown> takedowns = db.Takedowns.OrderByDescending(b => b.DateRequested).ToList();
model.Takedowns = (takedowns != null) ? takedowns : new List<Takedown>();
// Grab canary file
if (System.IO.File.Exists(Config.TransparencyConfig.CanaryPath))
{
model.Canary = System.IO.File.ReadAllText(Config.TransparencyConfig.CanaryPath);
}
else
{
model.Canary = string.Empty;
}
}
return View(model);
}
[HttpGet]
[AllowAnonymous]
public ActionResult GetVisitorData()
{
// Get the data from the Piwik
if (!string.IsNullOrEmpty(Config.PiwikConfig.API))
{
List<VisitorData> dataList = Reporting.GetVisitSummaryByDays(Config, 31);
List<object> uniqueData = new List<object>();
List<object> totalData = new List<object>();
foreach (VisitorData data in dataList.OrderBy(d => d.Date))
{
object uniqueDay = new { x = Convert.ToInt64((data.Date.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds), y = data.UniqueVisitors };
uniqueData.Add(uniqueDay);
object totalDay = new { x = Convert.ToInt64((data.Date.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds), y = data.Visits };
totalData.Add(totalDay);
}
return Json(new { result = new { uniqueVisitors = uniqueData.ToArray(), totalVisitors = totalData.ToArray() } }, JsonRequestBehavior.AllowGet);
}
return Json(new { error = new { message = "Piwik not configured" } }, JsonRequestBehavior.AllowGet);
}
}
}

View File

@ -1,69 +0,0 @@
var visitChart;
$(document).ready(function () {
$('#bills-section').collapse('hide');
$('#oneTime-section').collapse('hide');
$('#donations-section').collapse('hide');
$('#takedowns-section').collapse('hide');
visitChart = new Highcharts.chart({
chart: {
renderTo: 'visitor-chart'
},
title: {
text: 'Daily Visitors'
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: { // don't display the dummy year
month: '%e. %b',
year: '%b'
},
title: {
text: 'Date'
}
},
yAxis: {
title: {
text: 'Visitors'
}
},
tooltip: {
shared: true,
crosshairs: true,
headerFormat: '<span style="font-size: 10px">{point.key:%B %e, %Y}</span><br/>',
pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.y}</b><br/>'
},
series: [
{
name: 'All Visitors',
data: []
},
{
name: 'Unique Visitors',
data: []
}
]
});
if (statsEnabled) {
$.ajax({
type: "GET",
url: getVisitorDataURL,
success: function (response) {
if (response.result) {
visitChart.series[0].setData(response.result.totalVisitors);
visitChart.series[1].setData(response.result.uniqueVisitors);
}
else {
var err = response;
if (response.error) {
err = response.error.message;
}
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + err + '</div>');
}
}
});
}
});

View File

@ -1,45 +0,0 @@
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Optimization;
using Teknik.Configuration;
using Teknik.Utilities;
namespace Teknik.Areas.Transparency
{
public class TransparencyAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Transparency";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
Config config = Config.Load();
context.MapSubdomainRoute(
"Transparency.Index",
new List<string>() { "transparency" }, // Subdomains
new List<string>() { config.Host }, // domains
"",
new { controller = "Transparency", action = "Index" },
new[] { typeof(Controllers.TransparencyController).Namespace }
);
context.MapSubdomainRoute(
"Transparency.Action",
new List<string>() { "transparency" }, // Subdomains
new List<string>() { config.Host }, // domains
"Action/{controller}/{action}",
new { controller = "Transparency", action = "Index" },
new[] { typeof(Controllers.TransparencyController).Namespace }
);
// Register Script Bundle
BundleTable.Bundles.Add(new CdnScriptBundle("~/bundles/transparency", config.CdnHost).Include(
"~/Scripts/Highcharts/highcharts.js",
"~/Areas/Transparency/Scripts/Transparency.js"));
}
}
}

View File

@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teknik.Areas.Transparency.Models;
using Teknik.ViewModels;
namespace Teknik.Areas.Transparency.ViewModels
{
public class TransparencyViewModel : ViewModelBase
{
public string Canary { get; set; }
public Dictionary<string, double> TotalBills { get; set; }
public Dictionary<string, double> TotalOneTimes { get; set; }
public Dictionary<string, double> TotalDonations { get; set; }
public Dictionary<string, double> TotalNet { get; set; }
public List<Bill> Bills { get; set; }
public List<OneTime> OneTimes { get; set; }
public List<Donation> Donations { get; set; }
public List<Takedown> Takedowns { get; set; }
}
}

View File

@ -1,255 +0,0 @@
@model Teknik.Areas.Transparency.ViewModels.TransparencyViewModel
@using Teknik.Utilities
@using Teknik.Areas.Transparency.Models
@Scripts.Render("~/bundles/transparency")
<script type="text/javascript">
var statsEnabled = @(Model.Config.PiwikConfig.Enabled.ToString().ToLower());
var getVisitorDataURL = '@Url.SubRouteUrl("transparency", "Transparency.Action", new { action = "GetVisitorData" })';
</script>
<div class="container">
@if (Model.Config.TransparencyConfig.Enabled)
{
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<h2 class="text-center"><b>Behind the Scenes</b></h2>
<hr>
<p>
Here you can view all of Teknik's financial information, takedown requests and the actions we took.
</p>
<p>
If you would like to request additional information about Teknik, please feel free to contact us through our <a href="@Url.SubRouteUrl("contact", "Contact.Index")" target="_blank">Contact Form</a> or by emailing us at <a href="mailto:@Model.Config.SupportEmail">@Model.Config.SupportEmail</a>.
</p>
<br />
<h2 class="text-center"><b>Transactions</b></h2>
<hr>
<h3 class="text-center">Total Amounts</h3>
<div class="row">
<div class="col-sm-3 text-center">
<h4>Donations</h4>
@foreach (var val in Model.TotalDonations)
{
<p>@Math.Round(val.Value, 2) @val.Key</p>
}
</div>
<div class="col-sm-3 text-center">
<h4>Bills</h4>
@foreach (var val in Model.TotalBills)
{
<p>@Math.Round(val.Value, 2) @val.Key</p>
}
</div>
<div class="col-sm-3 text-center">
<h4>One-Time Payments</h4>
@foreach (var val in Model.TotalOneTimes)
{
<p>@Math.Round(val.Value, 2) @val.Key</p>
}
</div>
<div class="col-sm-3 text-center">
<h4>Net Profit</h4>
@foreach (var val in Model.TotalNet)
{
<p>@Math.Round(val.Value, 2) @val.Key</p>
}
</div>
</div>
@if (Model.Bills != null && Model.Bills.Any())
{
<h3>Bills</h3>
<div class="row">
<div class="col-sm-12">
<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#bills-section">View Bills</button>
</div>
</div>
<br />
<div id="bills-section" class="collapse in">
<div class="row">
<div class="col-sm-3">
<h4><strong>Date</strong></h4>
</div>
<div class="col-sm-2">
<h4><strong>Amount</strong></h4>
</div>
<div class="col-sm-7">
<h4><strong>Description</strong></h4>
</div>
</div>
@foreach (Bill bill in Model.Bills)
{
<div class="row">
<div class="col-sm-3">
@bill.DateSent.ToString("MMMM dd, yyyy")
</div>
<div class="col-sm-2">
@bill.Amount <var>@bill.Currency</var>
</div>
<div class="col-sm-7">
@bill.Reason
</div>
</div>
}
</div>
}
@if (Model.OneTimes != null && Model.OneTimes.Any())
{
<h3>One Time Payments</h3>
<div class="row">
<div class="col-sm-12">
<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#oneTime-section">View Payments</button>
</div>
</div>
<br />
<div id="oneTime-section" class="collapse in">
<div class="row">
<div class="col-sm-3">
<h4><strong>Date</strong></h4>
</div>
<div class="col-sm-2">
<h4><strong>Amount</strong></h4>
</div>
<div class="col-sm-7">
<h4><strong>Reason for Payment</strong></h4>
</div>
</div>
@foreach (OneTime oneTime in Model.OneTimes)
{
<div class="row">
<div class="col-sm-3">
@oneTime.DateSent.ToString("MMMM dd, yyyy")
</div>
<div class="col-sm-2">
@oneTime.Amount <var>@oneTime.Currency</var>
</div>
<div class="col-sm-7">
@oneTime.Reason
</div>
</div>
}
</div>
}
@if (Model.Donations != null && Model.Donations.Any())
{
<h3>Donations</h3>
<div class="row">
<div class="col-sm-12">
<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#donations-section">View Donations</button>
</div>
</div>
<br />
<div id="donations-section" class="collapse in">
<div class="row">
<div class="col-sm-3">
<h4><strong>Date</strong></h4>
</div>
<div class="col-sm-2">
<h4><strong>Amount</strong></h4>
</div>
<div class="col-sm-2">
<h4><strong>Donor</strong></h4>
</div>
<div class="col-sm-5">
<h4><strong>Reason for Donation</strong></h4>
</div>
</div>
@foreach (Donation donation in Model.Donations)
{
<div class="row">
<div class="col-sm-3">
@donation.DateSent.ToString("MMMM dd, yyyy")
</div>
<div class="col-sm-2">
@donation.Amount <var>@donation.Currency</var>
</div>
<div class="col-sm-2">
@donation.Sender
</div>
<div class="col-sm-5">
@donation.Reason
</div>
</div>
}
</div>
}
<br />
<h2 class="text-center"><b>Takedowns</b></h2>
<hr>
@if (Model.Takedowns != null && Model.Takedowns.Any())
{
<h3>Takedowns</h3>
<div class="row">
<div class="col-sm-12">
<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#takedowns-section">View Takedowns</button>
</div>
</div>
<br />
<div id="takedowns-section" class="collapse in">
<div class="row">
<div class="col-sm-2">
<h4><strong>Requester</strong></h4>
</div>
<div class="col-sm-2">
<h4><strong>Contact</strong></h4>
</div>
<div class="col-sm-2">
<h4><strong>Reason</strong></h4>
</div>
<div class="col-sm-2">
<h4><strong>Action Taken</strong></h4>
</div>
<div class="col-sm-2">
<h4><strong>Date Requested</strong></h4>
</div>
<div class="col-sm-2">
<h4><strong>Date Of Action</strong></h4>
</div>
</div>
@foreach (Takedown takedown in Model.Takedowns)
{
<div class="row">
<div class="col-sm-2">
@takedown.Requester
</div>
<div class="col-sm-2">
@takedown.RequesterContact
</div>
<div class="col-sm-2">
@takedown.Reason
</div>
<div class="col-sm-2">
@takedown.ActionTaken
</div>
<div class="col-sm-2">
@takedown.DateRequested.ToString("MMMM dd, yyyy")
</div>
<div class="col-sm-2">
@takedown.DateActionTaken.ToString("MMMM dd, yyyy")
</div>
</div>
}
</div>
}
<br />
</div>
</div>
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
@if (!string.IsNullOrEmpty(Model.Canary))
{
<pre>@Model.Canary</pre>
}
</div>
</div>
}
else
{
<div class="row">
<div class="col-sm-8 col-sm-offset-2 text-center">
<h3>Transparency Information has been disabled</h3>
</div>
</div>
}
</div>

View File

@ -1,3 +0,0 @@
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}

View File

@ -1,36 +0,0 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.Optimization" />
<add namespace="Teknik" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.webServer>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>

View File

@ -8,7 +8,7 @@ using Teknik.Migrations;
using Teknik.Areas.Upload.Models;
using Teknik.Areas.Paste.Models;
using Teknik.Areas.Podcast.Models;
using Teknik.Areas.Transparency.Models;
using Teknik.Areas.Status.Models;
using Teknik.Areas.Shortener.Models;
using Teknik.Attributes;
using System.Data.Entity.ModelConfiguration.Conventions;

Binary file not shown.

View File

@ -103,6 +103,10 @@
<HintPath>..\packages\MySql.Data.6.9.9\lib\net45\MySql.Data.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NBitcoin, Version=3.0.2.4, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NBitcoin.3.0.2.4\lib\net45\NBitcoin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nClam, Version=2.0.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\nClam.2.0.6.0\lib\net40-Client\nClam.dll</HintPath>
<Private>True</Private>
@ -259,8 +263,19 @@
<Compile Include="Areas\Privacy\PrivacyAreaRegistration.cs" />
<Compile Include="Areas\Privacy\ViewModels\PrivacyViewModel.cs" />
<Compile Include="Areas\Status\Controllers\StatusController.cs" />
<Compile Include="Areas\Status\Models\Bill.cs" />
<Compile Include="Areas\Status\Models\Donation.cs" />
<Compile Include="Areas\Status\Models\OneTime.cs" />
<Compile Include="Areas\Status\Models\Takedown.cs" />
<Compile Include="Areas\Status\Models\Transaction.cs" />
<Compile Include="Areas\Status\StatusAreaRegistration.cs" />
<Compile Include="Areas\Status\ViewModels\OneTimeViewModel.cs" />
<Compile Include="Areas\Status\ViewModels\DonationViewModel.cs" />
<Compile Include="Areas\Status\ViewModels\StatusViewModel.cs" />
<Compile Include="Areas\Status\ViewModels\TakedownViewModel.cs" />
<Compile Include="Areas\Status\ViewModels\TransactionsViewModel.cs" />
<Compile Include="Areas\Status\ViewModels\BillViewModel.cs" />
<Compile Include="Areas\Status\ViewModels\TransactionViewModel.cs" />
<Compile Include="Areas\User\Controllers\UserController.cs" />
<Compile Include="Areas\User\Models\BlogSettings.cs" />
<Compile Include="Areas\User\Models\ResetPasswordVerification.cs" />
@ -302,14 +317,6 @@
<Compile Include="Areas\TOS\Controllers\TOSController.cs" />
<Compile Include="Areas\TOS\TOSAreaRegistration.cs" />
<Compile Include="Areas\TOS\ViewModels\TOSViewModel.cs" />
<Compile Include="Areas\Transparency\Controllers\TransparencyController.cs" />
<Compile Include="Areas\Transparency\Models\Bill.cs" />
<Compile Include="Areas\Transparency\Models\Donation.cs" />
<Compile Include="Areas\Transparency\Models\OneTime.cs" />
<Compile Include="Areas\Transparency\Models\Takedown.cs" />
<Compile Include="Areas\Transparency\Models\Transaction.cs" />
<Compile Include="Areas\Transparency\TransparencyAreaRegistration.cs" />
<Compile Include="Areas\Transparency\ViewModels\TransparencyViewModel.cs" />
<Compile Include="Areas\Upload\Controllers\UploadController.cs" />
<Compile Include="Areas\Upload\Models\FileModel.cs" />
<Compile Include="Areas\Upload\Models\Upload.cs" />
@ -371,7 +378,6 @@
<Content Include="Areas\Podcast\Content\Podcast.css" />
<Content Include="Areas\Podcast\Scripts\Podcast.js" />
<Content Include="Areas\Status\Scripts\Status.js" />
<Content Include="Areas\Transparency\Scripts\Transparency.js" />
<Content Include="Areas\Upload\Content\Upload.css" />
<Content Include="Areas\User\Scripts\CheckAuthCode.js" />
<Content Include="Areas\User\Scripts\Profile.js" />
@ -564,9 +570,7 @@
<Content Include="Areas\Podcast\Views\Podcast\ViewPodcast.cshtml" />
<Content Include="App_Data\Config.json" />
<Content Include="Areas\User\Views\User\Settings.cshtml" />
<Content Include="Areas\Transparency\Views\web.config" />
<Content Include="Areas\Vault\Views\_ViewStart.cshtml" />
<Content Include="Areas\Transparency\Views\Transparency\Index.cshtml" />
<Content Include="Areas\Help\Views\Help\RSS.cshtml" />
<Content Include="Areas\Stream\Views\web.config" />
<Content Include="Areas\Stream\Views\_ViewStart.cshtml" />
@ -612,14 +616,18 @@
<Content Include="Fonts\fontawesome-webfont.eot" />
<Content Include="Areas\User\Views\User\AuthToken.cshtml" />
<Content Include="Areas\Error\Views\Error\Http401.cshtml" />
<Content Include="Areas\Transparency\Views\_ViewStart.cshtml" />
<Content Include="Areas\Vault\Views\Vault\ModifyVault.cshtml" />
<Content Include="Areas\Vault\Views\Vault\ModifyVaultItem.cshtml" />
<Content Include="Areas\Vault\Views\Vault\PasteItem.cshtml" />
<Content Include="Areas\Vault\Views\Vault\UploadItem.cshtml" />
<Content Include="Areas\Status\Views\web.config" />
<Content Include="Areas\Status\Views\_ViewStart.cshtml" />
<Content Include="Areas\Status\Views\Shared\Index.cshtml" />
<Content Include="Areas\Status\Views\Status\Index.cshtml" />
<Content Include="Areas\Status\Views\Status\Transactions.cshtml" />
<Content Include="Areas\Status\Views\Status\Bills.cshtml" />
<Content Include="Areas\Status\Views\Status\OneTimes.cshtml" />
<Content Include="Areas\Status\Views\Status\Donations.cshtml" />
<Content Include="Areas\Status\Views\Status\Takedowns.cshtml" />
<None Include="Properties\PublishProfiles\Teknik Dev.pubxml" />
<None Include="Properties\PublishProfiles\Teknik Production.pubxml" />
<None Include="Scripts\jquery-2.1.4.intellisense.js" />
@ -718,12 +726,10 @@
<Folder Include="Areas\Privacy\Models\" />
<Folder Include="Areas\Privacy\Views\Shared\" />
<Folder Include="Areas\Shortener\Views\Shared\" />
<Folder Include="Areas\Status\Models\" />
<Folder Include="Areas\Status\Views\Status\" />
<Folder Include="Areas\Status\Views\Shared\" />
<Folder Include="Areas\Stream\Views\Shared\" />
<Folder Include="Areas\TOS\Models\" />
<Folder Include="Areas\TOS\Views\Shared\" />
<Folder Include="Areas\Transparency\Views\Shared\" />
<Folder Include="Areas\Upload\Views\Shared\" />
<Folder Include="Areas\User\Repositories\" />
<Folder Include="Areas\User\Views\Shared\" />

View File

@ -51,7 +51,7 @@
}
<div class="row">
<div class="col-sm-5 col-sm-offset-1 text-left text-muted">
&copy; Teknik 2013-2017 | <a href="@Url.SubRouteUrl("privacy", "Privacy.Index")">Privacy</a> | <a href="@Url.SubRouteUrl("tos", "TOS.Index")">TOS</a> | <a href="@Url.SubRouteUrl("transparency", "Transparency.Index")">Transparency</a>
&copy; Teknik 2013-2017 | <a href="@Url.SubRouteUrl("privacy", "Privacy.Index")">Privacy</a> | <a href="@Url.SubRouteUrl("tos", "TOS.Index")">TOS</a> | <a href="@Url.SubRouteUrl("status", "Status.Index")">Status</a>
</div>
<div class="col-sm-5 text-right text-muted">
<div id="pagetime" style="display:none;">

View File

@ -32,6 +32,7 @@
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net46" userInstalled="true" />
<package id="Modernizr" version="2.8.3" targetFramework="net452" userInstalled="true" />
<package id="MySql.Data" version="6.9.9" targetFramework="net452" />
<package id="NBitcoin" version="3.0.2.4" targetFramework="net462" />
<package id="nClam" version="2.0.6.0" targetFramework="net462" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" userInstalled="true" />
<package id="Owin" version="1.0" targetFramework="net462" />

View File

@ -40,7 +40,6 @@ namespace Teknik.Configuration
private StreamConfig _StreamConfig;
private ShortenerConfig _ShortenerConfig;
private VaultConfig _VaultConfig;
private TransparencyConfig _TransparencyConfig;
private StatusConfig _StatusConfig;
private DatabaseConfig _DatabaseConfig;
private LoggingConfig _LoggingConfig;
@ -98,9 +97,6 @@ namespace Teknik.Configuration
// Vault Configuration
public VaultConfig VaultConfig { get { return _VaultConfig; } set { _VaultConfig = value; } }
// Transparency Configuration
public TransparencyConfig TransparencyConfig { get { return _TransparencyConfig; } set { _TransparencyConfig = value; } }
// Status Configuration
public StatusConfig StatusConfig { get { return _StatusConfig; } set { _StatusConfig = value; } }
@ -150,7 +146,6 @@ namespace Teknik.Configuration
StreamConfig = new StreamConfig();
ShortenerConfig = new ShortenerConfig();
VaultConfig = new VaultConfig();
TransparencyConfig = new TransparencyConfig();
StatusConfig = new StatusConfig();
DatabaseConfig = new DatabaseConfig();
LoggingConfig = new LoggingConfig();

View File

@ -63,7 +63,6 @@
<Compile Include="VaultConfig.cs" />
<Compile Include="ShortenerConfig.cs" />
<Compile Include="StreamConfig.cs" />
<Compile Include="TransparencyConfig.cs" />
<Compile Include="UploadConfig.cs" />
<Compile Include="UserConfig.cs" />
</ItemGroup>

View File

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Teknik.Configuration
{
public class TransparencyConfig
{
public bool Enabled { get; set; }
public string CanaryPath { get; set; }
public TransparencyConfig()
{
Enabled = false;
CanaryPath = string.Empty;
}
}
}

View File

@ -0,0 +1,78 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Teknik.Utilities
{
public static class CurrencyHelper
{
private static decimal m_CurrentBTCPrice = 0;
private static DateTime m_LastBTCQuery = DateTime.MinValue;
private static TimeSpan m_MaxBTCQueryTime = new TimeSpan(1, 0, 0); // Max query of every hour
/// <summary>
/// Gets the exchange rate for a given currency relative to USD
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
public static decimal GetExchangeRate(CurrencyType target)
{
decimal exchangeRate = 1;
switch (target)
{
case CurrencyType.USD:
exchangeRate = 1;
break;
case CurrencyType.BTC:
// get BTC usd price
exchangeRate = GetBTCPrice();
break;
}
return exchangeRate;
}
public static decimal GetBTCPrice()
{
DateTime curTime = DateTime.Now;
if (curTime - m_LastBTCQuery > m_MaxBTCQueryTime)
{
m_LastBTCQuery = curTime;
string url = "http://api.bitcoincharts.com/v1/weighted_prices.json";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
try
{
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
string jsonResult = reader.ReadToEnd();
JObject result = JsonConvert.DeserializeObject<JObject>(jsonResult);
if (result["USD"] != null)
{
string priceStr = result["USD"]["24h"].ToString();
decimal.TryParse(priceStr, out m_CurrentBTCPrice);
}
}
}
catch (WebException ex)
{
WebResponse errorResponse = ex.Response;
using (Stream responseStream = errorResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
}
}
}
return m_CurrentBTCPrice;
}
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Teknik.Utilities
{
public enum CurrencyType
{
USD,
BTC
}
}

View File

@ -105,6 +105,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CurrencyHelper.cs" />
<Compile Include="CurrencyType.cs" />
<Compile Include="FileGenerateResult.cs" />
<Compile Include="HttpWebResponseResult.cs" />
<Compile Include="BundleExtensions.cs" />