Google App Engine में फ़ाइलें अपलोड करें


79

मैं एक वेब ऐप बनाने की योजना बना रहा हूं जो उपयोगकर्ताओं को अपने दृश्य स्टूडियो प्रोजेक्ट फ़ाइलों को डाउनग्रेड करने की अनुमति देता है। हालाँकि, ऐसा लगता है कि Google App Engine Google सर्वर पर अपलोडिंग और फ्लैट फाइल को स्टोर करने के माध्यम से स्वीकार करता है db.TextPropertyऔर db.BlobProperty

मुझे खुशी है कि किसी को भी कोड सैंपल (क्लाइंट और सर्वर साइड दोनों) प्रदान किया जा सकता है कि यह कैसे किया जा सकता है।


@ user858915 लिंक टूट गया है :(
मार्को

जवाबों:


44

यहाँ एक पूर्ण, कामकाजी फ़ाइल है। मैंने Google साइट से मूल को खींच लिया और इसे थोड़ा और वास्तविक दुनिया बनाने के लिए संशोधित किया।

ध्यान देने योग्य कुछ बातें:

  1. यह कोड BlobStore API का उपयोग करता है
  2. ServeHandler वर्ग में इस लाइन का उद्देश्य कुंजी को "ठीक" करना है ताकि इसे किसी भी नाम से छेड़छाड़ से छुटकारा मिल जाए जो कि ब्राउज़र में हो सकता है (मैंने क्रोम में कोई भी अवलोकन नहीं किया है)

    blob_key = str(urllib.unquote(blob_key))
    
  3. इसके अंत में "save_as" खंड महत्वपूर्ण है। यह सुनिश्चित कर लेगा कि आपके ब्राउज़र में भेजे जाने पर फ़ाइल का नाम मैंगल्ड न हो जाए। इससे छुटकारा पाएं कि क्या होता है।

    self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)
    

शुभ लाभ!

import os
import urllib

from google.appengine.ext import blobstore
from google.appengine.ext import webapp
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app

class MainHandler(webapp.RequestHandler):
    def get(self):
        upload_url = blobstore.create_upload_url('/upload')
        self.response.out.write('<html><body>')
        self.response.out.write('<form action="%s" method="POST" enctype="multipart/form-data">' % upload_url)
        self.response.out.write("""Upload File: <input type="file" name="file"><br> <input type="submit" name="submit" value="Submit"> </form></body></html>""")

        for b in blobstore.BlobInfo.all():
            self.response.out.write('<li><a href="https://stackoverflow.com/serve/%s' % str(b.key()) + '">' + str(b.filename) + '</a>')

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        upload_files = self.get_uploads('file')
        blob_info = upload_files[0]
        self.redirect('/')

class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self, blob_key):
        blob_key = str(urllib.unquote(blob_key))
        if not blobstore.get(blob_key):
            self.error(404)
        else:
            self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)

def main():
    application = webapp.WSGIApplication(
          [('/', MainHandler),
           ('/upload', UploadHandler),
           ('/serve/([^/]+)?', ServeHandler),
          ], debug=True)
    run_wsgi_app(application)

if __name__ == '__main__':
  main()

कमाल मेरे लिए छोड़कर हर किसी के लिए यह काम करता है ... कि self.__uploadsमें blobstore_handlerहै Noneजब मैं इस प्रयास करें।
टिम

49

वास्तव में, इस सवाल का जवाब ऐप ईगनिन प्रलेखन में दिया गया है। उपयोगकर्ता छवियाँ अपलोड करने पर एक उदाहरण देखें ।

HTML कोड, अंदर <form> </ form>:

<input type = "file" name = "img" />

पायथन कोड:

क्लास गेस्टबुक (webapp.RequestHandler):
  डीईएफ पोस्ट (स्व):
    अभिवादन = अभिवादन ()
    अगर उपयोगकर्ता .get_current_user ():
      अभिवादन। उपलक्ष = users.get_current_user ()
    अभिवादन। स्वंय = self.request.get ("सामग्री")
    अवतार = स्व.श्रेणी.गेट ("img")
    अभिवादन। अवतार = db.Blob (अवतार)
    अभिवादन।
    स्व.निर्देश ('/')

इस दृष्टिकोण को पसंद न करें क्योंकि आप ढीले माइम प्रकार की जानकारी देते हैं।
संतियागोबसुल्तो

@santiagobasulto: आप इसे हमारे द्वारा जाँच क्यों नहीं करते?
21

मैं इसकी जाँच नहीं करना चाहता। जब आपको एक छवि प्रदर्शित करनी होती है, तो आपको माइम प्रकार की जानकारी प्रदान करनी चाहिए (चाहे छवि JPG, GIF, आदि हो), आपको सामग्री-प्रकार HTTP शीर्ष लेख प्रदान करना होगा। यदि आप अपने द्वारा प्रदान किए गए समाधान के साथ छवि अपलोड करते हैं, तो आपको भविष्य में पता नहीं चलेगा कि चित्र का प्रकार, एर्गो, आप हेडर, एर्गो सेट नहीं कर सकते, पुराने-अजीब ब्राउज़रों को छवि प्रदर्शित करने में समस्या होगी ( सामग्री प्रकार की अनुपस्थिति के
बीज़हाउस

1
यदि आप क्लाइंट पर भरोसा करने वाले माइम प्रकार की जांच नहीं करते हैं, तो आप ब्लैक हैट हमलों या क्लाइंट में गलत प्रकार के माइम टाइप को छोड़ देते हैं। यदि आप ऐसा करने वाले हैं, तो आप केवल फ़ाइल एक्सटेंशन पर भरोसा कर सकते हैं।
नाचो कोलोमा


6

Google ने बड़ी फ़ाइलों को संग्रहीत करने के लिए एक सेवा जारी की है। ब्लॉस्टस्टोर एपीआई प्रलेखन पर एक नज़र डालें । यदि आपकी फ़ाइलें> 1MB हैं, तो आपको इसका उपयोग करना चाहिए।


फ़ाइलों को कैसे बचाएं> 1mb। मैं github.com/ckopanos/django-google-cloud-storage
जियो जैकब

6

मैं इसे आज कोशिश करता हूं, यह निम्नलिखित के रूप में काम करता है:

मेरा sdk संस्करण 1.3.x है

html पृष्ठ:

<form enctype="multipart/form-data" action="/upload" method="post" > 
<input type="file" name="myfile" /> 
<input type="submit" /> 
</form> 

सर्वर कोड:

file_contents = self.request.POST.get('myfile').file.read() 

3

यदि आपको अभी भी कोई समस्या हो रही है, तो आप फॉर्म टैग में एन्टाइप का उपयोग कर रहे हैं

नहीं:

<form encoding="multipart/form-data" action="/upload">

हाँ:

<form enctype="multipart/form-data" action="/upload">

आपके जवाब पर अमल करने से पहले मुझे एक एन्कोडिंग त्रुटि मिल रही थी
Jader Dias

1
मेरे लिए एक वास्तविक कष्टप्रद रोड़ा जब मैं ऐसा कर रहा था तो फ़ाइल इनपुट प्रकार के लिए "आकार" शामिल नहीं था। मैं सफारी के साथ परीक्षण कर रहा था, जो जाहिर तौर पर डिफ़ॉल्ट रूप से एक बहुत छोटी फ़ाइल लंबाई (?) है और सभी मुझे फ़ाइल की सामग्री के लिए जीएई में मिल रहा था, फ़ाइल का नाम था। चेतावनी का एक शब्द जो किसी को मामूली सिरदर्द से बचा सकता है।
जॉन कार्टर

1

आप फ़ाइलों को संग्रहीत नहीं कर सकते क्योंकि कोई पारंपरिक फ़ाइल सिस्टम नहीं है। आप उन्हें केवल अपने स्वयं के डेटास्टोर (एक ब्लॉबप्रॉपी के रूप में परिभाषित क्षेत्र में ) में संग्रहीत कर सकते हैं

पिछले लिंक में एक उदाहरण है:

class MyModel(db.Model):
  blob = db.BlobProperty()

obj = MyModel()
obj.blob = db.Blob( file_contents )

1

व्यक्तिगत रूप से मुझे यहां वर्णित ट्यूटोरियल मिला जब जावा रन टाइम का उपयोग जीएई के साथ करना उपयोगी था। किसी कारण से, जब मैंने एक फ़ाइल का उपयोग करके अपलोड करने का प्रयास किया

<form action="/testservelet" method="get" enctype="multipart/form-data">
    <div>
        Myfile:<input type="file" name="file" size="50"/>
    </div>

    <div>
        <input type="submit" value="Upload file">
    </div>
</form>

मैंने पाया कि मेरा HttpServlet वर्ग किसी कारण से 'enctype' विशेषता के साथ फ़ॉर्म स्वीकार नहीं करेगा। हालांकि, इसे हटाने से काम होता है, इसका मतलब है कि मैं कोई भी फाइल अपलोड नहीं कर सकता।


1
यह हो सकता है क्योंकि आप प्राप्त विधि का उपयोग कर रहे हैं, इसे पोस्ट करने के लिए सेट करने का प्रयास करें। मुझे यकीन नहीं है कि यह काम करेगा लेकिन यह कोशिश करने लायक है।
स्लैशनिक

0

Google App Engine में कोई समतल फ़ाइल संग्रहीत नहीं है। सब कुछ डेटास्टोर पर जाना पड़ता है जो एक रिलेशनल डेटाबेस की तरह है लेकिन काफी नहीं है।

आप TextProperty या BlobProperty विशेषताओं के रूप में फ़ाइलों को संग्रहीत कर सकते हैं ।

डेटास्टोर प्रविष्टियों पर 1MB की सीमा है जो एक समस्या हो सकती है या नहीं भी हो सकती है।


कैसे 1mb से अधिक फ़ाइलों को बचाने के लिए। मैं github.com/ckopanos/django-google-cloud-storage
जियो जैकब

0

मैंने App Engine पर फाइलें अपलोड करते समय कुछ अजीब व्यवहार देखे हैं। जब आप निम्नलिखित फॉर्म जमा करते हैं:

<form method="post" action="/upload" enctype="multipart/form-data">
    <input type="file" name="img" />
    ...
</form>

और फिर आप imgइस तरह अनुरोध से निकालते हैं :

img_contents = self.request.get('img')

img_contentsचर एक है str()गूगल क्रोम में, लेकिन यह फ़ायरफ़ॉक्स में यूनिकोड है। और जैसा आप अभी, एdb.Blob() कंस्ट्रक्टर एक स्ट्रिंग लेता है और यदि आप एक यूनिकोड स्ट्रिंग में पास करते हैं तो एक त्रुटि होगी।

क्या किसी को पता है कि यह कैसे तय किया जा सकता है?

इसके अलावा, जो मुझे बिल्कुल अजीब लगता है वह यह है कि जब मैं गेस्टबुक एप्लिकेशन (अवतार) के साथ कॉपी और पेस्ट करता हूं, तो यह पूरी तरह से काम करता है। मैं अपने कोड में सब कुछ ठीक उसी तरह करता हूं, लेकिन यह सिर्फ काम नहीं करेगा। मैं अपने बालों को बाहर खींचने के बहुत करीब हूं।


2
: डी फॉर्म में कहा गया है: मल्टीपार्ट / फॉर्म-डेटा के बजाय उत्परिवर्तित / प्रपत्र-डेटा। क्रोम टाइपो को सही करने के लिए पर्याप्त स्मार्ट है, फ़ायरफ़ॉक्स नहीं है।
होन्जा पोकॉर्नी

0

फ्लैट फाइल सिस्टम (उपयोग के परिप्रेक्ष्य में कम से कम) का उपयोग करने का एक तरीका है

यह Google App Engine Virtual FileSystem प्रोजेक्ट है । यह एक साधारण फाइल सिस्टम का अनुकरण करने के लिए डेटास्टोर और मेकैच एपीआई की मदद से कार्यान्वित किया जाता है। इस लाइब्रेरी का उपयोग करके आप एक समान फाइल सिस्टम एक्सेस (पढ़ने और लिखने) का उपयोग कर सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.