How can i make a "github client" with Octokit.Net in C#? - c#

I use the tool Octokit.net to make an own GitHub client and my question is how can I delete the files in the repository when they aren't in the local folder anymore?
This is the code I already have:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Reactive.Linq;
using System.IO;
using Octokit;
using Octokit.Internal;
using Octokit.Reactive;
class Program
{
static void Main(string[] args)
{
MainAsync(args[0], args[1], args[2], args[3]).Wait();
}
static async Task MainAsync(string rootPath, string owner, string repo, string branch)
{
var github = new GitHubClient(new ProductHeaderValue("repository"));
var user = await github.User.Get("username");
github.Credentials = new Credentials("token");
var contents = await github.Repository.Content.GetAllContents(owner, repo);
foreach(var githubFilePath in contents)
{
Console.WriteLine(githubFilePath);
}
Console.WriteLine(contents);
UpdateFull().Wait();
// Update a whole folder
async Task UpdateFull()
{
updateGithub(rootPath).Wait();
async Task updateGithub(string path)
{
var localContents = Directory.GetFiles(path);
var localContentFolders = Directory.GetDirectories(path);
var headMasterRef = "heads/master";
var masterReference = await github.Git.Reference.Get(owner, repo, headMasterRef);
var latestCommit = await github.Git.Commit.Get(owner, repo, masterReference.Object.Sha);
var nt = new NewTree { BaseTree = latestCommit.Tree.Sha };
// Add items based on blobs
AddDirectoryToTree(path, path + "\\", nt).Wait();
var rootTree = await github.Git.Tree.Create(owner, repo, nt);
// Create Commit
var newCommit = new NewCommit("Commit test with several files", rootTree.Sha, masterReference.Object.Sha);
var commit = await github.Git.Commit.Create(owner, repo, newCommit);
await github.Git.Reference.Update(owner, repo, headMasterRef, new ReferenceUpdate(commit.Sha));
}
async Task AddDirectoryToTree(string DirectoryPath, string RootPath, NewTree Tree)
{
// all direct files in the folder
//
var localContents = Directory.GetFiles(DirectoryPath);
foreach (var filePath in localContents)
{
string sExtension = Path.GetExtension(filePath).ToUpper();
string sFilename = filePath.Replace(RootPath, "").Replace(#"\", "/");
Console.WriteLine("File(Local): " + sFilename);
switch (sExtension)
{
default:
// Create text blob
var textBlob = new NewBlob { Encoding = EncodingType.Utf8, Content = File.ReadAllText(filePath) };
var textBlobRef = await github.Git.Blob.Create(owner, repo, textBlob);
Tree.Tree.Add(new NewTreeItem { Path = sFilename, Mode = "100644", Type = TreeType.Blob, Sha = textBlobRef.Sha });
break;
case ".PNG":
case ".JPEG":
case ".JPG":
// For image, get image content and convert it to base64
var imgBase64 = Convert.ToBase64String(File.ReadAllBytes(filePath));
// Create image blob
var imgBlob = new NewBlob { Encoding = EncodingType.Base64, Content = (imgBase64) };
var imgBlobRef = await github.Git.Blob.Create(owner, repo, imgBlob);
Tree.Tree.Add(new NewTreeItem { Path = sFilename, Mode = "100644", Type = TreeType.Blob, Sha = imgBlobRef.Sha });
break;
}
}
// subfolder
//
var localContentFolders = Directory.GetDirectories(DirectoryPath);
foreach (string subDirPath in localContentFolders)
{
AddDirectoryToTree(subDirPath, RootPath, Tree).Wait();
}
}
}
Console.WriteLine("-----------------------------------");
Console.WriteLine("Successfully commited Files");
Console.ReadKey();
Do I maybe need to add a new foreach for the Github repository and make then an if statement to look at the repository and local folder? :o
Would appreciateif you guys could help me with that! :D

Related

Add file to existing table from ASP.NET MVC

I am just trying to learn ASP.NET MVC and am having an issue, well not so much of an issue but lack of understanding any is not working I am trying to update an SQL table, the code below works fine if I want to delete a table but all I want to do is to add another file to the data table
public async Task<IActionResult> DeleteSnTFileFromFileSystem(int id)
{
var file = await context.SnTModels.Where(x => x.Id == id).FirstOrDefaultAsync();
if (file == null)
return null;
var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\wwwroot" + file.FilePath);
if (System.IO.File.Exists(basePath))
{
System.IO.File.Delete(basePath);
}
context.SnTModels.Remove(file);
context.SaveChanges();
TempData["Message"] = $"Removed {file.Name + file.Extension} successfully from File System.";
return RedirectToAction("Scenario");
}
Here is my code to create the table
[HttpPost]
public async Task<IActionResult> SnTUploadToFileSystem(List<IFormFile> files, string description)
{
foreach (var file in files)
{
var subPath = "\\*dir file\\";
var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\wwwroot" + subPath);
bool basePathExists = System.IO.Directory.Exists(basePath);
if (!basePathExists)
Directory.CreateDirectory(basePath);
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
var filePath = Path.Combine(basePath, file.FileName);
var extension = Path.GetExtension(file.FileName);
if (!System.IO.File.Exists(filePath))
{
// saving our file to the file system
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
// creating a model and save this model into the db
var SnTModel = new SnTOnFileSystem
{
CreatedOn = DateTime.UtcNow,
FileType = file.ContentType,
Extension = extension,
Name = fileName,
Description = description,
FilePath = subPath + file.FileName
};
context.SnTModels.Add(SnTModel);
context.SaveChanges();
}
}
TempData["Message"] = "File successfully uploaded to File System.";
return RedirectToAction("Index");
}
Here is the post to update the table
[HttpPost]
public async Task<IActionResult> SnTUpdateToFileSystem(List<IFormFile> files, int id)
{
var file = files[0];
var subPath = "\\Training\\SnT\\Document\\";
var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\wwwroot" + subPath);
bool basePathExists = System.IO.Directory.Exists(basePath);
if (!basePathExists)
Directory.CreateDirectory(basePath);
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
var documentFilePath = Path.Combine(basePath, file.FileName);
var extension = Path.GetExtension(file.FileName);
if (!System.IO.File.Exists(documentFilePath))
{
// saving our file to the file system
using (var stream = new FileStream(documentFilePath, FileMode.OpenOrCreate))
{
await file.CopyToAsync(stream);
}
// creating a model and save this model into the db
var SnTModel = new SnTOnFileSystem
{
Name = fileName,
DocumentFilePath = subPath + file.FileName
};
context.SnTModels.Update(SnTModel);
context.SaveChanges();
}
TempData["Message"] = "Document successfully uploaded to File System.";
return RedirectToAction("Scenario");
}

Upload file in asp.net and angular 7 null

I upload image from angular to .net core but the file input I receive always null , with the postman , it's receive exactly. I don't know why ?
Can you help me how to solve it?
Thank you so much !
[HttpPost("upload-file")]
public async Task<IActionResult> UploadFile(IFormFile file)
{
try
{
//var file = Request.Form.Files[0];
var rnd = FileHelper.RandomNumber();
//var file = file;
var folder = "Folder";
var index = file.FileName.LastIndexOf('.');
var onlyName = file.FileName.Substring(0, index);
var fileName = onlyName + rnd;
var extension = Path.GetExtension(file.FileName);
var folderThumb = folder + "Thumbnail";
var fileNameThumb = fileName + "Thumbnail";
var t1 = Task.Run(() => FileHelper.SaveFile(folder, fileName, file));
await Task.WhenAll(t1);
var path = new MediaResponseModel()
{
Url = Url.Action("GetFile", "Media", new { folder = folder, fileName = string.Format("{0}{1}", fileName, extension) }, Request.Scheme),
UrlThumbnail = Url.Action("GetFile", "Media", new { folder = folderThumb, fileName = string.Format("{0}{1}", fileNameThumb, extension) }, Request.Scheme),
Title = onlyName
};
return Ok(path);
}
catch (System.Exception e)
{
throw e;
}
}
handleFileInput(files: FileList) {
const file = files.item(0);
this.fileToUpload = {};
this.fileToUpload.data = files.item(0);
this.fileToUpload.fileName = files.item(0).name;
}
onUpload() {
const formData = new FormData();
formData.append('file', this.fileToUpload.data, this.fileToUpload.name);
this.http.post('http://localhost:56000/api/media/upload-file', formData).subscribe(res => console.log(res));
}

Azure File Storage: Create nested directories

My code looks like this
CloudFileClient client = ...;
client.GetShareReference("fileStorageShare")
.GetRootDirectoryReference()
.GetDirectoryReference("one/two/three")
.Create();
This errors if directories one or two don't exist. Is there a way to create these nested directories with a single call?
It is impossible. The SDK does not support it this way, you should create them one by one.
A issue has already submitted here.
If you wanna create them one by one, you can use the following sample code:
static void NestedDirectoriesTest()
{
var cred = new StorageCredentials(accountName, accountKey);
var account = new CloudStorageAccount(cred, true);
var client = account.CreateCloudFileClient();
var share = client.GetShareReference("temp2");
share.CreateIfNotExists();
var cloudFileDirectory = share.GetRootDirectoryReference();
//Specify the nested folder
var nestedFolderStructure = "Folder/SubFolder";
var delimiter = new char[] { '/' };
var nestedFolderArray = nestedFolderStructure.Split(delimiter);
for (var i=0; i<nestedFolderArray.Length; i++)
{
cloudFileDirectory = cloudFileDirectory.GetDirectoryReference(nestedFolderArray[i]);
cloudFileDirectory.CreateIfNotExists();
Console.WriteLine(cloudFileDirectory.Name + " created...");
}
}
Following the advice of Ivan Yang, I adapted my code using Azure.Storage.Files.Shares (Version=12.2.3.0).
Here's my contribution:
readonly string storageConnectionString = "yourConnectionString";
readonly string shareName = "yourShareName";
public string StoreFile(string dirName,string fileName, Stream fileContent)
{
// Get a reference to a share and then create it
ShareClient share = new ShareClient(storageConnectionString, shareName);
share.CreateIfNotExists();
// Get a reference to a directory and create it
string[] arrayPath = dirName.Split('/');
string buildPath = string.Empty;
var tempoShare = share;
ShareDirectoryClient directory = null; // share.GetDirectoryClient(dirName);
// Here's goes the nested directories builder
for (int i=0; i < arrayPath.Length; i++)
{
buildPath += arrayPath[i];
directory = share.GetDirectoryClient(buildPath);
directory.CreateIfNotExists();
buildPath += '/';
}
// Get a reference to a file and upload it
ShareFileClient file = directory.GetFileClient(fileName);
using (Stream stream = fileContent)
{
file.Create(stream.Length);
file.UploadRange(new HttpRange(0, stream.Length), stream);
}
return directory.Path;
}
Here is a simplified version of Hagen's code:
public async Task<ShareFileClient> CreateFileClient(string connection, string shareName, string path)
{
var share = new ShareClient(connection, shareName);
await share.CreateIfNotExistsAsync();
var dir = share.GetRootDirectoryClient();
var pathChain = path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
int dirCount = pathChain.Length - 1;
for (int i = 0; i < dirCount; ++i)
{
dir = dir.GetSubdirectoryClient(pathChain[i]);
await dir.CreateIfNotExistsAsync();
}
return dir.GetFileClient(pathChain[dirCount]);
}

The 'await' operator can only be used within an async > method

I have the following controller:
[Authorize]
public class SetupController : ApiController
{
[HttpPost]
public Task async SetupPartnerPackAsync(SetupInformation info)
{
if (info.SslCertificateGenerate)
{
SetupManager.CreateX509Certificate(info);
}
else
{
SetupManager.LoadX509Certificate(info);
}
info.SslCertificateThumbprint = SetupManager.GetX509CertificateThumbprint(info);
info.AzureAppKeyCredential = SetupManager.GetX509CertificateInformation(info);
await SetupManager.RegisterAzureADApplication(info);
}
}
But I have the following 2 error which seems simple:
Severity Code Description Project File Line Suppression State
Error CS1520 Method must have a return
type InnovationInABoxWebApi H:\InnovationInABoxWebApi\InnovationInABoxWebApi\Controllers\SetupController.cs 24 Active
Severity Code Description Project File Line Suppression State
Error CS4033 The 'await' operator can only be used within an async
method. Consider marking this method with the 'async' modifier and
changing its return type to
'Task'. InnovationInABoxWebApi H:\InnovationInABoxWebApi\InnovationInABoxWebApi\Controllers\SetupController.cs 39 Active
However I am not sure how to fix this, as the operation can take some time to complete, it really needs to be asybnc
and the setupmanager
using CERTENROLLLib;
using Microsoft.Identity.Client;
using Microsoft.Online.SharePoint.TenantAdministration;
using Microsoft.SharePoint.Client;
using Newtonsoft.Json;
using OfficeDevPnP.Core;
using OfficeDevPnP.Core.Entities;
using OfficeDevPnP.Core.Framework.Provisioning.Model;
using OfficeDevPnP.Core.Framework.Provisioning.ObjectHandlers;
using OfficeDevPnP.Core.Framework.Provisioning.Providers.Xml;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Resources;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Xml.Linq;
namespace InnovationInABoxWebApi.Components
{
public static class SetupManager
{
public static String GetX509CertificateThumbprint(SetupInformation info)
{
var certificate = info.AuthenticationCertificate;
return (certificate.Thumbprint.ToUpper());
}
public static String GetX509CertificateInformation(SetupInformation info)
{
// var basePath = String.Format(#"{0}..\..\..\..\Scripts\", AppDomain.CurrentDomain.BaseDirectory);
var certificate = info.AuthenticationCertificate;
//var certificate = new X509Certificate2();
//if (info.SslCertificateGenerate)
//{
// certificate.Import($#"{basePath}{info.SslCertificateCommonName}.cer");
//}
//else
//{
// certificate = new X509Certificate2(info.SslCertificateFile, info.SslCertificatePassword);
//}
var rawCert = certificate.GetRawCertData();
var base64Cert = System.Convert.ToBase64String(rawCert);
var rawCertHash = certificate.GetCertHash();
var base64CertHash = System.Convert.ToBase64String(rawCertHash);
var KeyId = System.Guid.NewGuid().ToString();
var keyCredential =
"{" +
"\"customKeyIdentifier\": \"" + base64CertHash + "\"," +
"\"keyId\": \"" + KeyId + "\"," +
"\"type\": \"AsymmetricX509Cert\"," +
"\"usage\": \"Verify\"," +
"\"key\": \"" + base64Cert + "\"" +
"}";
return (keyCredential);
}
public static void CreateX509Certificate(SetupInformation info)
{
var certificate = CreateSelfSignedCertificate(info.SslCertificateCommonName.ToLower(),
info.SslCertificateStartDate, info.SslCertificateEndDate, info.SslCertificatePassword);
SaveCertificateFiles(info, certificate);
}
public static void LoadX509Certificate(SetupInformation info)
{
var certificate = new X509Certificate2(info.SslCertificateFile, info.SslCertificatePassword);
info.AuthenticationCertificate = certificate;
info.SslCertificateCommonName = certificate.SubjectName.Name;
}
public static void SaveCertificateFiles(SetupInformation info, X509Certificate2 certificate)
{
info.AuthenticationCertificate = certificate;
//var basePath = String.Format(#"{0}..\..\..\..\Scripts\", AppDomain.CurrentDomain.BaseDirectory);
//info.SslCertificateFile = $#"{basePath}{info.SslCertificateCommonName}.pfx";
//var pfx = certificate.Export(X509ContentType.Pfx, info.SslCertificatePassword);
//System.IO.File.WriteAllBytes(info.SslCertificateFile, pfx);
//var cer = certificate.Export(X509ContentType.Cert);
//System.IO.File.WriteAllBytes($#"{basePath}{info.SslCertificateCommonName}.cer", cer);
}
public static X509Certificate2 CreateSelfSignedCertificate(string subjectName, DateTime startDate, DateTime endDate, String password)
{
// Create DistinguishedName for subject and issuer
var name = new CX500DistinguishedName();
name.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);
// Create a new Private Key for the certificate
CX509PrivateKey privateKey = new CX509PrivateKey();
privateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider";
privateKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE;
privateKey.Length = 2048;
privateKey.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)";
privateKey.MachineContext = true;
privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
privateKey.Create();
// Define the hashing algorithm
var serverauthoid = new CObjectId();
serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // Server Authentication
var ekuoids = new CObjectIds();
ekuoids.Add(serverauthoid);
var ekuext = new CX509ExtensionEnhancedKeyUsage();
ekuext.InitializeEncode(ekuoids);
// Create the self signing request
var cert = new CX509CertificateRequestCertificate();
cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, String.Empty);
cert.Subject = name;
cert.Issuer = cert.Subject;
cert.NotBefore = startDate;
cert.NotAfter = endDate;
cert.X509Extensions.Add((CX509Extension)ekuext);
cert.Encode();
// Enroll the certificate
var enroll = new CX509Enrollment();
enroll.InitializeFromRequest(cert);
string certData = enroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64HEADER);
enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate,
certData, EncodingType.XCN_CRYPT_STRING_BASE64HEADER, String.Empty);
var base64encoded = enroll.CreatePFX(password, PFXExportOptions.PFXExportChainWithRoot);
// Instantiate the target class with the PKCS#12 data
return new X509Certificate2(
System.Convert.FromBase64String(base64encoded), password,
System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable);
}
public async static Task RegisterAzureADApplication(SetupInformation info)
{
// Fix the App URL
if (!info.AzureWebAppUrl.EndsWith("/"))
{
info.AzureWebAppUrl = info.AzureWebAppUrl + "/";
}
// Load the App Manifest template
//Stream stream = typeof(SetupManager)
// .Assembly
// .GetManifestResourceStream("OfficeDevPnP.PartnerPack.Setup.Resources.azure-ad-app-manifest.json");
using (StreamReader sr = new StreamReader("Resources\azure-ad-app-manifest.json"))
{
// Get the JSON manifest
var jsonApplication = sr.ReadToEnd();
var application = JsonConvert.DeserializeObject<AzureAdApplication>(jsonApplication);
var keyCredential = JsonConvert.DeserializeObject<KeyCredential>(info.AzureAppKeyCredential);
application.displayName = info.ApplicationName;
application.homepage = info.AzureWebAppUrl;
application.identifierUris = new List<String>();
application.identifierUris.Add(info.ApplicationUniqueUri);
application.keyCredentials = new List<KeyCredential>();
application.keyCredentials.Add(keyCredential);
application.replyUrls = new List<String>();
application.replyUrls.Add(info.AzureWebAppUrl);
// Generate the Application Shared Secret
var startDate = DateTime.Now;
Byte[] bytes = new Byte[32];
using (var rand = System.Security.Cryptography.RandomNumberGenerator.Create())
{
rand.GetBytes(bytes);
}
info.AzureAppSharedSecret = System.Convert.ToBase64String(bytes);
application.passwordCredentials = new List<object>();
application.passwordCredentials.Add(new AzureAdApplicationPasswordCredential
{
CustomKeyIdentifier = null,
StartDate = startDate.ToString("o"),
EndDate = startDate.AddYears(2).ToString("o"),
KeyId = Guid.NewGuid().ToString(),
Value = info.AzureAppSharedSecret,
});
// Get an Access Token to create the application via Microsoft Graph
var office365AzureADAccessToken = await AzureManagementUtility.GetAccessTokenSilentAsync(
AzureManagementUtility.MicrosoftGraphResourceId,
ConfigurationManager.AppSettings["O365:ClientId"]);
var azureAdApplicationCreated = false;
// Create the Azure AD Application
try
{
await CreateAzureADApplication(info, application, office365AzureADAccessToken);
azureAdApplicationCreated = true;
}
catch (ApplicationException ex)
{
var graphError = JsonConvert.DeserializeObject<GraphError>(((HttpException)ex.InnerException).Message);
if (graphError != null && graphError.error.code == "Request_BadRequest" &&
graphError.error.message.Contains("identifierUris already exists"))
{
// We need to remove the existing application
// Thus, retrieve it
String jsonApplications = await HttpHelper.MakeGetRequestForStringAsync(
String.Format("{0}applications?$filter=identifierUris/any(c:c+eq+'{1}')",
AzureManagementUtility.MicrosoftGraphBetaBaseUri,
HttpUtility.UrlEncode(info.ApplicationUniqueUri)),
office365AzureADAccessToken);
var applications = JsonConvert.DeserializeObject<AzureAdApplications>(jsonApplications);
var applicationToUpdate = applications.Applications.FirstOrDefault();
if (applicationToUpdate != null)
{
// Remove it
await HttpHelper.MakeDeleteRequestAsync(
String.Format("{0}applications/{1}",
AzureManagementUtility.MicrosoftGraphBetaBaseUri,
applicationToUpdate.Id),
office365AzureADAccessToken);
// And add it again
await CreateAzureADApplication(info, application, office365AzureADAccessToken);
azureAdApplicationCreated = true;
}
}
}
if (azureAdApplicationCreated)
{
// TODO: We should upload the logo
// property mainLogo: stream of the application via PATCH
}
}
}
public static async Task CreateAzureADApplication(SetupInformation info, AzureAdApplication application, string office365AzureADAccessToken)
{
String jsonResponse = await HttpHelper.MakePostRequestForStringAsync(
String.Format("{0}applications",
AzureManagementUtility.MicrosoftGraphBetaBaseUri),
application,
"application/json", office365AzureADAccessToken);
var azureAdApplication = JsonConvert.DeserializeObject<AzureAdApplication>(jsonResponse);
info.AzureAppClientId = azureAdApplication.AppId.HasValue ? azureAdApplication.AppId.Value : Guid.Empty;
}
}
}
You are defining the method with async word after the return type Task, async must be before Task.
public async Task SetupPartnerPackAsync(SetupInformation info)
{
.
.
.

.NET Google Drive API - Get files with parent folder

Is there any possible way to get the list of files with parent folder name and without making additional queries?
My Files.List() code sample:
var sheets = new List<File>();
var sheetsRequest = Service.Files.List();
sheetsRequest.Fields = "nextPageToken, files(id, name, owners, parents)";
sheetsRequest.Q = $"mimeType = '{mimeType}' and name = '{name}'";
sheetsRequest.PageSize = 500;
var sheetsFeed = await sheetsRequest.ExecuteAsync();
while (sheetsFeed.Files != null)
{
foreach (var file in sheetsFeed.Files)
{
sheets.Add(file);
}
if (sheetsFeed.NextPageToken == null)
break;
sheetsRequest.PageToken = sheetsFeed.NextPageToken;
sheetsFeed = await sheetsRequest.ExecuteAsync();
}
return sheets;
Because for now I making GetFileParentDirAsync call for each File using following method (and it's very slow):
public async Task<string> GetFileParentDirAsync(File file)
{
return await Task.Run(async () =>
{
var folderName = string.Empty;
if (file.Parents?.First() == null) return folderName;
var parentId = file.Parents.First();
var parentRequest = Service.Files.Get(parentId);
var parentResponse = await parentRequest.ExecuteAsync();
folderName = parentResponse.Name;
return folderName;
});
}
Thanks.

Categories