Google App Engine에 몇 개의 .rar 파일을 다운로드 할 수있는 정적 웹 사이트가 있습니다.Google App Engine과의 다운로드 링크
handlers:
- url: /(.*\.(bz2|gz|rar|tar|tgz|zip))
static_files: static/\1
upload: static/(.*\.(bz2|gz|rar|tar|tgz|zip))
지금 내가하고 싶은 것을 그래서 할 수 카운트 다운로드 /download?MyFile.rar 같은 다운로드 링크를 제공 할 수 있습니다 : 은 지금 당장은 정적 파일 처리기 정의 (애플리케이션 제목)에 의해 처리 있어요 및 누구의 핫 링크를 참조하십시오.
웹 사이트가이 URL (실제 경로는 숨김/사용할 수 없음)을 사용하는 한 핫 링크를 방지하고 싶지 않습니다. 이렇게하면 외부에서 오는 경우에도 다운로드 수를 계산할 수 있습니다 (Google 애널리틱스 또는 Clicky는 분명히 처리하지 못하고 로그 보존 기간은 약 90 일이며 그 목적에 편리하지 않습니다).
질문은 : 사용자를위한 파일 다운로드를 시작할 수있는 파이썬 처리기를 만드는 방법은 무엇입니까? 우리가 많은 php/asp 웹 사이트에서 보는 것처럼.
많이 검색하고 그 2 개 스레드 (How do I let Google App Engine have a download link that downloads something from a database?, google app engine download a file containing files)을 읽은 후, 그것이 내가 뭔가 할 수 보인다
self.response.headers['Content-Type'] = 'application/octet-stream'
self.response.out.write(filecontent) # how do I get that content?
#or
self.response.headers["Content-Type"] = "application/zip"
self.response.headers['Content-Disposition'] = "attachment; filename=MyFile.rar" # does that work? how do I get the actual path?
나는 핸들러는 제한된 시간 동안 실행할 수 읽었다을 그래서 수도 있지 큰 파일을 위해 일하니?
모든 안내를 보내 주시면 감사하겠습니다.
감사합니다.
Romz
편집 : 가 작동했고 그것은 나를 모든 .RAR 파일을 하나의 핸들러를 가지고 있습니다. 그것은 직접 링크 (example.com/File.rar)처럼 보이는 URL을 가질 수는 있지만 파이썬에서는 실제로 처리됩니다 (그래서 referer를 확인하고 다운로드를 계산할 수 있습니다).
파일은 실제로 다른 하위 폴더에 있으며 은 경로가 생성되는 방식 때문에 실제 직접 다운로드으로부터 보호됩니다. 필자는 다른 문자 ('/'및 '\')가 필터링되어야하는지 모르지만이 방법으로는 아무도 상위 폴더의 다른 파일에 액세스 할 수 없어야합니다.
내 할당량 및 파일 크기 제한에 대한 모든 의미가 실제로 무엇인지는 알 수 없지만.
애플리케이션 제목을
handlers:
- url: /(.*\.rar)
script: main.app
당신은 BLOB 저장소에서 파일 내용을 저장하고 거기에서 역할을하지만, 큰 파일을 느린 클라이언트의 경우 수
from google.appengine.ext import webapp
from google.appengine.api import memcache
from google.appengine.ext import db
import os, urlparse
class GeneralCounterShard(db.Model):
name = db.StringProperty(required=True)
count = db.IntegerProperty(required=True, default=0)
def CounterIncrement(name):
def txn():
counter = GeneralCounterShard.get_by_key_name(name)
if counter is None:
counter = GeneralCounterShard(key_name=name, name=name)
counter.count += 1
counter.put()
db.run_in_transaction(txn)
memcache.incr(name) # does nothing if the key does not exist
class MainPage(webapp.RequestHandler):
def get(self):
referer = self.request.headers.get("Referer")
if (referer and not referer.startswith("http://www.example.com/")):
self.redirect('http://www.example.com')
return
path = urlparse.urlparse(self.request.url).path.replace('/', '').replace('\\', '')
fullpath = os.path.join(os.path.dirname(__file__), 'files/'+path)
if os.path.exists(fullpath):
CounterIncrement(path)
self.response.headers['Content-Type'] = 'application/zip'
self.response.headers["Content-Disposition"] = 'attachment; filename=' + path
self.response.out.write(file(fullpath, 'rb').read())
else:
self.response.out.write('<br>The file does not exist<br>')
app = webapp.WSGIApplication([('/.*', MainPage)], debug=False)
파일 크기가 작은 한 잘 수행됩니다. 크기가 더 큰 경우 블롭 스토어에 저장하고 직접 블롭 스토어 지원을 사용하여 제공해야하므로 앱의 메모리로 읽을 필요가 없습니다. –