Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa58a7aee4 | ||
|
|
7b45a1171e | ||
|
|
b1cb61b51c | ||
|
|
768bfcc8eb | ||
|
|
8af91ea74b | ||
|
|
c785df3adf | ||
|
|
bb3f0fccd0 | ||
|
|
5c1ffbb8af | ||
|
|
ff4711e802 | ||
|
|
b8d6ac929b |
@@ -0,0 +1,9 @@
|
||||
<Application x:Class="DevconBoothImages.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:DevconBoothImages"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Windows;
|
||||
|
||||
namespace DevconBoothImages
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
@@ -0,0 +1,77 @@
|
||||
using CodexOpenApi;
|
||||
using IdentityModel.Client;
|
||||
using System.Net.Http;
|
||||
using System.Windows;
|
||||
using Utils;
|
||||
|
||||
namespace DevconBoothImages
|
||||
{
|
||||
public class Codexes
|
||||
{
|
||||
public Codexes(CodexApi local, CodexApi testnet)
|
||||
{
|
||||
Local = local;
|
||||
Testnet = testnet;
|
||||
}
|
||||
|
||||
public CodexApi Local { get; }
|
||||
public CodexApi Testnet { get; }
|
||||
}
|
||||
|
||||
public class CodexWrapper
|
||||
{
|
||||
public async Task<Codexes> GetCodexes()
|
||||
{
|
||||
var config = new Configuration();
|
||||
return new Codexes(
|
||||
await GetCodexWithPort(config.CodexLocalEndpoint),
|
||||
await GetCodexWithoutPort(config.CodexPublicEndpoint, config.AuthUser, config.AuthPw)
|
||||
);
|
||||
}
|
||||
|
||||
private async Task<CodexApi> GetCodexWithPort(string endpoint)
|
||||
{
|
||||
var splitIndex = endpoint.LastIndexOf(':');
|
||||
var host = endpoint.Substring(0, splitIndex);
|
||||
var port = Convert.ToInt32(endpoint.Substring(splitIndex + 1));
|
||||
|
||||
var address = new Address(
|
||||
host: host,
|
||||
port: port
|
||||
);
|
||||
|
||||
var client = new HttpClient();
|
||||
var codex = new CodexApi(client);
|
||||
codex.BaseUrl = $"{address.Host}:{address.Port}/api/codex/v1";
|
||||
|
||||
await CheckCodex(codex, endpoint);
|
||||
return codex;
|
||||
}
|
||||
|
||||
private async Task<CodexApi> GetCodexWithoutPort(string endpoint, string user, string pw)
|
||||
{
|
||||
var client = new HttpClient();
|
||||
client.SetBasicAuthentication(user, pw);
|
||||
var codex = new CodexApi(client);
|
||||
codex.BaseUrl = $"{endpoint}/api/codex/v1";
|
||||
|
||||
await CheckCodex(codex, endpoint);
|
||||
return codex;
|
||||
}
|
||||
|
||||
private async Task CheckCodex(CodexApi codex, string endpoint)
|
||||
{
|
||||
try
|
||||
{
|
||||
var info = await codex.GetDebugInfoAsync();
|
||||
if (string.IsNullOrEmpty(info.Id)) throw new Exception("Failed to fetch Codex node id");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Failed to connect to codex '{endpoint}': {ex}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace DevconBoothImages
|
||||
{
|
||||
public class Configuration
|
||||
{
|
||||
public string CodexLocalEndpoint { get; } = "http://localhost:8080";
|
||||
public string CodexPublicEndpoint { get; } = "https://api.testnet.codex.storage/storage/node-9";
|
||||
|
||||
public string AuthUser { get; } = "";
|
||||
public string AuthPw { get; } = "";
|
||||
public string LocalNodeBootstrapInfo { get; } = "";
|
||||
public string WorkingDir { get; } = "D:\\DevconBoothApp";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ProjectPlugins\CodexPlugin\CodexPlugin.csproj" />
|
||||
<ProjectReference Include="..\Tools\AutoClient\AutoClient.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Update="App.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="MainWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,38 @@
|
||||
<Window x:Class="DevconBoothImages.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:DevconBoothImages"
|
||||
mc:Ignorable="d"
|
||||
Title="CodexBoothImages" Height="450" Width="800" WindowState="Maximized">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.Column="0" Name="Img" />
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="Instructions:"/>
|
||||
<Image Name="ImgInstructions" />
|
||||
<TextBlock Text="Local CID:"/>
|
||||
<Image Name="ImgLocalCid" />
|
||||
<TextBlock Text="TestNet CID:"/>
|
||||
<Image Name="ImgTestnetCid" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Row="1">
|
||||
<TextBlock Name="Txt" HorizontalAlignment="Center" />
|
||||
<Button Content="Check Codex connections" Click="Button_Click_2" />
|
||||
<Button Content="Generate image -> Upload to Codex -> Put CID info in clipboard" Padding="10" Click="Button_Click"/>
|
||||
<Button Content="Put last CID info in clipboard" Padding="10" Click="Button_Click_1"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,160 @@
|
||||
using AutoClient;
|
||||
using CodexOpenApi;
|
||||
using Logging;
|
||||
using QRCoder;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace DevconBoothImages
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private readonly Configuration config = new Configuration();
|
||||
private readonly CodexWrapper codexWrapper = new CodexWrapper();
|
||||
private readonly ImageGenerator imageGenerator = new ImageGenerator(new NullLog());
|
||||
private string currentLocalCid = string.Empty;
|
||||
private string currentPublicCid = string.Empty;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
|
||||
}
|
||||
|
||||
private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
MessageBox.Show("Unhandled exception: " + e.Exception);
|
||||
}
|
||||
|
||||
private async void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// image
|
||||
Log("Getting image...");
|
||||
var file = await imageGenerator.Generate();
|
||||
var filename = Path.Combine(config.WorkingDir, file);
|
||||
File.Copy(file, filename);
|
||||
|
||||
var bmp = new BitmapImage();
|
||||
bmp.BeginInit();
|
||||
bmp.UriSource = new Uri(filename);
|
||||
bmp.EndInit();
|
||||
Img.Source = bmp;
|
||||
|
||||
Log("Uploading...");
|
||||
// upload
|
||||
await UploadToCodexes(filename, file);
|
||||
|
||||
// clipboard info
|
||||
InfoToClipboard();
|
||||
}
|
||||
|
||||
private BitmapImage GenerateQr(string text)
|
||||
{
|
||||
using (QRCodeGenerator qrGenerator = new QRCodeGenerator())
|
||||
using (QRCodeData qrCodeData = qrGenerator.CreateQrCode(text, QRCodeGenerator.ECCLevel.Default))
|
||||
using (PngByteQRCode qrCode = new PngByteQRCode(qrCodeData))
|
||||
{
|
||||
byte[] qrCodeImage = qrCode.GetGraphic(7);
|
||||
using (var ms = new MemoryStream(qrCodeImage))
|
||||
{
|
||||
var img = Image.FromStream(ms);
|
||||
using (var ms2 = new MemoryStream())
|
||||
{
|
||||
img.Save(ms2, ImageFormat.Png);
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.StreamSource = ms2;
|
||||
bitmapImage.EndInit();
|
||||
|
||||
return bitmapImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void Button_Click_1(object sender, RoutedEventArgs e)
|
||||
{
|
||||
InfoToClipboard();
|
||||
}
|
||||
|
||||
private async void Button_Click_2(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// check codexes
|
||||
Log("Checking Codex connections...");
|
||||
await codexWrapper.GetCodexes();
|
||||
Log("Connections OK");
|
||||
}
|
||||
|
||||
private async Task UploadToCodexes(string filename, string shortName)
|
||||
{
|
||||
var codexes = await codexWrapper.GetCodexes();
|
||||
try
|
||||
{
|
||||
currentLocalCid = await UploadFile(filename, shortName, codexes.Local);
|
||||
currentPublicCid = await UploadFile(filename, shortName, codexes.Testnet);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Upload failed: " + ex);
|
||||
}
|
||||
Log($"Generated CIDs");
|
||||
}
|
||||
|
||||
private async Task<string> UploadFile(string filename, string shortName, CodexApi codex)
|
||||
{
|
||||
using (var fileStream = File.OpenRead(filename))
|
||||
{
|
||||
var response = await codex.UploadAsync(
|
||||
"image/jpeg",
|
||||
$"attachment; filename=\"{shortName}\"",
|
||||
fileStream);
|
||||
|
||||
if (string.IsNullOrEmpty(response) ||
|
||||
response.ToLowerInvariant().Contains("unable to store block"))
|
||||
{
|
||||
throw new Exception("Unable to upload image. Response empty or error message.");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
private void InfoToClipboard()
|
||||
{
|
||||
Clipboard.Clear();
|
||||
if (string.IsNullOrEmpty(currentLocalCid) || string.IsNullOrEmpty(currentPublicCid))
|
||||
{
|
||||
Log("No CIDs were generated! Clipboard cleared.");
|
||||
return;
|
||||
}
|
||||
|
||||
var nl = Environment.NewLine;
|
||||
var msg =
|
||||
$"** Codex@Devcon 💻 Raspberry Pi Challenge **{nl}" +
|
||||
$"📢 A new image is available. Download it and bring it to the booth!{nl}" +
|
||||
$"Public Testnet CID: `{currentPublicCid}`{nl}" +
|
||||
$"Local Devcon network CID: `{currentLocalCid}`{nl}" +
|
||||
$"Setup instructions: [Here](https://docs.codex.storage){nl}" +
|
||||
$"Local Devcon network information: [Here](https://github.com/codex-storage/codex-testnet-starter/blob/master/SETUP_DEVCONNET.md)";
|
||||
|
||||
Clipboard.SetText(msg);
|
||||
Log("CID info copied to clipboard. Paste it in Discord plz!");
|
||||
|
||||
ImgLocalCid.Source = GenerateQr(currentLocalCid);
|
||||
ImgTestnetCid.Source = GenerateQr(currentPublicCid);
|
||||
ImgInstructions.Source = GenerateQr("https://github.com/codex-storage/codex-testnet-starter/blob/master/SETUP_DEVCONNET.md");
|
||||
}
|
||||
|
||||
private void Log(string v)
|
||||
{
|
||||
Txt.Text = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -10,7 +10,7 @@ namespace CodexPlugin
|
||||
public class ApiChecker
|
||||
{
|
||||
// <INSERT-OPENAPI-YAML-HASH>
|
||||
private const string OpenApiYamlHash = "39-0C-32-A3-EA-90-4F-29-1C-67-12-F1-D5-BE-31-67-8D-90-43-1E-F2-02-63-5B-0C-49-F7-1E-E5-EC-F7-00";
|
||||
private const string OpenApiYamlHash = "09-53-C3-A6-31-A5-0C-8B-53-1C-3D-C7-2B-1E-85-C7-17-60-54-43-01-C4-49-4E-D9-68-35-7D-F7-41-13-B5";
|
||||
private const string OpenApiFilePath = "/codex/openapi.yaml";
|
||||
private const string DisableEnvironmentVariable = "CODEXPLUGIN_DISABLE_APICHECK";
|
||||
|
||||
|
||||
@@ -63,10 +63,10 @@ namespace CodexPlugin
|
||||
});
|
||||
}
|
||||
|
||||
public string UploadFile(FileStream fileStream, Action<Failure> onFailure)
|
||||
public string UploadFile(UploadInput uploadInput, Action<Failure> onFailure)
|
||||
{
|
||||
return OnCodex(
|
||||
api => api.UploadAsync(fileStream),
|
||||
api => api.UploadAsync(uploadInput.ContentType, uploadInput.ContentDisposition, uploadInput.FileStream),
|
||||
CreateRetryConfig(nameof(UploadFile), onFailure));
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace CodexPlugin
|
||||
|
||||
public LocalDatasetList LocalFiles()
|
||||
{
|
||||
return mapper.Map(OnCodex(api => api.ListDataAsync("", "")));
|
||||
return mapper.Map(OnCodex(api => api.ListDataAsync()));
|
||||
}
|
||||
|
||||
public StorageAvailability SalesAvailability(StorageAvailability request)
|
||||
@@ -261,4 +261,18 @@ namespace CodexPlugin
|
||||
log.Log($"{GetName()} {msg}");
|
||||
}
|
||||
}
|
||||
|
||||
public class UploadInput
|
||||
{
|
||||
public UploadInput(string contentType, string contentDisposition, FileStream fileStream)
|
||||
{
|
||||
ContentType = contentType;
|
||||
ContentDisposition = contentDisposition;
|
||||
FileStream = fileStream;
|
||||
}
|
||||
|
||||
public string ContentType { get; }
|
||||
public string ContentDisposition { get; }
|
||||
public FileStream FileStream { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace CodexPlugin
|
||||
DebugPeer GetDebugPeer(string peerId);
|
||||
ContentId UploadFile(TrackedFile file);
|
||||
ContentId UploadFile(TrackedFile file, Action<Failure> onFailure);
|
||||
ContentId UploadFile(TrackedFile file, string contentType, string contentDisposition, Action<Failure> onFailure);
|
||||
TrackedFile? DownloadContent(ContentId contentId, string fileLabel = "");
|
||||
TrackedFile? DownloadContent(ContentId contentId, Action<Failure> onFailure, string fileLabel = "");
|
||||
LocalDatasetList LocalFiles();
|
||||
@@ -138,6 +139,11 @@ namespace CodexPlugin
|
||||
}
|
||||
|
||||
public ContentId UploadFile(TrackedFile file, Action<Failure> onFailure)
|
||||
{
|
||||
return UploadFile(file, "application/x-binary", $"attachment; filename=\"{file.Filename}\"", onFailure);
|
||||
}
|
||||
|
||||
public ContentId UploadFile(TrackedFile file, string contentType, string contentDisposition, Action<Failure> onFailure)
|
||||
{
|
||||
using var fileStream = File.OpenRead(file.Filename);
|
||||
var uniqueId = Guid.NewGuid().ToString();
|
||||
@@ -145,10 +151,11 @@ namespace CodexPlugin
|
||||
|
||||
hooks.OnFileUploading(uniqueId, size);
|
||||
|
||||
var logMessage = $"Uploading file {file.Describe()}...";
|
||||
var input = new UploadInput(contentType, contentDisposition, fileStream);
|
||||
var logMessage = $"Uploading file {file.Describe()} with contentType: '{input.ContentType}' and disposition: '{input.ContentDisposition}'...";
|
||||
var measurement = Stopwatch.Measure(log, logMessage, () =>
|
||||
{
|
||||
return CodexAccess.UploadFile(fileStream, onFailure);
|
||||
return CodexAccess.UploadFile(input, onFailure);
|
||||
});
|
||||
|
||||
var response = measurement.Value;
|
||||
|
||||
@@ -443,21 +443,6 @@ paths:
|
||||
summary: "Lists manifest CIDs stored locally in node."
|
||||
tags: [ Data ]
|
||||
operationId: listData
|
||||
parameters:
|
||||
- name: content-type
|
||||
in: header
|
||||
required: false
|
||||
description: The content type of the file. Must be valid.
|
||||
schema:
|
||||
type: string
|
||||
example: "image/png"
|
||||
- name: content-disposition
|
||||
in: header
|
||||
required: false
|
||||
description: The content disposition used to send the filename.
|
||||
schema:
|
||||
type: string
|
||||
example: "attachment; filename=\"codex.png\""
|
||||
responses:
|
||||
"200":
|
||||
description: Retrieved list of content CIDs
|
||||
@@ -478,6 +463,21 @@ paths:
|
||||
summary: "Upload a file in a streaming manner. Once finished, the file is stored in the node and can be retrieved by any node in the network using the returned CID."
|
||||
tags: [ Data ]
|
||||
operationId: upload
|
||||
parameters:
|
||||
- name: content-type
|
||||
in: header
|
||||
required: false
|
||||
description: The content type of the file. Must be valid.
|
||||
schema:
|
||||
type: string
|
||||
example: "image/png"
|
||||
- name: content-disposition
|
||||
in: header
|
||||
required: false
|
||||
description: The content disposition used to send the filename.
|
||||
schema:
|
||||
type: string
|
||||
example: "attachment; filename=\"codex.png\""
|
||||
requestBody:
|
||||
content:
|
||||
application/octet-stream:
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace AutoClient
|
||||
{
|
||||
var info = new FileInfo(filename);
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
var cid = await UploadStream(fileStream);
|
||||
var cid = await UploadStream(fileStream, filename);
|
||||
var time = sw.Elapsed;
|
||||
app.Performance.UploadSuccessful(info.Length, time);
|
||||
app.CidRepo.Add(nodeId, cid.Id, info.Length);
|
||||
@@ -132,10 +132,13 @@ namespace AutoClient
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ContentId> UploadStream(FileStream fileStream)
|
||||
private async Task<ContentId> UploadStream(FileStream fileStream, string filename)
|
||||
{
|
||||
log.Debug($"Uploading file...");
|
||||
var response = await codex.UploadAsync(fileStream, app.Cts.Token);
|
||||
var response = await codex.UploadAsync(
|
||||
content_type: "application/x-binary",
|
||||
content_disposition: $"attachment; filename=\"{filename}\"",
|
||||
fileStream, app.Cts.Token);
|
||||
|
||||
if (string.IsNullOrEmpty(response)) FrameworkAssert.Fail("Received empty response.");
|
||||
if (response.StartsWith("Unable to store block")) FrameworkAssert.Fail("Node failed to store block.");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using CodexOpenApi;
|
||||
using IdentityModel.Client;
|
||||
using Logging;
|
||||
using Utils;
|
||||
|
||||
namespace BiblioTech
|
||||
@@ -8,11 +9,13 @@ namespace BiblioTech
|
||||
{
|
||||
private static readonly string nl = Environment.NewLine;
|
||||
private readonly Configuration config;
|
||||
private readonly ILog log;
|
||||
private CodexApi? currentCodexNode;
|
||||
|
||||
public CodexCidChecker(Configuration config)
|
||||
public CodexCidChecker(Configuration config, ILog log)
|
||||
{
|
||||
this.config = config;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public async Task<CheckResponse> PerformCheck(string cid)
|
||||
@@ -150,6 +153,7 @@ namespace BiblioTech
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error(e.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace BiblioTech
|
||||
client = new DiscordSocketClient();
|
||||
client.Log += ClientLog;
|
||||
|
||||
var checker = new CodexCidChecker(Config);
|
||||
var checker = new CodexCidChecker(Config, Log);
|
||||
var notifyCommand = new NotifyCommand();
|
||||
var associateCommand = new UserAssociateCommand(notifyCommand);
|
||||
var sprCommand = new SprCommand();
|
||||
|
||||
@@ -76,7 +76,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TranscriptAnalysis", "Tools
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarketInsights", "Tools\MarketInsights\MarketInsights.csproj", "{004614DF-1C65-45E3-882D-59AE44282573}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsvCombiner", "Tools\CsvCombiner\CsvCombiner.csproj", "{6230347F-5045-4E25-8E7A-13D7221B7444}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CsvCombiner", "Tools\CsvCombiner\CsvCombiner.csproj", "{6230347F-5045-4E25-8E7A-13D7221B7444}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevconBoothImages", "DevconBoothImages\DevconBoothImages.csproj", "{92AC64E7-F6B1-474E-B915-30C8EEE2F9D7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -208,6 +210,10 @@ Global
|
||||
{6230347F-5045-4E25-8E7A-13D7221B7444}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6230347F-5045-4E25-8E7A-13D7221B7444}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6230347F-5045-4E25-8E7A-13D7221B7444}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{92AC64E7-F6B1-474E-B915-30C8EEE2F9D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{92AC64E7-F6B1-474E-B915-30C8EEE2F9D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{92AC64E7-F6B1-474E-B915-30C8EEE2F9D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{92AC64E7-F6B1-474E-B915-30C8EEE2F9D7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -244,6 +250,7 @@ Global
|
||||
{C0EEBD32-23CB-45EC-A863-79FB948508C8} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3}
|
||||
{004614DF-1C65-45E3-882D-59AE44282573} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3}
|
||||
{6230347F-5045-4E25-8E7A-13D7221B7444} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3}
|
||||
{92AC64E7-F6B1-474E-B915-30C8EEE2F9D7} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {237BF0AA-9EC4-4659-AD9A-65DEB974250C}
|
||||
|
||||
Reference in New Issue
Block a user