2012-11-15 4 views
8

मैं इस तरह से एक संगीत फ़ाइल डाउनलोड करना चाहते:रुबी - ओपन-यूरी के साथ फ़ाइल का नाम कैसे प्राप्त करें?

require 'open-uri' 

source_url = "http://soundcloud.com/stereo-foo/cohete-amigo/download" 

attachment_file = "test.wav" 

open(attachment_file, "wb") do |file| 
    file.print open(source_url).read 
end 

कि उदाहरण मैं वास्तविक फ़ाइल नाम में "Test.wav" बदलना चाहते हैं (उदाहरण के JDownloader कार्यक्रम के लिए करता है की तरह)।

संपादित: मैं अस्थायी फ़ाइल मतलब यह नहीं है, मेरा मतलब है JDownloader की तरह वेब में संग्रहीत फ़ाइल हो जाता है: "Cohete अमीगो - स्टीरियो Foo.wav"

ठनक यू के लिए

अद्यतन पढ़ :

मैं इस नाम को स्टोर करने की कोशिश की है:

attachment_file = File.basename(open(source_url)) 

मुझे लगता है कि कोई मतलब नहीं है, लेकिन मैं जिस तरह से पता नहीं है ऐसा करने के लिए, क्षमा करें।

उत्तर

15

फ़ाइल नाम Content-Disposition नामक हेडर फ़ील्ड में संग्रहीत है। हालांकि इस क्षेत्र को डीकोड करना थोड़ा मुश्किल हो सकता है। यहाँ उदाहरण के लिए कुछ चर्चा देखें: तो क्रम ऐसा ही कुछ को डिकोड करने में

f = open('http://soundcloud.com/stereo-foo/cohete-amigo/download') 
f.meta['content-disposition'] 
=> "attachment;filename=\"Stereo Foo - Cohete Amigo.wav\"" 

:

How to encode the filename parameter of Content-Disposition header in HTTP?

open-uri के लिए आप वापस आ File वर्ग के meta एक्सेसर के माध्यम से सभी शीर्ष लेख फ़ील्ड का उपयोग कर सकते आप यह कर सकते हैं:

cd = f.meta['content-disposition']. 
filename = cd.match(/filename=(\"?)(.+)\1/)[2] 
=> "Stereo Foo - Cohete Amigo.wav" 

यह आपके विशेष के लिए काम करता है मामला, और यह भी काम करता है अगर उद्धरण " मौजूद नहीं हैं। लेकिन यूटीएफ -8 फाइलनाम जैसे अधिक जटिल सामग्री-स्वभाव मामलों में आप थोड़ी परेशानी में पड़ सकते हैं। यह सुनिश्चित नहीं है कि यूटीएफ -8 कितनी बार प्रयोग किया जाता है, और यदि ध्वनि ध्वनि कभी भी यूटीएफ -8 का उपयोग करता है। तो शायद आपको इसके बारे में चिंता करने की आवश्यकता नहीं है (पुष्टि नहीं की गई है और न ही परीक्षण किया गया है)।

तुम भी Mechanize की तरह एक और अधिक उन्नत वेब-क्रॉलिंग ढांचे इस्तेमाल कर सकते हैं, और यह भरोसा आप के लिए डिकोडिंग करने के लिए:

require 'mechanize' 

agent = Mechanize.new 
file = agent.get('http://soundcloud.com/stereo-foo/cohete-amigo/download') 
file.filename 
=> "Stereo_Foo_-_Cohete_Amigo.wav" 
+0

धन्यवाद, क्या आप जानते हैं कि मैं फाइलसाइज़ को भी पुनः प्राप्त कर सकता हूं और फ़ाइल के सभी एमबी प्राप्त करने के इंतजार किए बिना? – ElektroStudios

+0

सामग्री-लंबाई शीर्षलेख के अंदर देखें। – Danyel

6

क्योंकि open(source_url) रिटर्न कुछ की एक आई/ओ संभाल File.basename(open(source_url)) काम नहीं करेगा क्रमबद्ध करें, File.basename की तरह स्ट्रिंग नहीं।

File.basename(source_url) 

, काम का एक बेहतर मौका है, जब तक कि यूआरएल कुछ path/to/service/with/parameters/in/line/like/this प्रकार एन्कोडिंग का उपयोग कर रहा है होगा।

रूबी की यूआरआई लाइब्रेरी में यहां मदद करने के लिए उपयोगी टूल हैं। कुछ ऐसा:

File.basename(URI.parse(source_url).path) 

एक प्रारंभिक बिंदु होगा।

require 'uri' 

File.basename(URI.parse('http://www.example.com/path/to/file/index.html').path 
# => "index.html" 

और: उदाहरण के लिए

File.basename(URI.parse('http://www.example.com/path/to/file/index.html?foo=bar').path) 
# => "index.html" 

क्या आप जानते हैं कि अगर मैं फ़ाइल आकार भी और कैसे पुनर्प्राप्त कर सकते हैं?

स्थानीय स्तर पर HTTP सामान परीक्षण करने के लिए एक शानदार तरीका, कमांड लाइन से gem server चलाते हैं, और जवाहरात इसके प्रलेखन के लिए एक छोटे से वेब सर्वर आग जाने के लिए है:

require 'open-uri' 

html_doc = open('http://0.0.0.0:8808/') do |io| 
    puts io.size 
    io.read 
end 

puts html_doc.size 

# => 114350 
# => 114350 

आप एक ब्लॉक का उपयोग करते हैं OpenURI के open कमांड के साथ, यह आपको ब्लॉक वैरिएबल में कनेक्शन के बारे में बहुत सारी जानकारी तक पहुंच प्रदान करता है, जो Tempfile कक्षा का एक उदाहरण है। तो, आप size का उपयोग कर आने वाली फ़ाइल का आकार पा सकते हैं।

कि छोटे फ़ाइलों के लिए ठीक है, लेकिन अगर आप एक बड़ी फ़ाइल में खींच रहे आप एक head अनुरोध है, जो आकार शामिल हो सकता है भेजने के लिए Net :: HTTP का उपयोग कर जांच करने के लिए चाहते हो सकता है। मैं कहता हूं कि हो सकता है, क्योंकि कभी-कभी सर्वर नहीं जानता कि कितना वापस किया जाएगा, गतिशील सामग्री के मामले में, या सीजीआई या उप-सेवा द्वारा वापस लौटाई जाने वाली सामग्री जो कहने के लिए परेशान नहीं है।

"हेड" अनुरोध का उपयोग करने का लाभ यह है कि सर्वर पूरी सामग्री को वापस नहीं करता है, केवल हेडर। इसलिए, अतीत में, मैंने यह देखने के लिए कि मुझे आवश्यक डेटा प्राप्त हो सकता है, मैंने head का उपयोग करके एक अनुरोध को पूर्ववत कर दिया है। यदि नहीं, तो मुझे सामान्य get का उपयोग करके पूर्ण प्रतिक्रिया में खींचने के लिए मजबूर होना होगा।

+0

धन्यवाद, क्या आप जानते हैं कि मैं फाइलसाइज़ को भी पुनः प्राप्त कर सकता हूं और कैसे? – ElektroStudios

+0

फाइलसाइज़ कठिन है। इसे अक्सर सर्वर से लौटाए गए HTTP शीर्षलेख में वापस कर दिया जाता है, और नेट :: HTTP के तरीकों के माध्यम से पहुंचा जा सकता है। यदि आप 'ओपन' वाले ब्लॉक का उपयोग करते हैं तो उनमें से कुछ ओपनुरि के हेडर में उपलब्ध हैं। समस्या यह है कि सभी अनुरोधों के परिणामस्वरूप सामग्री-लंबाई शीर्षलेख नहीं होता है क्योंकि सर्वर नहीं जानता कि कितना वापस आ रहा है। यह किसी प्रकार की सीजीआई द्वारा उत्पन्न गतिशील सामग्री के लिए विशेष रूप से सच है। –

+0

जानकारी – ElektroStudios

संबंधित मुद्दे