diff mbox

[v4,7/9] views: Expose Series mbox

Message ID 20170310173807.13407-8-stephen@that.guru
State Accepted
Headers show

Commit Message

Stephen Finucane March 10, 2017, 5:38 p.m. UTC
It is possible to download a patch mbox with all dependencies. Now make
it possible to download the entire series. This takes the form of the
following URL when using the default routes:

    /series/{seriesID}/mbox/

Like the equivalent patch and bundle links, this will return a 404 if
'{seriesID}' does not match an existing series' ID. However, a 404 will
also be returned in the series is not complete, as indicated by
Series.total > Series.received_total. You can override this behavior by
providing the 'force' parameter:

    /series/{seriesID}/mbox/?force=1

Note that there are no current plans to provide a series-specific view,
a.k.a.

    /series/{seriesID}/

As a result, this particular URL will continue to return a 404.

Signed-off-by: Stephen Finucane <stephen@that.guru>
---
v3:
- Correct license header
---
 patchwork/models.py       |  6 ++++++
 patchwork/urls.py         |  7 ++++++-
 patchwork/views/series.py | 35 +++++++++++++++++++++++++++++++++++
 patchwork/views/utils.py  | 17 +++++++++++++++++
 4 files changed, 64 insertions(+), 1 deletion(-)
 create mode 100644 patchwork/views/series.py

Comments

Daniel Axtens March 23, 2017, 2 a.m. UTC | #1
Hi Stephen,

Looks good to me.

Reviewed-by: Daniel Axtens <dja@axtens.net>

Regards,
Daniel

Stephen Finucane <stephen@that.guru> writes:

> It is possible to download a patch mbox with all dependencies. Now make
> it possible to download the entire series. This takes the form of the
> following URL when using the default routes:
>
>     /series/{seriesID}/mbox/
>
> Like the equivalent patch and bundle links, this will return a 404 if
> '{seriesID}' does not match an existing series' ID. However, a 404 will
> also be returned in the series is not complete, as indicated by
> Series.total > Series.received_total. You can override this behavior by
> providing the 'force' parameter:
>
>     /series/{seriesID}/mbox/?force=1
>
> Note that there are no current plans to provide a series-specific view,
> a.k.a.
>
>     /series/{seriesID}/
>
> As a result, this particular URL will continue to return a 404.
>
> Signed-off-by: Stephen Finucane <stephen@that.guru>
> ---
> v3:
> - Correct license header
> ---
>  patchwork/models.py       |  6 ++++++
>  patchwork/urls.py         |  7 ++++++-
>  patchwork/views/series.py | 35 +++++++++++++++++++++++++++++++++++
>  patchwork/views/utils.py  | 17 +++++++++++++++++
>  4 files changed, 64 insertions(+), 1 deletion(-)
>  create mode 100644 patchwork/views/series.py
>
> diff --git a/patchwork/models.py b/patchwork/models.py
> index 94aaa0f..22ab522 100644
> --- a/patchwork/models.py
> +++ b/patchwork/models.py
> @@ -589,6 +589,12 @@ class Series(models.Model):
>      def received_all(self):
>          return self.total <= self.received_total
>  
> +    @property
> +    def filename(self):
> +        fname_re = re.compile(r'[^-_A-Za-z0-9\.]+')
> +        fname = fname_re.sub('-', str(self))
> +        return fname.strip('-') + '.patch'
> +
>      def add_cover_letter(self, cover):
>          """Add a cover letter to the series.
>  
> diff --git a/patchwork/urls.py b/patchwork/urls.py
> index 7a8ea95..ef283c0 100644
> --- a/patchwork/urls.py
> +++ b/patchwork/urls.py
> @@ -32,6 +32,7 @@ from patchwork.views import notification as notification_views
>  from patchwork.views import patch as patch_views
>  from patchwork.views import project as project_views
>  from patchwork.views import pwclient as pwclient_views
> +from patchwork.views import series as series_views
>  from patchwork.views import user as user_views
>  from patchwork.views import xmlrpc as xmlrpc_views
>  
> @@ -61,10 +62,14 @@ urlpatterns = [
>      url(r'^cover/(?P<cover_id>\d+)/$', cover_views.cover_detail,
>          name='cover-detail'),
>  
> -    # comment urls
> +    # comment views
>      url(r'^comment/(?P<comment_id>\d+)/$', comment_views.comment,
>          name='comment-redirect'),
>  
> +    # series views
> +    url(r'^series/(?P<series_id>\d+)/mbox/$', series_views.series_mbox,
> +        name='series-mbox'),
> +
>      # logged-in user stuff
>      url(r'^user/$', user_views.profile, name='user-profile'),
>      url(r'^user/todo/$', user_views.todo_lists,
> diff --git a/patchwork/views/series.py b/patchwork/views/series.py
> new file mode 100644
> index 0000000..a59bffd
> --- /dev/null
> +++ b/patchwork/views/series.py
> @@ -0,0 +1,35 @@
> +# Patchwork - automated patch tracking system
> +# Copyright (C) 2017 Stephen Finucane <stephen@that.guru>
> +#
> +# This file is part of the Patchwork package.
> +#
> +# Patchwork is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 2 of the License, or
> +# (at your option) any later version.
> +#
> +# Patchwork is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with Patchwork; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> +
> +from django.http import HttpResponse
> +from django.shortcuts import get_object_or_404
> +
> +from patchwork.models import Series
> +from patchwork.views.utils import series_to_mbox
> +
> +
> +def series_mbox(request, series_id):
> +    series = get_object_or_404(Series, id=series_id)
> +
> +    response = HttpResponse(content_type='text/plain')
> +    response.write(series_to_mbox(series))
> +    response['Content-Disposition'] = 'attachment; filename=' + \
> +        series.filename.replace(';', '').replace('\n', '')
> +
> +    return response
> diff --git a/patchwork/views/utils.py b/patchwork/views/utils.py
> index f936ed8..49d9c0c 100644
> --- a/patchwork/views/utils.py
> +++ b/patchwork/views/utils.py
> @@ -151,3 +151,20 @@ def series_patch_to_mbox(patch, series_num):
>      mbox.append(patch_to_mbox(patch))
>  
>      return '\n'.join(mbox)
> +
> +
> +def series_to_mbox(series):
> +    """Get an mbox representation of an entire series.
> +
> +    Arguments:
> +        series: The Series object to convert.
> +
> +    Returns:
> +        A string for the mbox file.
> +    """
> +    mbox = []
> +
> +    for dep in series.seriespatch_set.all():
> +        mbox.append(patch_to_mbox(dep.patch))
> +
> +    return '\n'.join(mbox)
> -- 
> 2.9.3
>
> _______________________________________________
> Patchwork mailing list
> Patchwork@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/patchwork
diff mbox

Patch

diff --git a/patchwork/models.py b/patchwork/models.py
index 94aaa0f..22ab522 100644
--- a/patchwork/models.py
+++ b/patchwork/models.py
@@ -589,6 +589,12 @@  class Series(models.Model):
     def received_all(self):
         return self.total <= self.received_total
 
+    @property
+    def filename(self):
+        fname_re = re.compile(r'[^-_A-Za-z0-9\.]+')
+        fname = fname_re.sub('-', str(self))
+        return fname.strip('-') + '.patch'
+
     def add_cover_letter(self, cover):
         """Add a cover letter to the series.
 
diff --git a/patchwork/urls.py b/patchwork/urls.py
index 7a8ea95..ef283c0 100644
--- a/patchwork/urls.py
+++ b/patchwork/urls.py
@@ -32,6 +32,7 @@  from patchwork.views import notification as notification_views
 from patchwork.views import patch as patch_views
 from patchwork.views import project as project_views
 from patchwork.views import pwclient as pwclient_views
+from patchwork.views import series as series_views
 from patchwork.views import user as user_views
 from patchwork.views import xmlrpc as xmlrpc_views
 
@@ -61,10 +62,14 @@  urlpatterns = [
     url(r'^cover/(?P<cover_id>\d+)/$', cover_views.cover_detail,
         name='cover-detail'),
 
-    # comment urls
+    # comment views
     url(r'^comment/(?P<comment_id>\d+)/$', comment_views.comment,
         name='comment-redirect'),
 
+    # series views
+    url(r'^series/(?P<series_id>\d+)/mbox/$', series_views.series_mbox,
+        name='series-mbox'),
+
     # logged-in user stuff
     url(r'^user/$', user_views.profile, name='user-profile'),
     url(r'^user/todo/$', user_views.todo_lists,
diff --git a/patchwork/views/series.py b/patchwork/views/series.py
new file mode 100644
index 0000000..a59bffd
--- /dev/null
+++ b/patchwork/views/series.py
@@ -0,0 +1,35 @@ 
+# Patchwork - automated patch tracking system
+# Copyright (C) 2017 Stephen Finucane <stephen@that.guru>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+from django.http import HttpResponse
+from django.shortcuts import get_object_or_404
+
+from patchwork.models import Series
+from patchwork.views.utils import series_to_mbox
+
+
+def series_mbox(request, series_id):
+    series = get_object_or_404(Series, id=series_id)
+
+    response = HttpResponse(content_type='text/plain')
+    response.write(series_to_mbox(series))
+    response['Content-Disposition'] = 'attachment; filename=' + \
+        series.filename.replace(';', '').replace('\n', '')
+
+    return response
diff --git a/patchwork/views/utils.py b/patchwork/views/utils.py
index f936ed8..49d9c0c 100644
--- a/patchwork/views/utils.py
+++ b/patchwork/views/utils.py
@@ -151,3 +151,20 @@  def series_patch_to_mbox(patch, series_num):
     mbox.append(patch_to_mbox(patch))
 
     return '\n'.join(mbox)
+
+
+def series_to_mbox(series):
+    """Get an mbox representation of an entire series.
+
+    Arguments:
+        series: The Series object to convert.
+
+    Returns:
+        A string for the mbox file.
+    """
+    mbox = []
+
+    for dep in series.seriespatch_set.all():
+        mbox.append(patch_to_mbox(dep.patch))
+
+    return '\n'.join(mbox)