sketchucation logo sketchucation
    • 登入
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    ⚠️ Important | Libfredo 15.6b introduces important bugfixes for Fredo's Extensions Update

    Unzipping archive from Ruby (Mac and Windows)

    已排程 已置頂 已鎖定 已移動 Developers' Forum
    55 貼文 11 Posters 10.2k 瀏覽 11 Watching
    正在載入更多貼文
    • 從舊到新
    • 從新到舊
    • 最多點贊
    回覆
    • 在新貼文中回覆
    登入後回覆
    此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
    • TIGT 離線
      TIG Moderator
      最後由 編輯

      Your MAC ' zip' example is much like I use on older SketchUp version MACs with no Ruby zip built-in [with -q ?].

      Your ' ROBOCOPY' examples just makes a copy of the files in the source-folder in a new folder named ' xxxx.zip' - not zipped ! and it flashes up a black cmd window - just like in any WIN system call.

      On PCs you can make a longer set of strings that are VB commands. and put them into a ' xxxx.vbs' file which then runs silently using UI.openURL("file:///#{path_to_vbs_file}"), and it will make a proper ZIP file... I use that in older SketchUp version PCs with no Ruby zip built-in.

      txt="Const FOF_CREATEPROGRESSDLG = &H0&
      Const MyZip = \"#{zip.tr("/","\\")}\"
      Const File1 = \"#{tskp1.tr("/","\\")}\"
      Const File2 = \"#{tskp2.tr("/","\\")}\"
      'Create the basis of new zip file
      CreateObject(\"Scripting.FileSystemObject\").CreateTextFile(MyZip, True).Write \"PK\" & Chr(5) & Chr(6) & String(18, vbNullChar)
      'get ready to add files to zip
      With CreateObject(\"Shell.Application\")
      'add files
      .NameSpace(MyZip).CopyHere File1, FOF_CREATEPROGRESSDLG
      wScript.Sleep 200
      .NameSpace(MyZip).CopyHere File2
      End With
      ' wait 3 secs, to let it finish...
      wScript.Sleep 3000
      '''
      

      Where ' zip' is the path to the new ZIP file, and ' tskp1' etc paths to SKP files - the tr makes / into \ for VBS use
      You can get it to write a temp txt file at the end so you know it's done...

      TIG

      1 條回覆 最後回覆 回覆 引用 0
      • fredo6F 離線
        fredo6
        最後由 編輯

        Yes, I noticed there is a Zip module that seems to ship in Ruby 2.0 in the standard Sketchup installation.

        I did not find the documentation however, but this could be the answer, at least for SU2014 and SU2015.

        Fredo

        1 條回覆 最後回覆 回覆 引用 0
        • D 離線
          driven
          最後由 編輯

          403 Forbidden

          favicon

          (ruby-doc.org)

          learn from the mistakes of others, you may not live long enough to make them all yourself...

          1 條回覆 最後回覆 回覆 引用 0
          • tt_suT 離線
            tt_su
            最後由 編輯

            @eneroth3 said:

            Thanks! The gem rubyzip gem does exactly what I wanted 😄 .

            However I don't know what's the best practice to use a gem. Should I ask the user to install it or should I check if it exists when the plugin loads and otherwise install it? Should I in that case use statusbar texts to tell the user the gem is being installed and that it may take some time?

            What I've done is wrap the require in a begin/rescue that catch LoadErrors (you don't want to catch other errors) and then use Gem.install to install it if it's missing.

            1 條回覆 最後回覆 回覆 引用 0
            • tt_suT 離線
              tt_su
              最後由 編輯

              @fredo6 said:

              Yes, I noticed there is a Zip module that seems to ship in Ruby 2.0 in the standard Sketchup installation.

              I did not find the documentation however, but this could be the answer, at least for SU2014 and SU2015.

              Fredo

              It doesn't support ZIP files, it for general compression and GZ files.

              1 條回覆 最後回覆 回覆 引用 0
              • D 離線
                driven
                最後由 編輯

                cheers for the explanation...

                as I follow up to your last reply, this works on mac...

                      def is_texture(file)
                          result = false
                          Zip;;InputStream;;open(file) {|io|
                            while (entry = io.get_next_entry)
                              result = true if entry.to_s.include? "ref\/"
                            end
                          result
                          }
                      end
                

                could you test on Win with a skm path as file...
                john
                EDIT: added result = false although it is working...

                learn from the mistakes of others, you may not live long enough to make them all yourself...

                1 條回覆 最後回覆 回覆 引用 0
                • fredo6F 離線
                  fredo6
                  最後由 編輯

                  @driven said:

                  403 Forbidden

                  favicon

                  (ruby-doc.org)

                  This is ZLib. Is the Zip module just a wrapper of it?

                  Fredo

                  1 條回覆 最後回覆 回覆 引用 0
                  • Dan RathbunD 離線
                    Dan Rathbun
                    最後由 編輯

                    @driven said:

                    could you test on Win with a skm path as file...
                    john

                    John the following is what I will have used in my SKM Import Library:
                    (Yes it works on Windows and should also on Mac.)

                    <span class="syntaxdefault">  def skm_has_texture</span><span class="syntaxkeyword">?(</span><span class="syntaxdefault">file_path</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    </span><span class="syntaxcomment"># validate file_path here<br /></span><span class="syntaxdefault">    bool </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> nil<br />    Zip</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">File</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">open</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">file_path</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> do </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">skm</span><span class="syntaxkeyword">|<br /></span><span class="syntaxdefault">      tag </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> skm</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">read</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'document.xml'</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">slice</span><span class="syntaxkeyword">(/<</span><span class="syntaxdefault">mat</span><span class="syntaxkeyword">;</span><span class="syntaxdefault">material</span><span class="syntaxkeyword">\</span><span class="syntaxdefault">s</span><span class="syntaxkeyword">(.*)(\</span><span class="syntaxdefault">s</span><span class="syntaxkeyword">*>|\</span><span class="syntaxdefault">s</span><span class="syntaxkeyword">*\/>)/)<br /></span><span class="syntaxdefault">      unless tag</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">nil</span><span class="syntaxkeyword">?<br /></span><span class="syntaxdefault">        bool </span><span class="syntaxkeyword">=(</span><span class="syntaxdefault"> tag </span><span class="syntaxkeyword">!~</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">/(</span><span class="syntaxdefault">hasTexture</span><span class="syntaxkeyword">=\</span><span class="syntaxstring">"0\")/ rescue false )<br />      else<br />        puts("</span><span class="syntaxdefault">XML Read Error</span><span class="syntaxkeyword">;</span><span class="syntaxdefault"> Could not extract </span><span class="syntaxkeyword">\</span><span class="syntaxstring">"mat;material\" element.>"</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">      end<br />    end </span><span class="syntaxcomment"># open skmfile<br /></span><span class="syntaxdefault">    </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault">  rescue </span><span class="syntaxkeyword">=></span><span class="syntaxdefault"> e<br />    puts</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"Error; #<#{e.class.name}; #{e.message}.>"</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    return nil<br />  else<br />    return bool<br />  end </span><span class="syntaxcomment"># skm_has_texture?()<br />&nbsp;</span><span class="syntaxdefault"></span>
                    

                    I'm not here much anymore.

                    1 條回覆 最後回覆 回覆 引用 0
                    • D 離線
                      driven
                      最後由 編輯

                      @dan
                      yes, that works on mac,
                      I'm want to test if reading the stream works as it is meant to be the closest to unzip -t...
                      avoiding reading the file is said to be more efficient...

                      does my example even run on your PC?
                      john

                      learn from the mistakes of others, you may not live long enough to make them all yourself...

                      1 條回覆 最後回覆 回覆 引用 0
                      • Dan RathbunD 離線
                        Dan Rathbun
                        最後由 編輯

                        I had not tried it yet.

                        IMHO, your current code iterates all of the entries, and I think the test weak on the existence of the "ref" sub-directory. I decided myself not to rely upon that.

                        Reading a small text (xml) file should be relatively fast. It is not like this will be done thousands of times in a modeling operation. The only delays I notice are the output of console debug information.

                        I'm not here much anymore.

                        1 條回覆 最後回覆 回覆 引用 0
                        • D 離線
                          driven
                          最後由 編輯

                          @dan rathbun said:

                          It is not like this will be done thousands of times in a modeling operation.

                          I'm using it to add icons to batches of skm's, possibly hundreds at a time...
                          I want a quick check before unzipping, as I need to use different file for color v material...
                          john

                          learn from the mistakes of others, you may not live long enough to make them all yourself...

                          1 條回覆 最後回覆 回覆 引用 0
                          • Dan RathbunD 離線
                            Dan Rathbun
                            最後由 編輯

                            This works on Windows:

                            <span class="syntaxdefault">def is_texture</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> file</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">UI</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">openpanel</span><span class="syntaxkeyword">()</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">  result </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> false<br />  Zip</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">InputStream</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">open</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">file</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{|</span><span class="syntaxdefault">io</span><span class="syntaxkeyword">|<br /></span><span class="syntaxdefault">    while </span><span class="syntaxkeyword">(</span><span class="syntaxdefault">entry </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> io</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">get_next_entry</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">      if entry</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_s</span><span class="syntaxkeyword">.include?</span><span class="syntaxdefault"> </span><span class="syntaxstring">"ref\/"<br /></span><span class="syntaxdefault">        result </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> true<br />        break<br />      end<br />    end<br />  </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">  puts </span><span class="syntaxstring">"\"#{file}\"\n  is_texture; #{result.inspect}"</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># debug<br /></span><span class="syntaxdefault">  return result<br />end<br /></span>
                            

                            Just added a break inside the while loop, and moved the return result outside the block (because the block always returns the io object accd'g to the docs.)

                            Set the default arg to UI.openpanel() just so I could pick SKMs for test.

                            I'm not here much anymore.

                            1 條回覆 最後回覆 回覆 引用 0
                            • eneroth3E 離線
                              eneroth3
                              最後由 編輯

                              @tt_su said:

                              @eneroth3 said:

                              Thanks! The gem rubyzip gem does exactly what I wanted 😄 .

                              However I don't know what's the best practice to use a gem. Should I ask the user to install it or should I check if it exists when the plugin loads and otherwise install it? Should I in that case use statusbar texts to tell the user the gem is being installed and that it may take some time?

                              What I've done is wrap the require in a begin/rescue that catch LoadErrors (you don't want to catch other errors) and then use Gem.install to install it if it's missing.

                              What do you think is the best implementation? What about showing a web dialog or UI.messagebox when the plugin loads and the gem isn't installed telling the user that the gem is required? The user can choose to do it later (next time plugin is loaded) and the extension wont load or choose to download it now and there's a message saying it may take some time. The user would also be informed that this only has to be done once (per user and computer). Of course the extension warehouse info page would say that the extension will ask the user to install the gem and then automatically do it.

                              My website: http://julia-christina-eneroth.se/

                              1 條回覆 最後回覆 回覆 引用 0
                              • D 離線
                                driven
                                最後由 編輯

                                that's similar to how TT handles his Lib requirement...

                                pop up a webdialog for a yes/no, then switch it to your instructions manual...
                                that they can read then while they wait...

                                and have no excuse for not reading them...
                                john

                                learn from the mistakes of others, you may not live long enough to make them all yourself...

                                1 條回覆 最後回覆 回覆 引用 0
                                • tt_suT 離線
                                  tt_su
                                  最後由 編輯

                                  @eneroth3 said:

                                  What do you think is the best implementation? What about showing a web dialog or UI.messagebox when the plugin loads and the gem isn't installed telling the user that the gem is required? The user can choose to do it later (next time plugin is loaded) and the extension wont load or choose to download it now and there's a message saying it may take some time. The user would also be informed that this only has to be done once (per user and computer). Of course the extension warehouse info page would say that the extension will ask the user to install the gem and then automatically do it.

                                  There is no need for user interaction. You simply call Gem.install("nameOfGem") and it's done automatically for you. Look at the Gem module in the StdLib: http://ruby-doc.org/stdlib-2.0.0/libdoc/rubygems/rdoc/Gem.html

                                  However, you might want to call that only right before you need to use the gem - otherwise, if you call that in the head of the RB file with all the other require's it'll lock up SketchUp until the gem has been downloaded and installed. Not a big deal perhaps in the normal cases - but imagine if a user copied a few extensions that did this, then there's be a potential large lag during startup. But only once.

                                  1 條回覆 最後回覆 回覆 引用 0
                                  • 1
                                  • 2
                                  • 3
                                  • 3 / 3
                                  • 第一個貼文
                                    最後的貼文
                                  Buy SketchPlus
                                  Buy SUbD
                                  Buy WrapR
                                  Buy eBook
                                  Buy Modelur
                                  Buy Vertex Tools
                                  Buy SketchCuisine
                                  Buy FormFonts

                                  Advertisement