14-04-20, 01:04 AM (آخر تعديل لهذه المشاركة : 14-04-20, 02:44 AM {2} بواسطة ابو ليلى.)
التعامل مع DropBox Api - تحديداً DropBox SDK V2
بسم الله الرحمن الرحيم و الصلاة و السلام على سيدنا محمد و على آله و صحبه اجمعين السلام عليكم و رحمة الله و بركاته --------------------------------------------- يعد موقع DropBox مقصداً للكثير من المطورين لسهولة التعامل معه في رفع و تحميل الملفات. و نظراً لاننا نتعامل معه بطريقة او باخرى من خلال برامجنا , ولاننا نفتقد لاي مصدر عربي يسهل علينا التعامل مع Api الخاص بالموقع, لما يوفره من سهولة في التعامل و يفتح لنا ابواب اوسع لمعالجة امور كنا بحاجتها دوماً. -------------------------------------------- فقد قررت كتابة هذه المقال لسببين : الاول : هو اضاءة على الـ Api الخاص بهم للاستفادة منه في برامجنا. الثاني : ايجاد طريقة اكثر تفاعلاً مع تحميل الملفات للاخوة الذين يتعاملون مع الموقع لتحديث برامجهم. ------------------------------------------- في البداية ننشئ برنامج و من ثم نقوم بتحميل المكتبة لبرنامجنا عبر Manage NuGet Packages
بعد التحميل وفق الصور السابقة ننتقل الى الفورم الرئيسي لدينا . فكرة البرنامج هو التعامل مع المكتبة وفق مسارين 1- رفع ملفات الى مساحتنا على الموقع. 2- تحميل ملفات من مساحتنا في الموقع.
سندخل الى الموقع اولاً و ننشئ بداخل المساحة مجلد لنرفع بداخله ملفاتنا. من الجيد اذا كنت ممن لديه عدة برامج و رغبت ان يكون لكل برنامج مجلد خاص ترفع له ملفاتك , ان تنشأ مجلد خاص بكل برنامج. نبقى مع الصور
سنستخدم المجلد Folder1 لنرفع اليه ملفاتنا كتجربة.
للتعامل مع المكتبة من خلال برنامجك يجب ان تمتلك حق الولوج الى Api الخاص بالموقع لذا يجب عليك ان تمتلك Access Token سنتعرف الى طريقة انشائها عبر الموقع بخطوات بسيطة عبر الصور.
الان و بعد ان تحصلت على Access Token انسخه و احتفظ به لاننا سنحتاجه للتعامل مع المكتبة عبر برنامجنا. جهز نفسك لننطلق في تجهيز البرنامج... سننتقل الى الفورم الرئيسي لدينا و نصممه كما في الصورة
قررت تقسيم الشاشة الى قسمين واحد لرفع الملفات و الثاني لتحميل الملفات شرح الارقام بالترتيب و ما يقابلها من سيناريوهات.
اولاً القسم الخاص برفع الملفات. 1- GetFiles سيكون لدينا اجراء يقوم بفتح مستعرض المجلدات لتحديد الملفات داخل المجلد. 2- DataGridView صمم ليعرض لنا اسماء الملفات داخل المجلد المحدد سابقاً مع معلومات عن حجم كل ملف و رقم النسخة الخاصة به و مسار الملف. تجدر الاشارة الى ان الملفات التي لا تحمل في خصائصا رقم نسخة سنقوم باعطائها الرقم صفر. العمود Status داخل القريد من النوع CheckBox سنستخدمه لتحديد الملفات التي نريد رفعها. 3- Upload سيقابله اجراء يقوم بالمرور على الملفات المحددة و رفعها الى مسار محدد داخل مساحتنا , المجلد Folder1 الذي انشأناه سابقاً. 4- يعرض لنا الملف الحالي الجاري رفعه الى المسار المحدد مع عرض نسبة الرفع بالتزامن مع ProgresBar فوقه لتكون العملية تفاعلية. هذا فيما يخص قسم الرفع.
ثانياً القسم الخاص بالتحميل
5- يعرض لنا المسار الذي يتم التحميل منه. 6- هنا تظهر الملفات التي داخل المسار السابق. 7- Download يقابله اجراء يقوم بالمرور على الملفات السابقة و البدء بتحميلها الى القرص المحلي وفق المسار المعطى داخل الكود. 8- يعرض الملف الحالي الجاري تحميله مع نسبة التقدم بالتوامن مع ProgresBar تفاعلي.
كل العمليات من رفع و تحميل تتم بشكل تزامني Asyncronis و تجري اغلب العمليات في مهام منفصلة لكي لا نواجه مشاكل التجميد حيث يمكنك الرفع و التحميل في نفس الوقت.
ندخل الى محرر الاكواد الخاص بنا لنتعرف الى اهم عناصر المكتبة.
في البداية يلزمنا استيراد الفضاءات التالية لنتمكن من العمل.
سنعمل على القسم الاول الخاص برفع الملفات. لذا سنقوم بتعريف اجراء يقوم بفتح المستعرض على مكان محدد لنسحب الملفات بداخله الى القريد الخاص بنا. سنقوم ببناء جدول له نفس اعمدة القريد و نخزن داخله المعلومات القادمة من كل ملف و من ثم نسنده الى القريد.
PHP كود :
Private Function BuildTable() As DataTable Dim Dt As New DataTable Dim Columns As New List(Of DataColumn) Columns.Add(New DataColumn With {.ColumnName = "Status"}) Columns.Add(New DataColumn With {.ColumnName = "FileName"}) Columns.Add(New DataColumn With {.ColumnName = "FileSize"}) Columns.Add(New DataColumn With {.ColumnName = "Version"}) Columns.Add(New DataColumn With {.ColumnName = "FilePath"})
Dt.Columns.AddRange(Columns.ToArray) Return Dt
End Function
هذا الاجراء المسؤول عن تشكيل الجدول . الان سيكون لدينا اجراء لجلب الملفات و المرور على كل ملف و نستخلص منه الاسم و الحجم و رقم النسخة و المسار.
PHP كود :
Dim Dt_FileUpdate As New DataTable Private Sub Btn_CollectFiles_Click(sender As Object, e As EventArgs) Handles Btn_CollectFiles.Click If (FolderBrowserDialog1.ShowDialog() = DialogResult.OK) Then Txt_Path.Text = FolderBrowserDialog1.SelectedPath
Dt_FileUpdate = BuildTable() Try Me.Cursor = Cursors.WaitCursor For Each f In Directory.GetFiles(Txt_Path.Text, "*", IO.SearchOption.AllDirectories) Dim _file As New IO.FileInfo(f)
FileVersionInfo.GetVersionInfo(f) Dim myFileVersionInfo As FileVersionInfo = FileVersionInfo.GetVersionInfo(f)
Dim F_Version As String = myFileVersionInfo.FileVersion If String.IsNullOrEmpty(F_Version) Then F_Version = 0
Dim Row As String() = New String() {"False", _file.Name, GetSizeKB(f), F_Version, f} Dt_FileUpdate.Rows.Add(Row)
Next DGV1.DataSource = Dt_FileUpdate Me.Cursor = Cursors.Arrow Catch ex As UnauthorizedAccessException MsgBox(ex.Message) Me.Cursor = Cursors.Arrow End Try End If End Sub
الاجراء يقوم باضافة معلومات كل ملف الى الجدول Dt_FileUpdate . الاجراء المسؤول عن حجم كل ملف كالتالي:
PHP كود :
Public Function GetSizeKB(ByVal filename As String) As Double Dim len As Double = New FileInfo(filename).Length / 1024 Return String.Format("{0:0.##}", len) End Function
بعد ان تكون القريد قد احتوت على ملفات , يمكننا الان معالجة عملية رفع الملفات. عند هذه النقطة سنحتاج الى كائنات رئيسية من المكتبة الخاصة بـ DropBox. الكائن الرئيسي في هذه المكتبة هو DropboxClient , هو المسؤول عن التخاطب و الارسال و الاستقبال... داخل هذا الكائن سنرسل Access Token التي حصلنا عليها سابقاً , و هي ترسل كوسيطة نصية. كما و يرتبط هذا الكائن بشكل وثيق مع HttpClient الخاص بالمكتبة Http.HttpClient. و هي المكتبة الحديثة من اطار عمل الدوت نت وهذه المكتبة صصمت للتعامل بشكل تزامني مع ملفات الانترنت و المواقع. يحتاج الكائن الى ضبط بعض الاعدادات البسيطة.
نعرف هذه المتغيرات في بداية النموذج.
PHP كود :
Dim config As DropboxClientConfig Dim client As DropboxClient Dim httpClient As Http.HttpClient Dim Path As String = "/UpdateFolder63/Folder1" 'مسار المجلد في الموقع
في بداية اقلاع النموذج
PHP كود :
'تعريفات و ضبط اعدادت httpClient = New Http.HttpClient(New Http.WebRequestHandler With { .ReadWriteTimeout = 10 * 1000}) With {.Timeout = TimeSpan.FromMinutes(20)}
config = New DropboxClientConfig("AnyThing") With {.HttpClient = httpClient}
client = New DropboxClient(My.Settings.AccessToken, config)
لقد خزنا Access Token داخل اعدادات البرنامج لنستدعيها في اي مكان.
14-04-20, 02:38 AM (آخر تعديل لهذه المشاركة : 14-04-20, 02:42 AM {2} بواسطة ابو ليلى.)
الان سنقوم بمعالجة عملية الرفع وفق التالي. سنحدد الملفات التي نريد رفعها عبر CheckBox و من ثم نقوم بالمرور على كل صفوف الجدول فاذا وفق ان الصف محدد سنقوم عندها برفع الملف .
PHP كود :
Private Async Sub Btn_Upload_Click(sender As Object, e As EventArgs) Handles Btn_Upload.Click
If DGV1.RowCount > 0 Then For Each Row As DataRow In Dt_FileUpdate.Rows If Row IsNot Nothing Then If Row("Status").ToString = "True" Then Lb_FileToUpload.Text = Row("FilePath") Btn_Upload.Enabled = False Await Uploader(client, Path, Row("FileName"), Row("FilePath")) Btn_Upload.Enabled = True End If
End If Next End If
End Sub End Class
الدالة المسؤولة عن الرفع هي دالة من النوع Asyncronis تحتاج الى عدة وسائط (كائن DropboxClient , مسار الرفع و اسم الملف و مساره) و كلها تتوفر لدينا في الجدول و لكل ملف.
الدالة Uploader :
PHP كود :
''' <summary> ''' رفع ملفات ''' </summary> ''' <param name="dbx"></param> ''' <param name="folder"></param> ''' <param name="_file"></param> ''' <param name="fileToUpload"></param> ''' <returns></returns> Private Async Function Uploader(ByVal dbx As DropboxClient, ByVal folder As String, ByVal _file As String, ByVal fileToUpload As String) As Task Const ChunkSize As Integer = 2 * 1024
Using fileStream = File.Open(fileToUpload, FileMode.Open)
If fileStream.Length <= ChunkSize Then Await dbx.Files.UploadAsync(folder & "/" & _file, WriteMode.Overwrite.Instance, body:=fileStream) Else Await UploadWthProgress(dbx, folder & "/" & _file, fileStream, CInt(ChunkSize)) End If End Using End Function
''' <summary> ''' الرفع مع بروجرس ''' </summary> ''' <param name="dbx"></param> ''' <param name="path"></param> ''' <param name="stream"></param> ''' <param name="chunkSize"></param> ''' <returns></returns> Private Async Function UploadWthProgress(ByVal dbx As DropboxClient, ByVal path As String, ByVal stream As FileStream, ByVal chunkSize As Integer) As Task Dim numChunks As ULong = CULng(Math.Ceiling(CDbl(stream.Length) / chunkSize)) Dim buffer As Byte() = New Byte(chunkSize - 1) {} Dim sessionId As String = Nothing
Dim idx As ULong = 0 PG2.Invoke(New Action(Sub() idx = 0 Me.PG2.Value = 0 PG2.Maximum = numChunks - 1 End Sub))
For idx = 0 To numChunks - 1 Dim byteRead = stream.Read(buffer, 0, chunkSize)
Using memStream = New MemoryStream(buffer, 0, byteRead)
If idx = 0 Then Dim result = Await dbx.Files.UploadSessionStartAsync(False, memStream) sessionId = result.SessionId Else Dim cursor = New UploadSessionCursor(sessionId, CULng(chunkSize) * idx)
If idx = numChunks - 1 Then Lb_FileToUpload.Invoke(New Action(Sub() Lb_FileToUpload.Text = "اكتمل الرفع" Lb_FileToUpload.Update() End Sub))
Dim fileMetadata As FileMetadata = Await dbx.Files.UploadSessionFinishAsync(cursor, New CommitInfo(path), memStream)
الدالة تم تقسيمها الى جزئين و السبب هو وجود ملفات ذات حجم كبير يمكن ان يتم رفعها الى المساحة و بالتالي لا بد من طريقة لاشعار المستخدم ان هناك تقدم في عملية الرفع بدل الانتظار لوقت ظويل دون معرفة ما يجري في الخلفة. اما الملفات الصغيرة فيتم تحميلها مباشرة دون الشعور بتقدم المؤشر و يمكن التحكم باقل حجم بعده ينطلق الجزء الثاني من الدالة عبر تغير قيمة المتغير ChunkSize . صراحة تم العمل كثيراً على هذا الجزء الخاص بربط ProgressBar مع عملية التحميل حيث ان العملية غير مدعومة داخل المكتبة . و كون عملية الرفع تجري في الخلفية في Task منفصل فكان من الصعب جداً الوصول الى طريقة فعالة , و لكن و الحمد لله تم حل المشكلة و هي تعمل بكفاءة.
------------------------------------------------------------- الشق الثاني المتعلق بتحميل الملفات : يجري بنفس السيناريو حيث نقوم بتحميل اسماء الملفات ضمن المسار المحدد الى ListBox و من ثم نقوم بالمرور على الملفات داخل المسار و نحملها تباعاً الى مسار محدد ستراه داخل الكود. اجراء التحميل:
PHP كود :
Private Async Sub Btn_Download_Click(sender As Object, e As EventArgs) Handles Btn_Download.Click
Dim list = Await ListFolder(client, Path) GroupBox4.Text = "Files To Download in Folder : " & Path
Try For Each Itm In list.Entries
If Itm.IsFile Then Btn_Download.Enabled = False Await Downloader(client, Path, Itm.AsFile) Btn_Download.Enabled = True End If
Next Label1.Text = "اكتمل التحميل..." Catch ex As Exception
End Try
End Sub
الدالة ListFolder داخل الكود مهمتها مزدوجة تقوم بالمرور على شقين داخل المسار المحدد. الشق الاول تقوم بجلب كل المجلدات الفرعية داخل المسار , اهذا انا انشأت مجلدات فرعية في بداية الشرح.. الشق الثاني تقوم بجلب كل الملفات داخل المسار المحدد (داخل المجلد المحدد في المسار). شكل الدالة :
PHP كود :
''' <summary> ''' جلب الملفات من مسار محدد ضمن الموقع '''DropBox المسار هو مجلد داخل ''' </summary> ''' <param name="client"></param> ''' <param name="path"></param> ''' <returns></returns> Private Async Function ListFolder(ByVal client As DropboxClient, ByVal path As String) As Task(Of ListFolderResult)
Dim list = Await client.Files.ListFolderAsync(path) 'هذا لجلب مجلدات ضمن المسار 'For Each item In list.Entries.Where(Function(i) i.IsFolder) ' ListBox_Folders.Items.Add(item.Name) 'Next
ListBox_Files.Items.Clear() 'جلب املفات ضمن المسار For Each item In list.Entries.Where(Function(i) i.IsFile) Dim file = item.AsFile ListBox_Files.Items.Add(file.Size & " / " & item.Name) Next
Return list End Function
اما دالة التحميل Downloader فهي تقوم بتحميل الملف بدلالة مساره و اسمه القادم من الموقع الى مكان محدد داخل جهازي وهو هنا (D:\Test Folder\) يمكنك جعل الامر اكثر تفاعلا بجعل المستخدم يحدد المكان.
شكل الدالة :
PHP كود :
''' <summary> ''' تحميل ملفات تم الدمج وفق طريقتين ''' </summary> ''' <param name="client"></param> ''' <param name="folder"></param> ''' <param name="file"></param> ''' <returns></returns> Private Async Function Downloader(ByVal client As DropboxClient, ByVal folder As String, ByVal file As FileMetadata) As Task
Using response = Await client.Files.DownloadAsync(folder & "/" & file.Name) Dim fileSize As ULong = response.Response.Size Const bufferSize As Integer = 1024 * 1024 Dim buffer = New Byte(bufferSize) {}
الى هنا نكون قد وصلنا الى الهدف من برنامجنا. المكتبة تمكنك من عمل الكثير من انشاء مجلدات و ملفات و التعديل عليها و الحذف و غيرها من الامور الاعتيادية التي تستطيع التعامل معها , ان كان على مستوى خاص او على مستوى فريق .... الخ نحن اكتفينا ببعض الامور التي تفيدنا .
الملف المرفق يحتوي على المثال كامل . ان كنت ستعتمد عليه , فعليك بتغير Access Token الى الخاص بك في اعدادات البرنامج. صور للاستخدام.
08-09-22, 11:54 AM (آخر تعديل لهذه المشاركة : 08-09-22, 11:55 AM {2} بواسطة saif2023.
تعديل السبب: System.Net.WebException: تم إجهاض الطلب: تعذر إنشاء قناة SSL/TLS آمنة.
)
(14-04-20, 02:38 AM)ابو ليلى كتب : الان سنقوم بمعالجة عملية الرفع وفق التالي. سنحدد الملفات التي نريد رفعها عبر CheckBox و من ثم نقوم بالمرور على كل صفوف الجدول فاذا وفق ان الصف محدد سنقوم عندها برفع الملف .
PHP كود :
Private Async Sub Btn_Upload_Click(sender As Object, e As EventArgs) Handles Btn_Upload.Click
If DGV1.RowCount > 0 Then For Each Row As DataRow In Dt_FileUpdate.Rows If Row IsNot Nothing Then If Row("Status").ToString = "True" Then Lb_FileToUpload.Text = Row("FilePath") Btn_Upload.Enabled = False Await Uploader(client, Path, Row("FileName"), Row("FilePath")) Btn_Upload.Enabled = True End If
End If Next End If
End Sub End Class
الدالة المسؤولة عن الرفع هي دالة من النوع Asyncronis تحتاج الى عدة وسائط (كائن DropboxClient , مسار الرفع و اسم الملف و مساره) و كلها تتوفر لدينا في الجدول و لكل ملف.
الدالة Uploader :
PHP كود :
''' <summary> ''' رفع ملفات ''' </summary> ''' <param name="dbx"></param> ''' <param name="folder"></param> ''' <param name="_file"></param> ''' <param name="fileToUpload"></param> ''' <returns></returns> Private Async Function Uploader(ByVal dbx As DropboxClient, ByVal folder As String, ByVal _file As String, ByVal fileToUpload As String) As Task Const ChunkSize As Integer = 2 * 1024
Using fileStream = File.Open(fileToUpload, FileMode.Open)
If fileStream.Length <= ChunkSize Then Await dbx.Files.UploadAsync(folder & "/" & _file, WriteMode.Overwrite.Instance, body:=fileStream) Else Await UploadWthProgress(dbx, folder & "/" & _file, fileStream, CInt(ChunkSize)) End If End Using End Function
''' <summary> ''' الرفع مع بروجرس ''' </summary> ''' <param name="dbx"></param> ''' <param name="path"></param> ''' <param name="stream"></param> ''' <param name="chunkSize"></param> ''' <returns></returns> Private Async Function UploadWthProgress(ByVal dbx As DropboxClient, ByVal path As String, ByVal stream As FileStream, ByVal chunkSize As Integer) As Task Dim numChunks As ULong = CULng(Math.Ceiling(CDbl(stream.Length) / chunkSize)) Dim buffer As Byte() = New Byte(chunkSize - 1) {} Dim sessionId As String = Nothing
Dim idx As ULong = 0 PG2.Invoke(New Action(Sub() idx = 0 Me.PG2.Value = 0 PG2.Maximum = numChunks - 1 End Sub))
For idx = 0 To numChunks - 1 Dim byteRead = stream.Read(buffer, 0, chunkSize)
Using memStream = New MemoryStream(buffer, 0, byteRead)
If idx = 0 Then Dim result = Await dbx.Files.UploadSessionStartAsync(False, memStream) sessionId = result.SessionId Else Dim cursor = New UploadSessionCursor(sessionId, CULng(chunkSize) * idx)
If idx = numChunks - 1 Then Lb_FileToUpload.Invoke(New Action(Sub() Lb_FileToUpload.Text = "اكتمل الرفع" Lb_FileToUpload.Update() End Sub))
Dim fileMetadata As FileMetadata = Await dbx.Files.UploadSessionFinishAsync(cursor, New CommitInfo(path), memStream)
الدالة تم تقسيمها الى جزئين و السبب هو وجود ملفات ذات حجم كبير يمكن ان يتم رفعها الى المساحة و بالتالي لا بد من طريقة لاشعار المستخدم ان هناك تقدم في عملية الرفع بدل الانتظار لوقت ظويل دون معرفة ما يجري في الخلفة. اما الملفات الصغيرة فيتم تحميلها مباشرة دون الشعور بتقدم المؤشر و يمكن التحكم باقل حجم بعده ينطلق الجزء الثاني من الدالة عبر تغير قيمة المتغير ChunkSize . صراحة تم العمل كثيراً على هذا الجزء الخاص بربط ProgressBar مع عملية التحميل حيث ان العملية غير مدعومة داخل المكتبة . و كون عملية الرفع تجري في الخلفية في Task منفصل فكان من الصعب جداً الوصول الى طريقة فعالة , و لكن و الحمد لله تم حل المشكلة و هي تعمل بكفاءة.
------------------------------------------------------------- الشق الثاني المتعلق بتحميل الملفات : يجري بنفس السيناريو حيث نقوم بتحميل اسماء الملفات ضمن المسار المحدد الى ListBox و من ثم نقوم بالمرور على الملفات داخل المسار و نحملها تباعاً الى مسار محدد ستراه داخل الكود. اجراء التحميل:
PHP كود :
Private Async Sub Btn_Download_Click(sender As Object, e As EventArgs) Handles Btn_Download.Click
Dim list = Await ListFolder(client, Path) GroupBox4.Text = "Files To Download in Folder : " & Path
Try For Each Itm In list.Entries
If Itm.IsFile Then Btn_Download.Enabled = False Await Downloader(client, Path, Itm.AsFile) Btn_Download.Enabled = True End If
Next Label1.Text = "اكتمل التحميل..." Catch ex As Exception
End Try
End Sub
الدالة ListFolder داخل الكود مهمتها مزدوجة تقوم بالمرور على شقين داخل المسار المحدد. الشق الاول تقوم بجلب كل المجلدات الفرعية داخل المسار , اهذا انا انشأت مجلدات فرعية في بداية الشرح.. الشق الثاني تقوم بجلب كل الملفات داخل المسار المحدد (داخل المجلد المحدد في المسار). شكل الدالة :
PHP كود :
''' <summary> ''' جلب الملفات من مسار محدد ضمن الموقع '''DropBox المسار هو مجلد داخل ''' </summary> ''' <param name="client"></param> ''' <param name="path"></param> ''' <returns></returns> Private Async Function ListFolder(ByVal client As DropboxClient, ByVal path As String) As Task(Of ListFolderResult)
Dim list = Await client.Files.ListFolderAsync(path) 'هذا لجلب مجلدات ضمن المسار 'For Each item In list.Entries.Where(Function(i) i.IsFolder) ' ListBox_Folders.Items.Add(item.Name) 'Next
ListBox_Files.Items.Clear() 'جلب املفات ضمن المسار For Each item In list.Entries.Where(Function(i) i.IsFile) Dim file = item.AsFile ListBox_Files.Items.Add(file.Size & " / " & item.Name) Next
Return list End Function
اما دالة التحميل Downloader فهي تقوم بتحميل الملف بدلالة مساره و اسمه القادم من الموقع الى مكان محدد داخل جهازي وهو هنا (D:\Test Folder\) يمكنك جعل الامر اكثر تفاعلا بجعل المستخدم يحدد المكان.
شكل الدالة :
PHP كود :
''' <summary> ''' تحميل ملفات تم الدمج وفق طريقتين ''' </summary> ''' <param name="client"></param> ''' <param name="folder"></param> ''' <param name="file"></param> ''' <returns></returns> Private Async Function Downloader(ByVal client As DropboxClient, ByVal folder As String, ByVal file As FileMetadata) As Task
Using response = Await client.Files.DownloadAsync(folder & "/" & file.Name) Dim fileSize As ULong = response.Response.Size Const bufferSize As Integer = 1024 * 1024 Dim buffer = New Byte(bufferSize) {}
الى هنا نكون قد وصلنا الى الهدف من برنامجنا. المكتبة تمكنك من عمل الكثير من انشاء مجلدات و ملفات و التعديل عليها و الحذف و غيرها من الامور الاعتيادية التي تستطيع التعامل معها , ان كان على مستوى خاص او على مستوى فريق .... الخ نحن اكتفينا ببعض الامور التي تفيدنا .
الملف المرفق يحتوي على المثال كامل . ان كنت ستعتمد عليه , فعليك بتغير Access Token الى الخاص بك في اعدادات البرنامج. صور للاستخدام.