Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

file upload and store #4

Open
TintypeMolly opened this issue Jan 8, 2015 · 10 comments
Open

file upload and store #4

TintypeMolly opened this issue Jan 8, 2015 · 10 comments

Comments

@TintypeMolly
Copy link
Contributor

  1. file store strategy
  2. how twisted can accept file
  3. file size limitation 2mb
  4. file - article relationship database
  5. how to distinguish image and others
@angdev
Copy link
Member

angdev commented Mar 12, 2015

E-hard가 붙었지만 얼른 논의해봐야 할 것 같습니다. 가장 요청도 많이 들어오는 기능(?)이기도 하구요.

@TintypeMolly
Copy link
Contributor Author

근데 이거 왠지 파일업로드가 producer같은거 신경 안써도 자동으로 IO에 안묶이고 될 것같은 삘이 약간 들었어. twisted.web에서 reactor를 직접 건들어야 하는건 너무 지옥이니까 왠지 구현을 해놨을 것 같단 말이지. 적절히 몇기가쯤 되는 애 업로드 해보면서 테스트를 해봐야 할 것 같다.

@angdev
Copy link
Member

angdev commented Mar 12, 2015

어떻게 시도를 해보실 생각이세요?

@TintypeMolly
Copy link
Contributor Author

로컬에서 큰 파일업로드 시켜보면서 다른 request 처리하나 안하나 확인해볼 생각. 이거 안되면 엔진 뜯어야됨ㅋㅋㅋㅋ

@angdev
Copy link
Member

angdev commented Mar 13, 2015

@TintypeMolly
제가 twisted를 살펴보지는 않아서 아래 방법으로 시도해봤는데 render_POST까지 오는데도 block이 되더군요. 아마 렌더링 함수 부르기 전에 request 단에서 메모리에 다 올리고 처리할 거 다 처리하는데 오래 걸리는 것 같아요.

diff --git a/resource/upload.py b/resource/upload.py
new file mode 100644
index 0000000..07d23c1
--- /dev/null
+++ b/resource/upload.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+import cgi
+from exception import Unauthorized
+from twisted.web.server import NOT_DONE_YET
+from helper.resource import YuzukiResource
+
+class Upload(YuzukiResource):
+    def render_POST(self, request):
+        self.headers = request.getAllHeaders()
+        file_form = cgi.FieldStorage(
+            fp = request.content,
+            headers = self.headers,
+            environ = {
+                'REQUEST_METHOD':'POST',
+                'CONTENT_TYPE': self.headers['content-type'],
+            }
+        )
+
+        for file in file_form.getlist("filename"):
+            print "???"
+        return "uploaded"
\ No newline at end of file
diff --git a/route.py b/route.py
index 98522cd..141ced9 100644
--- a/route.py
+++ b/route.py
@@ -16,6 +16,7 @@ from resource.profile import Profile
 from resource.register import Register
 from resource.reply import ReplyParent
 from resource.search import Search
+from resource.upload import Upload
 from resource.welcome import Welcome

 ROUTE = {
@@ -36,5 +37,6 @@ ROUTE = {
     "robots.txt": File("static/etc/robots.txt"),
     "static": File("static"),
     "search": Search(),
+    "upload": Upload(),
     "welcome": Welcome(),
 }
diff --git a/template/article_write.html b/template/article_write.html
index c25bbc8..cf2dba9 100644
--- a/template/article_write.html
+++ b/template/article_write.html
@@ -28,6 +28,12 @@
             <input type="submit" class="btn btn-default" value="완료"/>
         </form>
     </div>
+
+    <form enctype="multipart/form-data" method="post" action="/upload">
+        <input type="file" name="filename">
+        <input type="submit" class="btn btn-default" value="완료"/>
+    </form>
+
 {% endblock %}
 {% block script %}
     <script>

@TintypeMolly
Copy link
Contributor Author

응 그럼 엔진 뜯어야됨

@angdev
Copy link
Member

angdev commented Mar 13, 2015

전 일단 외부 클라우드 파일 업로드 api를 붙이는 것도 하나의 방법이라고 봅니다. (예를 들어 http://docs.rackspace.com/files/api/v1/cf-devguide/content/FormPost-d1a555.html) 구현하실 생각이 있으시면 제대로 논의를 해보겠지만요.

@TintypeMolly TintypeMolly self-assigned this Mar 13, 2015
@TintypeMolly
Copy link
Contributor Author

놀라운 사실을 알아냈는데, 파일 크기 제한은 nginx를 앞단에 쓰고있어서 아무런 의미 없는 고민이었다. nginx가 따로 설정 안하면 최대 req 크기를 1메가로 제한하고 있었다능. nginx proxy를 쓰고있는 이상 이걸 고민할 필요는 없었다는 사실.

@TintypeMolly
Copy link
Contributor Author

https://github.com/TintypeMolly/Yuzuki/tree/file-upload-example
쓰레드 갈라져서 바쁜 쓰레드를 막지 않고 파일을 쓰는 예제를 만들었다.
해야 될 일이 몇 개 남았는데

  1. 사용자가 업로드한 파일명 따오기. 이거 파싱할때 왜 기본적으로 twisted쪽에서 안 따주는 거야? 어떻게 따오는지는 아는데 request 내장함수 하나 오버라이드 해야되고 쫌 짜증남.
  2. 파일 모델 만들고 article과 대응시켜주기. 1:N은 form 만들기도 귀찮고 1:1 대응시키려고 생각중임. 실제로 저장되는 파일명은 원래 파일명 + 시간 해서 해싱해서 임의 키 만들던가 해서 쓸거고, DB에 원래 파일명과 실제 파일명과 매치시키는 row를 삽입하는 것이다. 삭제/수정 관리를 잘 해야될 듯.
  3. 사용자가 다운로드 받을 때 파일 이름을 바꿔줘야 되는데 이거 어떻게하는지 젠젠 모름. twisted.web.static.File 뜯어서 db참조해서 파일명 원래대로 바꿔주는 로직이 필요하다.

@TintypeMolly
Copy link
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants