summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2013-06-10 11:37:25 +0800
committerJeremy Kerr <jk@ozlabs.org>2013-06-10 11:57:25 +0800
commit67181f5c929018d5304732969f0811795c13ea37 (patch)
treeb3a795c3cb45fe9579f8d84e6fddfe50cfdc4b10 /apps
parente7353352191516e45d21f9814375a92cc7f602dc (diff)
downloadpatchwork-67181f5c929018d5304732969f0811795c13ea37.tar.bz2
patchwork-67181f5c929018d5304732969f0811795c13ea37.tar.xz
views: Move mbox handling from models to views
Mbox generation is related to views, not the models themselves. This change creates a patch_to_mbox function in the views/ directory, which the actual view handlers use instead of Patch.mbox(). Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'apps')
-rw-r--r--apps/patchwork/models.py83
-rw-r--r--apps/patchwork/views/__init__.py82
-rw-r--r--apps/patchwork/views/bundle.py8
-rw-r--r--apps/patchwork/views/patch.py4
-rw-r--r--apps/patchwork/views/xmlrpc.py3
5 files changed, 92 insertions, 88 deletions
diff --git a/apps/patchwork/models.py b/apps/patchwork/models.py
index 250ad01..ec5727d 100644
--- a/apps/patchwork/models.py
+++ b/apps/patchwork/models.py
@@ -28,21 +28,6 @@ import re
import datetime, time
import random
-try:
- from email.mime.nonmultipart import MIMENonMultipart
- from email.encoders import encode_7or8bit
- from email.parser import HeaderParser
- from email.header import Header
- import email.utils
-except ImportError:
- # Python 2.4 compatibility
- from email.MIMENonMultipart import MIMENonMultipart
- from email.Encoders import encode_7or8bit
- from email.Parser import HeaderParser
- from email.Header import Header
- import email.Utils
- email.utils = email.Utils
-
class Person(models.Model):
email = models.CharField(max_length=255, unique = True)
name = models.CharField(max_length=255, null = True, blank = True)
@@ -188,14 +173,6 @@ class HashField(models.CharField):
def db_type(self, connection=None):
return 'char(%d)' % self.n_bytes
-class PatchMbox(MIMENonMultipart):
- patch_charset = 'utf-8'
- def __init__(self, _text):
- MIMENonMultipart.__init__(self, 'text', 'plain',
- **{'charset': self.patch_charset})
- self.set_payload(_text.encode(self.patch_charset))
- encode_7or8bit(self)
-
def get_default_initial_patch_state():
return State.objects.get(ordering=0)
@@ -245,62 +222,6 @@ class Patch(models.Model):
str = fname_re.sub('-', self.name)
return str.strip('-') + '.patch'
- def mbox(self):
- postscript_re = re.compile('\n-{2,3} ?\n')
-
- comment = None
- try:
- comment = Comment.objects.get(patch = self, msgid = self.msgid)
- except Exception:
- pass
-
- body = ''
- if comment:
- body = comment.content.strip() + "\n"
-
- parts = postscript_re.split(body, 1)
- if len(parts) == 2:
- (body, postscript) = parts
- body = body.strip() + "\n"
- postscript = postscript.strip() + "\n"
- else:
- postscript = ''
-
- for comment in Comment.objects.filter(patch = self) \
- .exclude(msgid = self.msgid):
- body += comment.patch_responses()
-
- if body:
- body += '\n'
-
- if postscript:
- body += '---\n' + postscript.strip() + '\n'
-
- if self.content:
- body += '\n' + self.content
-
- utc_timestamp = (self.date -
- datetime.datetime.utcfromtimestamp(0)).total_seconds()
-
- mail = PatchMbox(body)
- mail['Subject'] = self.name
- mail['Date'] = email.utils.formatdate(utc_timestamp)
- mail['From'] = email.utils.formataddr((
- str(Header(self.submitter.name, mail.patch_charset)),
- self.submitter.email))
- mail['X-Patchwork-Id'] = str(self.id)
- mail['Message-Id'] = self.msgid
- mail.set_unixfrom('From patchwork ' + self.date.ctime())
-
-
- copied_headers = ['To', 'Cc']
- orig_headers = HeaderParser().parsestr(str(self.headers))
- for header in copied_headers:
- if header in orig_headers:
- mail[header] = orig_headers[header]
-
- return mail
-
@models.permalink
def get_absolute_url(self):
return ('patchwork.views.patch.patch', (), {'patch_id': self.id})
@@ -382,10 +303,6 @@ class Bundle(models.Model):
'bundlename': self.name,
})
- def mbox(self):
- return '\n'.join([p.mbox().as_string(True)
- for p in self.ordered_patches()])
-
class BundlePatch(models.Model):
patch = models.ForeignKey(Patch)
bundle = models.ForeignKey(Bundle)
diff --git a/apps/patchwork/views/__init__.py b/apps/patchwork/views/__init__.py
index a9943e7..cb35c1f 100644
--- a/apps/patchwork/views/__init__.py
+++ b/apps/patchwork/views/__init__.py
@@ -22,6 +22,24 @@ from base import *
from patchwork.utils import Order, get_patch_ids, bundle_actions, set_bundle
from patchwork.paginator import Paginator
from patchwork.forms import MultiplePatchForm
+from patchwork.models import Comment
+import re
+import datetime
+
+try:
+ from email.mime.nonmultipart import MIMENonMultipart
+ from email.encoders import encode_7or8bit
+ from email.parser import HeaderParser
+ from email.header import Header
+ import email.utils
+except ImportError:
+ # Python 2.4 compatibility
+ from email.MIMENonMultipart import MIMENonMultipart
+ from email.Encoders import encode_7or8bit
+ from email.Parser import HeaderParser
+ from email.Header import Header
+ import email.Utils
+ email.utils = email.Utils
def generic_list(request, project, view,
view_args = {}, filter_settings = [], patches = None,
@@ -129,3 +147,67 @@ def process_multiplepatch_form(form, user, action, patches, context):
context.add_message("No patches updated")
return errors
+
+class PatchMbox(MIMENonMultipart):
+ patch_charset = 'utf-8'
+ def __init__(self, _text):
+ MIMENonMultipart.__init__(self, 'text', 'plain',
+ **{'charset': self.patch_charset})
+ self.set_payload(_text.encode(self.patch_charset))
+ encode_7or8bit(self)
+
+def patch_to_mbox(patch):
+ postscript_re = re.compile('\n-{2,3} ?\n')
+
+ comment = None
+ try:
+ comment = Comment.objects.get(patch = patch, msgid = patch.msgid)
+ except Exception:
+ pass
+
+ body = ''
+ if comment:
+ body = comment.content.strip() + "\n"
+
+ parts = postscript_re.split(body, 1)
+ if len(parts) == 2:
+ (body, postscript) = parts
+ body = body.strip() + "\n"
+ postscript = postscript.strip() + "\n"
+ else:
+ postscript = ''
+
+ for comment in Comment.objects.filter(patch = patch) \
+ .exclude(msgid = patch.msgid):
+ body += comment.patch_responses()
+
+ if body:
+ body += '\n'
+
+ if postscript:
+ body += '---\n' + postscript.strip() + '\n'
+
+ if patch.content:
+ body += '\n' + patch.content
+
+ utc_timestamp = (patch.date -
+ datetime.datetime.utcfromtimestamp(0)).total_seconds()
+
+ mail = PatchMbox(body)
+ mail['Subject'] = patch.name
+ mail['Date'] = email.utils.formatdate(utc_timestamp)
+ mail['From'] = email.utils.formataddr((
+ str(Header(patch.submitter.name, mail.patch_charset)),
+ patch.submitter.email))
+ mail['X-Patchwork-Id'] = str(patch.id)
+ mail['Message-Id'] = patch.msgid
+ mail.set_unixfrom('From patchwork ' + patch.date.ctime())
+
+
+ copied_headers = ['To', 'Cc']
+ orig_headers = HeaderParser().parsestr(str(patch.headers))
+ for header in copied_headers:
+ if header in orig_headers:
+ mail[header] = orig_headers[header]
+
+ return mail
diff --git a/apps/patchwork/views/bundle.py b/apps/patchwork/views/bundle.py
index 7a120dd..c99e322 100644
--- a/apps/patchwork/views/bundle.py
+++ b/apps/patchwork/views/bundle.py
@@ -26,7 +26,7 @@ import django.core.urlresolvers
from patchwork.models import Patch, Bundle, BundlePatch, Project
from patchwork.utils import get_patch_ids
from patchwork.forms import BundleForm, DeleteBundleForm
-from patchwork.views import generic_list
+from patchwork.views import generic_list, patch_to_mbox
from patchwork.filters import DelegateFilter
@login_required
@@ -193,10 +193,14 @@ def mbox(request, username, bundlename):
if not (request.user == bundle.owner or bundle.public):
return HttpResponseNotFound()
+ mbox = '\n'.join([patch_to_mbox(p).as_string(True)
+ for p in bundle.ordered_patches()])
+
response = HttpResponse(mimetype='text/plain')
response['Content-Disposition'] = \
'attachment; filename=bundle-%d-%s.mbox' % (bundle.id, bundle.name)
- response.write(bundle.mbox())
+
+ response.write(mbox)
return response
@login_required
diff --git a/apps/patchwork/views/patch.py b/apps/patchwork/views/patch.py
index 1583009..5eedcb5 100644
--- a/apps/patchwork/views/patch.py
+++ b/apps/patchwork/views/patch.py
@@ -23,7 +23,7 @@ from patchwork.forms import PatchForm, CreateBundleForm
from patchwork.requestcontext import PatchworkRequestContext
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponse, HttpResponseForbidden
-from patchwork.views import generic_list
+from patchwork.views import generic_list, patch_to_mbox
def patch(request, patch_id):
context = PatchworkRequestContext(request)
@@ -94,7 +94,7 @@ def content(request, patch_id):
def mbox(request, patch_id):
patch = get_object_or_404(Patch, id=patch_id)
response = HttpResponse(mimetype="text/plain")
- response.write(patch.mbox().as_string(True))
+ response.write(patch_to_mbox(patch).as_string(True))
response['Content-Disposition'] = 'attachment; filename=' + \
patch.filename().replace(';', '').replace('\n', '')
return response
diff --git a/apps/patchwork/views/xmlrpc.py b/apps/patchwork/views/xmlrpc.py
index a69c858..eebc2aa 100644
--- a/apps/patchwork/views/xmlrpc.py
+++ b/apps/patchwork/views/xmlrpc.py
@@ -26,6 +26,7 @@ from django.http import HttpResponse, HttpResponseRedirect, \
from django.core import urlresolvers
from django.contrib.auth import authenticate
from patchwork.models import Patch, Project, Person, State
+from patchwork.views import patch_to_mbox
from django.views.decorators.csrf import csrf_exempt
import sys
@@ -376,7 +377,7 @@ def patch_get_mbox(patch_id):
"""Return mbox string for the given patch ID."""
try:
patch = Patch.objects.filter(id = patch_id)[0]
- return patch.mbox().as_string()
+ return patch_to_mbox(patch).as_string()
except:
return ""