github.tcl 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #!/usr/bin/env tclsh
  2. # file github/github.tcl
  3. #https://wiki.tcl-lang.org/page/github%3A%3Agithub
  4. # chicken and egg problem we need non-standard packages tls and json ...
  5. package require tls
  6. package require http
  7. ::http::register https 443 ::tls::socket
  8. namespace eval ::github {
  9. variable libdir [file normalize [file join [file dirname [info script]] ..]]
  10. if {[lsearch $::auto_path $libdir] == -1} {
  11. lappend auto_path $libdir
  12. }
  13. }
  14. # I already placed the json folder below of the github folder
  15. package require json
  16. package provide github::github 0.2
  17. package provide github 0.2
  18. # Tcl package download
  19. proc ::github::github {cmd owner repo folder} {
  20. variable libdir
  21. set url https://api.github.com/repos/$owner/$repo/contents/
  22. #puts $url
  23. #puts [lindex $d 1]
  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 data [http::data [http::geturl $url]]
  32. set d [json::json2dict $data]
  33. set l [llength $d]
  34. set files [list]
  35. for {set i 0} {$i < $l} {incr i 1} {
  36. set dic [dict create {*}[lindex $d $i]]
  37. set file [dict get $dic download_url]
  38. set type [dict get $dic type]
  39. if {$file eq "null" && $type eq "dir"} {
  40. set file [dict get $dic url]
  41. set file [regsub {.ref=master} $file ""]
  42. }
  43. lappend files [list $type $file]
  44. }
  45. # TODO subfolders (done)
  46. foreach item $files {
  47. set file [lindex $item 1]
  48. set type [lindex $item 0]
  49. if {$debug} {
  50. puts "fetching $file"
  51. }
  52. if {$type eq "file"} {
  53. set fname [file tail $file]
  54. set fname [file join $folder $fname]
  55. set f [open $fname w]
  56. fconfigure $f -translation binary
  57. set tok [http::geturl $file -channel $f]
  58. set Stat [::http::status $tok]
  59. flush $f
  60. close $f
  61. http::cleanup $tok
  62. } else {
  63. if {$debug} {
  64. puts "fetch new folder $file ..."
  65. }
  66. set nfolder [file join $folder [file tail $file]]
  67. download $file $nfolder $debug
  68. }
  69. }
  70. }