offline
- Srki94
- Mod u pemziji
- Pridružio: 14 Feb 2008
- Poruke: 12402
|
MyCity Facts Generator koristi Dropbox kao server. Tamo se nalaze poslednje verzije i sve ostale neophone informacije.
Svaki put kad ažuriram aplikaciju, moram da odem na Dropbox, okačim novu verziju, prebacim staru u backup folder i ažuriram fajl sa informacijama o izmenema.
Želim taj proces da automatizujem preko jedne aplikacije, gde će mi na klik dugmeta biti dostupno preuzimanje starih verzija, uploadovanje novih verzija i izmena fajla sa informacijama o verziji.
Krajnji rezultat će izgledati slično ovom :
Koristićemo Dropbox Api v2 za ovo i Console/WindowsForms aplikaciju koja cilja .NET 4.5.
Dropbox API je prijatan za rad i dobro je dokumentovan, uz primere za Console App, WPF i čini mi se ASP.NET. Možete da nađete repo ovde : https://github.com/dropbox/dropbox-sdk-dotnet
INDEKS ::
1. Pravljenje Dropbox Aplikacije
2. Pravljenje Visual Studio Projekta i povlačenje DropboxApi NuGeta
3. Programiranje
- 3.1 DropboxClient
- 3.2 Izlistavanje svih foldera i fajlova na putanji
- 3.3 Download fajla
- 3.4 Upload fajla
1. Kreiranje Dropbox Aplikacije ^ nazad na Indeks
Da bi mogli da koristimo Dropbox API, moramo prvo da napravimo aplikaciju na Dropbox-u.
Ulogujte se na Dropbox akaunt i otvorite sledeći link : https://www.dropbox.com/developers/apps
U desnom gornjem uglu treba da postoji dugme "Create app". Kliknite na njega
Na novoj stranici prvo biramo tip APIa.
Nama treba Dropbox API.
Zatim biramo tip pristupa APIa.
Ukoliko izaberete App Folder,
- pristup aplikacije će vam biti ograničen na Dropbox Root/Apps/Ime Aplikacije
Ukoliko izaberete Full Dropbox,
- aplikacija će imati potpuni pristup vašem Dropbox nalogu.
Meni se generator nalazi na drugoj lokaciji pa bi izmena iste zahtevala ažuriranje Updater i osnovne Aplikacije, zbog toga ću izabrati Full Dropbox.
Na kraju, dajte ime aplikaciji.
Ovo je u potpunosti vaš izbor. Imajte u vidu da će u Dropbox root/Apps/ folderu biti napravljen novi folder za vašu aplikaciju sa tim nazivom.
Kliknite na dugme Create app.
Klikom na naziv aplikacije se otvara strana sa podešavanjima iste.
Ostavite ovu otvorenu stranu tu gde jeste, dok podesimo Visual Studio projekat.
2. Podešavanje Visual Studio projekta ^ nazad na Indeks
Napravite novi projekat, dajte mu ime po izboru, ciljajte .NET Framework 4.5
Kada se projekat otvori nakon kreiranja,
Kliknite na Tools > NuGet Package Manager > Package Manager Console
U donjem uglu, ukoliko niste menjali postavke, se otvorio novi prozor - Package Manager Console.
Upišite :
Install-Package Dropbox.Api -Pre
... pritisnite enter.
Pustite Visual Studio da preuzme sve potrebne pakete.
U jednom trenutku će vas pitati da prihvatite uslove za par drugih paketa, kliknite na Da.
Ukoliko je sve prošlo kako treba, neće biti crvenih boja u konzoli i dobićete potvrdnu povratnu poruku :
Da je sve prošlo dobro možete proveriti tako što ćete pogledati reference vašeg projekta u Solution Explorer kartici :
ili Tools > NuGet Package manager > Manage NuGet Packages for solution
Kako je moj Solution već sačinjen iz više projekata, ovaj sam dodao u isti.
Međutim, naišao sam na par problema kada sam pokušao da napravim projekat unutar Solutiona i onda dodam Dropbox. Čak i kad sam podesio .NET Target na 4.5 za ovaj projekat.
Zbog toga sam prvo napravio projekat van MCFG Solution-a i dodao ga kasnije na ovaj način.
Elem, to je to - dodali ste Dropbox API u trenutni projekat i sada nam preostaje da se bacimo na kod.
3. Programiranje ^ nazad na Indeks
3.1 DropboxClient
Ukoliko pogledate zvanični tutorijal - pre nego što možete da uradite bilo šta, morate da napravite instancu DropboxClient objekta.
Nemojte zaboraviti
using Dropbox.Api;
async Task Run()
{
using (var dbx = new DropboxClient("YOUR ACCESS TOKEN"))
{
}
}
Po pravilu, svaki korisnik koji koristi ovu aplikaicju treba da prođe kroz OAuth proces.
Međutim ja sam jedina osoba koja će da koristi ovu aplikaciju.
Dropbox nam pomaže ovde i nudi nam unique access token, za lako testiranje, koji možemo da prosledimo kao string parametar konstruktoru DropboxClient-a. Ovaj token će nam omogućiti pristup nalogu za koji je aplikacija vezana.
Token služi isključivo za testiranje i niko osim vas ne bi trebao da ga ima ili koristi.
Da dobijete token otvorite ponovo Aplikaciju na Dropbox-u i kliknite na dugme "Generate" u sekciji Generate Access token :
Sada će se pojaviti dugačak niz karaktera koji potom treba da kopirate i nalepite umesto "YOUR ACCESS TOKEN" teksta u kodu iznad.
Kod treba da izgleda ovako, gde je umesto 64 X-a vaš token :
async Task Run()
{
using (var dbx = new DropboxClient("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"))
{
}
}
Ako sve prođe OK, sada ćete imati pristup vašem akauntu.
Hajde da pozdravimo korisnika u konzoli i da ga obavestimo da je prošao Login bez problema.
try
{
using (var dbx = new DropboxClient("token"))
{
var full = await dbx.Users.GetCurrentAccountAsync();
Console.WriteLine("Successfully Logged In");
Console.WriteLine($"Welcome, {full.Name.DisplayName}; {full.Email}");
}
}
catch (Exception x)
{
Console.WriteLine($"ERROR : Exception : {x.Message}");
}
dbx.Users.GetCurrentAccountAsync();
Nam vraća FullAccount, koji sadrži sve informacije o nalogu korisnika.
Druge dve linije su valjda jasne, samo što bih pojasnio : "$".
To je nešto što se zove String Interpolation i dodato je u C# 6.0
Dobiće ga i VB eventualno.
U srži to je String.Format, samo sa lepšom sintaksom
Inače, da pozovete ovaj task :
var task = Task.Run((Func<Task>)Run);
task.Wait();
Bilo gde, recimo u Load eventu forme.
Ja sam takođe omogućio i konzolu ovako :
OK,
uspeli smo da se ulogujemo uz pomoć Unique Tokena.
Uspeli smo da prikažemo nekoliko informacija o vlasniku naloga.
Hajde da izlistamo sve fajlove i foldere.
3.2 Pristup fajlovima i folderima ^ nazad na Indeks
Pravimo novi Task po uzoru na primer iz originalnog tutorijala :
async Task ListRootFolder(DropboxClient dbx)
{
var list = await dbx.Files.ListFolderAsync(@"/Public/");
// show folders then files
foreach (var item in list.Entries.Where(i => i.IsFolder))
{
Console.WriteLine("D {0}/", item.Name);
await Task.Delay(20);
}
foreach (var item in list.Entries.Where(i => i.IsFile))
{
Console.WriteLine("F{0,8} {1}", item.AsFile.Size, item.Name);
await Task.Delay(50);
}
}
To je ceo kod ...
Ja sam ga, doduše, malo modifikovao jer koristim hardkodirane putanje.
dbx.Files.ListFolderAsync(@"/Public");
Ova linija koda nam vraća ListFolderResult koji sadrži sve informacije o folderima i fajlovima na toj putanji.
Ono što je bitno a nije rečeno nigde :
Dropbox API v2 kao Path može da koristi String.Empty, pri čemu čita sve iz root foldera.
Ukoliko ste u prvom koraku izabrali da aplikacija ima samo pristup njenom folderu, root folder će biti Apps/ImeAplikacije/. Ukoliko ste izabrali pun pristup, root je vaš dropbox root.
Ukoliko želite da pokupite informacije iz nekog drugog foldera, putanja mora da počne sa "/" ali ne sme da se završi sa kosom crtom.
Par primera :
Pravilno :
/Public
/Public/Neki Folder
Nije pravilno :
Public/
/Public/
Sledeće dve petlje samo prolaze kroz ListFolderResult i proveravaju lambda izrazom da li je tip unosa Fajl ili Folder, zatim u konzoli ispisuju naziv fajla ili foldera.
Task.Delay nije potreban uopšte, tu je samo zbog kozmetike
I to je sve što vam treba da pristupite listi fajlova i foldera na nekoj putanji u Dropbox-u.
Možete ovaj Task da pozovete ovako :
try
{
using (var dbx = new DropboxClient("token"))
{
var full = await dbx.Users.GetCurrentAccountAsync();
Console.WriteLine("Successfully Logged In");
Console.WriteLine($"Welcome, {full.Name.DisplayName}; {full.Email}");
Console.WriteLine("Files in Application folder :");
await ListRootFolder(dbx);
}
}
catch (Exception x)
{
Console.WriteLine($"ERROR : Exception : {x.Message}");
}
Pokrenite kod i ukoliko u Public folderu imate fajlove, dobićete sličan efekat :
Konzola nam, naravno, nije potrebna uopšte. Meni je praktična u ovoj situaciji pa je koristim zbog toga.
3.3 Download fajla ^ nazad na Indeks
Sada kada već imamo pristup fajlovima, hajde da neki preuzmemo i sačuvamo na HDD.
Novi task :
async Task DownloadFile()
{
try
{
byte[] file;
using (var response = await dbxC.Files.DownloadAsync(downloadFilePath))
{
file = await response.GetContentAsByteArrayAsync();
}
File.WriteAllBytes(downloadSavePath, file);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Beep();
Console.WriteLine($"Error while downloading old version file : {ex.Message}");
Console.ForegroundColor = ConsoleColor.White;
}
}
Dakle, prvo iskoristimo DownloadAsync i prosledimo mu putanju do fajla.
Zatim preko interfejsa povučemo fajl jednom od ovih metoda :
GetContentAsByteArrayAsync
GetContentAsStreamAsync
GetContentAsStringAsync
Kako ja preuzimam zip fajlove sa servera, samo sam iskoristio ByteArray, koji sam kasnije sačuvao uz pomoć File.WriteAllBytes, iz System.IO.
Ako do sada nije očigledno, DropboxAPI je krajnje jednostavan za upotrebu
Ja sam u mom slučaju nazive sa ekstenzijom svih fajlova iz određenog foldera sačuvao u ComboBox kontrolu. Kada izaberem iz nje neku stariju verziju MyCity generatora i kliknem na dugme Download, izvrši se ovaj kod :
downloadFilePath = @"/Folder/" + cbOldVersionsOnServer.Text;
downloadSavePath = $"{Application.StartupPath}\\Data\\OldVersions\\{cbOldVersionsOnServer.Text}";
var task = Task.Run((Func<Task>)DownloadFile);
task.Wait();
Process.Start(Application.StartupPath + @"\Data\OldVersions\");
Mislim da zvaničan tutorijal predlaže da se proslede dva stringa, folder i fajl. Međutim meni to i nije baš praktično i više volim da radim sa fiksnom putanjom iz jednog stringa.
... to je to kad je download u pitanju.
3.4 Upload ^ nazad na Indeks
async Task Upload()
{
using (var mem = new MemoryStream((fileToUpload)))
{
var updated = await dbxC.Files.UploadAsync(uploadFilePath,
WriteMode.Overwrite.Instance,
body: mem);
Console.WriteLine($"Saved {uploadFilePath} rev {updated.Rev}");
}
}
Takođe kod baziran na primeru, samo što sam uklonio parametre i pojednostavnio ih.
Još jedna izmena je ta što čitam sve bajtove fajla u promenljivu i odmah ih prosleđujem MemoryStreamu.
Kod dugmeta za upload izgleda ovako :
fileToUpload = File.ReadAllBytes("D:\\kali.zip");
uploadFilePath = @"/Test/test.zip";
var task = Task.Run((Func<Task>)Upload);
task.Wait();
Bonus :
Kontaktirao sam Dropbox API tim i zamolio ih da mi potvrde da je ovakav način upotrebe u redu.
Odgovorili su da je u redu da ostavim aplikaciju na dropbox-u u "Development" statusu i da nemam nikakvih problema, dok god samo ja pristupam toj aplikaciji.
~ Napisano 21. Januara 2016.
|