github.tcl 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #!/usr/bin/env tclsh
  2. # file github/github.tcl
  3. #https://wiki.tcl-lang.org/page/github%3A%3Agithub
  4. #
  5. #Version 1.1 - added a timer in seconds between files & folders
  6. # chicken and egg problem we need non-standard packages tls and json ...
  7. package require tls
  8. package require http
  9. ::http::register https 443 ::tls::socket
  10. namespace eval ::github {
  11. variable libdir [file normalize [file join [file dirname [info script]] ..]]
  12. if {[lsearch $::auto_path $libdir] == -1} {
  13. lappend auto_path $libdir
  14. }
  15. }
  16. # I already placed the json folder below of the github folder
  17. package require json
  18. package provide github::github 0.2
  19. package provide github 0.2
  20. # Tcl package download
  21. proc ::github::github {cmd owner repo folder} {
  22. variable libdir
  23. set url https://api.github.com/repos/$owner/$repo/contents/
  24. download $url $folder
  25. }
  26. # Folder download
  27. proc ::github::download {url folder {debug true}} {
  28. if {![file exists $folder]} {
  29. file mkdir $folder
  30. }
  31. set sfiles ""
  32. set dfiles ""
  33. set data [http::data [http::geturl $url]]
  34. set d [json::json2dict $data]
  35. set l [llength $d]
  36. set files [list]
  37. for {set i 0} {$i < $l} {incr i 1} {
  38. set dic [dict create {*}[lindex $d $i]]
  39. set file [dict get $dic download_url]
  40. set type [dict get $dic type]
  41. if {$file eq "null" && $type eq "dir"} {
  42. set file [dict get $dic url]
  43. set file [regsub {.ref=master} $file ""]
  44. }
  45. if {$type eq "file"} {
  46. lappend sfiles $file
  47. } else {
  48. lappend dfiles $file
  49. }
  50. }
  51. if {$sfiles != ""} {
  52. files $sfiles $folder 0 $dfiles
  53. return
  54. }
  55. if {$dfiles != ""} {
  56. dirs $dfiles $folder 0
  57. }
  58. }
  59. # Folders make
  60. proc ::github::dirs {dirs dir num} {
  61. set file [lindex $dirs $num]
  62. set nfolder [file join $dir [file tail $file]]
  63. download $file $nfolder
  64. set counter [expr $num + 1]
  65. if {[lindex $dirs $counter] != ""} {
  66. utimer 2 [list ::github::dirs $dirs $dir $counter]
  67. }
  68. }
  69. # Files make
  70. proc ::github::files {files dir num dirs} {
  71. set item [lindex $files $num]
  72. set file [lindex $item 0]
  73. set fname [file tail $file]
  74. set fname [file join $dir $fname]
  75. set f [open $fname w]
  76. fconfigure $f -translation binary
  77. set tok [http::geturl $file -channel $f]
  78. set Stat [::http::status $tok]
  79. flush $f
  80. close $f
  81. http::cleanup $tok
  82. set counter [expr $num + 1]
  83. if {[lindex $files $counter] != ""} {
  84. utimer 2 [list ::github::files $files $dir $counter $dirs]
  85. } else {
  86. if {$dirs != ""} {
  87. dirs $dirs $dir 0
  88. }
  89. }
  90. }