mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Merge pull request #1247 from paylogic/multiple-authors
Multiple authors implementation for #956
This commit is contained in:
commit
826ff4df50
16 changed files with 122 additions and 59 deletions
|
|
@ -7,6 +7,7 @@ Next release
|
|||
* Added the `:modified:` metadata field to complement `:date:`.
|
||||
Used to specify the last date and time an article was updated independently from the date and time it was published.
|
||||
* Produce inline links instead of reference-style links when importing content.
|
||||
* Multiple authors support added via new `:authors:` metadata field.
|
||||
|
||||
3.3.0 (2013-09-24)
|
||||
==================
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ this metadata in text files via the following syntax (give your file the
|
|||
:tags: thats, awesome
|
||||
:category: yeah
|
||||
:slug: my-super-post
|
||||
:author: Alexis Metaireau
|
||||
:authors: Alexis Metaireau, Conan Doyle
|
||||
:summary: Short version for index and feeds
|
||||
|
||||
Pelican implements an extension to reStructuredText to enable support for the
|
||||
|
|
@ -331,7 +331,7 @@ pattern::
|
|||
Category: Python
|
||||
Tags: pelican, publishing
|
||||
Slug: my-super-post
|
||||
Author: Alexis Metaireau
|
||||
Authors: Alexis Metaireau, Conan Doyle
|
||||
Summary: Short version for index and feeds
|
||||
|
||||
This is the content of my super blog post.
|
||||
|
|
@ -351,7 +351,7 @@ interprets the HTML in a very straightforward manner, reading metadata from
|
|||
<meta name="date" content="2012-07-09 22:28" />
|
||||
<meta name="modified" content="2012-07-10 20:14" />
|
||||
<meta name="category" content="yeah" />
|
||||
<meta name="author" content="Alexis Métaireau" />
|
||||
<meta name="authors" content="Alexis Métaireau, Conan Doyle" />
|
||||
<meta name="summary" content="Short version for index and feeds" />
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -380,6 +380,9 @@ __ `W3C ISO 8601`_
|
|||
Besides you can show ``modified`` in the templates, feed entries in feed readers will be updated automatically
|
||||
when you set ``modified`` to the current date after you modified your article.
|
||||
|
||||
``authors`` is a comma-separated list of article authors. If there's only one author you
|
||||
can use ``author`` field.
|
||||
|
||||
If you do not explicitly specify summary metadata for a given post, the
|
||||
``SUMMARY_MAX_LENGTH`` setting can be used to specify how many words from the
|
||||
beginning of an article are used as the summary.
|
||||
|
|
@ -587,12 +590,12 @@ classprefix string String to prepend to token class names
|
|||
hl_lines numbers List of lines to be highlighted.
|
||||
lineanchors string Wrap each line in an anchor using this
|
||||
string and -linenumber.
|
||||
linenos string If present or set to "table" output line
|
||||
linenos string If present or set to "table" output line
|
||||
numbers in a table, if set to
|
||||
"inline" output them inline. "none" means
|
||||
do not output the line numbers for this
|
||||
do not output the line numbers for this
|
||||
table.
|
||||
linenospecial number If set every nth line will be given the
|
||||
linenospecial number If set every nth line will be given the
|
||||
'special' css class.
|
||||
linenostart number Line number for the first line.
|
||||
linenostep number Print every nth line number.
|
||||
|
|
|
|||
|
|
@ -74,11 +74,17 @@ class Content(object):
|
|||
#default template if it's not defined in page
|
||||
self.template = self._get_template()
|
||||
|
||||
# default author to the one in settings if not defined
|
||||
# First, read the authors from "authors", if not, fallback to "author"
|
||||
# and if not use the settings defined one, if any.
|
||||
if not hasattr(self, 'author'):
|
||||
if 'AUTHOR' in settings:
|
||||
if hasattr(self, 'authors'):
|
||||
self.author = self.authors[0]
|
||||
elif 'AUTHOR' in settings:
|
||||
self.author = Author(settings['AUTHOR'], settings)
|
||||
|
||||
if not hasattr(self, 'authors') and hasattr(self, 'author'):
|
||||
self.authors = [self.author]
|
||||
|
||||
# XXX Split all the following code into pieces, there is too much here.
|
||||
|
||||
# manage languages
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ class ArticlesGenerator(Generator):
|
|||
|
||||
self.articles, self.translations = process_translations(all_articles)
|
||||
|
||||
signals.article_generator_pretaxonomy.send(self)
|
||||
signals.article_generator_pretaxonomy.send(self)
|
||||
|
||||
for article in self.articles:
|
||||
# only main articles are listed in categories and tags
|
||||
|
|
@ -444,9 +444,9 @@ class ArticlesGenerator(Generator):
|
|||
for tag in article.tags:
|
||||
self.tags[tag].append(article)
|
||||
# ignore blank authors as well as undefined
|
||||
if hasattr(article, 'author') and article.author.name != '':
|
||||
self.authors[article.author].append(article)
|
||||
|
||||
for author in getattr(article, 'authors', []):
|
||||
if author.name != '':
|
||||
self.authors[author].append(article)
|
||||
# sort the articles by date
|
||||
self.articles.sort(key=attrgetter('date'), reverse=True)
|
||||
self.dates = list(self.articles)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ METADATA_PROCESSORS = {
|
|||
'status': lambda x, y: x.strip(),
|
||||
'category': Category,
|
||||
'author': Author,
|
||||
'authors': lambda x, y: [Author(author, y) for author in x],
|
||||
}
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -144,6 +145,9 @@ class RstReader(BaseReader):
|
|||
value = render_node_to_html(document, body_elem)
|
||||
else:
|
||||
value = body_elem.astext()
|
||||
elif element.tagname == 'authors': # author list
|
||||
name = element.tagname
|
||||
value = [element.astext() for element in element.children]
|
||||
else: # standard fields (e.g. address)
|
||||
name = element.tagname
|
||||
value = element.astext()
|
||||
|
|
|
|||
6
pelican/tests/content/article_with_multiple_authors.rst
Normal file
6
pelican/tests/content/article_with_multiple_authors.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
This is an article with multiple authors!
|
||||
#########################################
|
||||
|
||||
:date: 2014-02-09 02:20
|
||||
:modified: 2014-02-09 02:20
|
||||
:authors: First Author, Second Author
|
||||
|
|
@ -346,6 +346,17 @@ class TestPage(unittest.TestCase):
|
|||
'<a href="http://notmyidea.org/article-spaces.html">link</a>'
|
||||
)
|
||||
|
||||
def test_multiple_authors(self):
|
||||
"""Test article with multiple authors."""
|
||||
args = self.page_kwargs.copy()
|
||||
content = Page(**args)
|
||||
assert content.authors == [content.author]
|
||||
args['metadata'].pop('author')
|
||||
args['metadata']['authors'] = ['First Author', 'Second Author']
|
||||
content = Page(**args)
|
||||
assert content.authors
|
||||
assert content.author == content.authors[0]
|
||||
|
||||
|
||||
class TestArticle(TestPage):
|
||||
def test_template(self):
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
['This is a super article !', 'published', 'Default', 'article'],
|
||||
['This is an article with category !', 'published', 'yeah',
|
||||
'article'],
|
||||
['This is an article with multiple authors!', 'published', 'Default', 'article'],
|
||||
['This is an article without category !', 'published', 'Default',
|
||||
'article'],
|
||||
['This is an article without category !', 'published',
|
||||
|
|
@ -257,6 +258,16 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings,
|
||||
blog=True, dates=dates)
|
||||
|
||||
def test_generate_authors(self):
|
||||
"""Check authors generation."""
|
||||
authors = [author.name for author, _ in self.generator.authors]
|
||||
authors_expected = sorted(['Alexis Métaireau', 'First Author', 'Second Author'])
|
||||
self.assertEqual(sorted(authors), authors_expected)
|
||||
# test for slug
|
||||
authors = [author.slug for author, _ in self.generator.authors]
|
||||
authors_expected = ['alexis-metaireau', 'first-author', 'second-author']
|
||||
self.assertEqual(sorted(authors), sorted(authors_expected))
|
||||
|
||||
|
||||
class TestPageGenerator(unittest.TestCase):
|
||||
# Note: Every time you want to test for a new field; Make sure the test
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from pelican.tests.support import (unittest, temporary_folder, mute,
|
|||
|
||||
from pelican.utils import slugify
|
||||
|
||||
CUR_DIR = os.path.dirname(__file__)
|
||||
CUR_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
WORDPRESS_XML_SAMPLE = os.path.join(CUR_DIR, 'content', 'wordpressexport.xml')
|
||||
WORDPRESS_ENCODED_CONTENT_SAMPLE = os.path.join(CUR_DIR,
|
||||
'content',
|
||||
|
|
@ -75,7 +75,7 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
out_name = fnames[index]
|
||||
self.assertTrue(out_name.endswith(filename))
|
||||
index += 1
|
||||
|
||||
|
||||
def test_unless_custom_post_all_items_should_be_pages_or_posts(self):
|
||||
self.assertTrue(self.posts)
|
||||
pages_data = []
|
||||
|
|
@ -85,7 +85,7 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
else:
|
||||
pages_data.append((title, fname))
|
||||
self.assertEqual(0, len(pages_data))
|
||||
|
||||
|
||||
def test_recognise_custom_post_type(self):
|
||||
self.assertTrue(self.custposts)
|
||||
cust_data = []
|
||||
|
|
@ -98,7 +98,7 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
self.assertEqual(('A custom post in category 4', 'custom1'), cust_data[0])
|
||||
self.assertEqual(('A custom post in category 5', 'custom1'), cust_data[1])
|
||||
self.assertEqual(('A 2nd custom post type also in category 5', 'custom2'), cust_data[2])
|
||||
|
||||
|
||||
def test_custom_posts_put_in_own_dir(self):
|
||||
silent_f2p = mute(True)(fields2pelican)
|
||||
test_posts = []
|
||||
|
|
@ -130,7 +130,7 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
else:
|
||||
test_posts.append(post)
|
||||
with temporary_folder() as temp:
|
||||
fnames = list(silent_f2p(test_posts, 'markdown', temp,
|
||||
fnames = list(silent_f2p(test_posts, 'markdown', temp,
|
||||
wp_custpost=True, dircat=True))
|
||||
index = 0
|
||||
for post in test_posts:
|
||||
|
|
@ -152,7 +152,7 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
if post[7] == 'page':
|
||||
test_posts.append(post)
|
||||
with temporary_folder() as temp:
|
||||
fnames = list(silent_f2p(test_posts, 'markdown', temp,
|
||||
fnames = list(silent_f2p(test_posts, 'markdown', temp,
|
||||
wp_custpost=True, dirpage=False))
|
||||
index = 0
|
||||
for post in test_posts:
|
||||
|
|
@ -161,8 +161,8 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
filename = os.path.join('pages', name)
|
||||
out_name = fnames[index]
|
||||
self.assertFalse(out_name.endswith(filename))
|
||||
|
||||
|
||||
|
||||
|
||||
def test_can_toggle_raw_html_code_parsing(self):
|
||||
def r(f):
|
||||
with open(f) as infile:
|
||||
|
|
@ -247,9 +247,9 @@ class TestBuildHeader(unittest.TestCase):
|
|||
'##############################################\n\n')
|
||||
|
||||
def test_galleries_added_to_header(self):
|
||||
header = build_header('test', None, None, None, None,
|
||||
header = build_header('test', None, None, None, None,
|
||||
None, ['output/test1', 'output/test2'])
|
||||
self.assertEqual(header, 'test\n####\n' + ':attachments: output/test1, '
|
||||
self.assertEqual(header, 'test\n####\n' + ':attachments: output/test1, '
|
||||
+ 'output/test2\n\n')
|
||||
|
||||
def test_galleries_added_to_markdown_header(self):
|
||||
|
|
@ -258,11 +258,11 @@ class TestBuildHeader(unittest.TestCase):
|
|||
self.assertEqual(header, 'Title: test\n' + 'Attachments: output/test1, '
|
||||
+ 'output/test2\n\n')
|
||||
|
||||
@unittest.skipUnless(BeautifulSoup, 'Needs BeautifulSoup module')
|
||||
class TestWordpressXMLAttachements(unittest.TestCase):
|
||||
@unittest.skipUnless(BeautifulSoup, 'Needs BeautifulSoup module')
|
||||
class TestWordpressXMLAttachements(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.attachments = get_attachments(WORDPRESS_XML_SAMPLE)
|
||||
|
||||
|
||||
def test_recognise_attachments(self):
|
||||
self.assertTrue(self.attachments)
|
||||
self.assertTrue(len(self.attachments.keys()) == 3)
|
||||
|
|
@ -283,7 +283,7 @@ class TestWordpressXMLAttachements(unittest.TestCase):
|
|||
def test_download_attachments(self):
|
||||
real_file = os.path.join(CUR_DIR, 'content/article.rst')
|
||||
good_url = 'file://' + real_file
|
||||
bad_url = 'http://www.notarealsite.notarealdomain/not_a_file.txt'
|
||||
bad_url = 'http://localhost:1/not_a_file.txt'
|
||||
silent_da = mute()(download_attachments)
|
||||
with temporary_folder() as temp:
|
||||
#locations = download_attachments(temp, [good_url, bad_url])
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
from __future__ import unicode_literals, print_function
|
||||
|
||||
import os
|
||||
from filecmp import dircmp
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
import locale
|
||||
import logging
|
||||
import subprocess
|
||||
|
||||
from pelican import Pelican
|
||||
from pelican.settings import read_settings
|
||||
|
|
@ -64,6 +64,13 @@ class TestPelican(LoggedTestCase):
|
|||
self.assertEqual(diff['right_only'], [], msg=msg)
|
||||
self.assertEqual(diff['diff_files'], [], msg=msg)
|
||||
|
||||
def assertDirsEqual(self, left_path, right_path):
|
||||
out, err = subprocess.Popen(
|
||||
['git', 'diff', '--no-ext-diff', '--exit-code', '-w', left_path, right_path], env={'PAGER': ''},
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
|
||||
assert not out, out
|
||||
assert not err, err
|
||||
|
||||
def test_basic_generation_works(self):
|
||||
# when running pelican without settings, it should pick up the default
|
||||
# ones and generate correct output without raising any exception
|
||||
|
|
@ -74,8 +81,7 @@ class TestPelican(LoggedTestCase):
|
|||
})
|
||||
pelican = Pelican(settings=settings)
|
||||
mute(True)(pelican.run)()
|
||||
dcmp = dircmp(self.temp_path, os.path.join(OUTPUT_PATH, 'basic'))
|
||||
self.assertFilesEqual(recursiveDiff(dcmp))
|
||||
self.assertDirsEqual(self.temp_path, os.path.join(OUTPUT_PATH, 'basic'))
|
||||
self.assertLogCountEqual(
|
||||
count=4,
|
||||
msg="Unable to find.*skipping url replacement",
|
||||
|
|
@ -90,8 +96,7 @@ class TestPelican(LoggedTestCase):
|
|||
})
|
||||
pelican = Pelican(settings=settings)
|
||||
mute(True)(pelican.run)()
|
||||
dcmp = dircmp(self.temp_path, os.path.join(OUTPUT_PATH, 'custom'))
|
||||
self.assertFilesEqual(recursiveDiff(dcmp))
|
||||
self.assertDirsEqual(self.temp_path, os.path.join(OUTPUT_PATH, 'custom'))
|
||||
|
||||
def test_theme_static_paths_copy(self):
|
||||
# the same thing with a specified set of settings should work
|
||||
|
|
|
|||
|
|
@ -360,6 +360,15 @@ class HTMLReaderTest(ReaderTest):
|
|||
for key, value in expected.items():
|
||||
self.assertEqual(value, page.metadata[key], key)
|
||||
|
||||
def test_article_with_multiple_authors(self):
|
||||
page = self.read_file(path='article_with_multiple_authors.rst')
|
||||
expected = {
|
||||
'authors': ['First Author', 'Second Author']
|
||||
}
|
||||
|
||||
for key, value in expected.items():
|
||||
self.assertEqual(value, page.metadata[key], key)
|
||||
|
||||
def test_article_with_metadata_and_contents_attrib(self):
|
||||
page = self.read_file(path='article_with_metadata_and_contents.html')
|
||||
expected = {
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@
|
|||
</abbr>
|
||||
{% endif %}
|
||||
|
||||
{% if article.author %}
|
||||
{% if article.authors %}
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="{{ SITEURL }}/{{ article.author.url }}">{{ article.author }}</a>
|
||||
By {% for author in article.authors %}
|
||||
<a class="url fn" href="{{ SITEURL }}/{{ author.url }}">{{ author }}</a>
|
||||
{% endfor %}
|
||||
</address>
|
||||
{% endif %}
|
||||
<p>In <a href="{{ SITEURL }}/{{ article.category.url }}">{{ article.category }}</a>. {% if PDF_PROCESSOR %}<a href="{{ SITEURL }}/pdf/{{ article.slug }}.pdf">get the pdf</a>{% endif %}</p>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
<section id="content" class="body">
|
||||
<h1>Authors on {{ SITENAME }}</h1>
|
||||
|
||||
{%- for author, articles in authors|sort %}
|
||||
<li><a href="{{ SITEURL }}/{{ author.url }}">{{ author }}</a> ({{ articles|count }})</li>
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,11 @@
|
|||
{{ article.locale_modified }}
|
||||
</abbr>
|
||||
{% endif %}
|
||||
{% if article.author %}
|
||||
{% if article.authors %}
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="{{ SITEURL }}/{{ article.author.url }}">{{ article.author }}</a>
|
||||
By {% for author in article.authors %}
|
||||
<a class="url fn" href="{{ SITEURL }}/{{ author.url }}">{{ author }}</a>
|
||||
{% endfor %}
|
||||
</address>
|
||||
{% endif %}
|
||||
</footer><!-- /.post-info -->
|
||||
|
|
|
|||
|
|
@ -11,7 +11,11 @@
|
|||
<header> <h2 class="entry-title"><a href="{{ SITEURL }}/{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title|striptags }}">{{ article.title }}</a></h2> </header>
|
||||
<footer class="post-info">
|
||||
<abbr class="published" title="{{ article.date.isoformat() }}"> {{ article.locale_date }} </abbr>
|
||||
{% if article.author %}<address class="vcard author">By <a class="url fn" href="{{ SITEURL }}/{{ article.author.url }}">{{ article.author }}</a></address>{% endif %}
|
||||
<address class="vcard author">By
|
||||
{% for author in article.authors %}
|
||||
<a class="url fn" href="{{ SITEURL }}/{{ author.url }}">{{ author }}</a>
|
||||
{% endfor %}
|
||||
</address>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content"> {{ article.summary }} </div><!-- /.entry-content -->
|
||||
</article></li>
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ def get_filename(filename, post_id):
|
|||
|
||||
def wp2fields(xml, wp_custpost=False):
|
||||
"""Opens a wordpress XML file, and yield Pelican fields"""
|
||||
|
||||
|
||||
items = get_items(xml)
|
||||
for item in items:
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ def wp2fields(xml, wp_custpost=False):
|
|||
filename = item.find('post_name').string
|
||||
post_id = item.find('post_id').string
|
||||
filename = get_filename(filename, post_id)
|
||||
|
||||
|
||||
content = item.find('encoded').string
|
||||
raw_date = item.find('post_date').string
|
||||
date_object = time.strptime(raw_date, "%Y-%m-%d %H:%M:%S")
|
||||
|
|
@ -161,7 +161,7 @@ def wp2fields(xml, wp_custpost=False):
|
|||
pass
|
||||
# Old behaviour was to name everything not a page as an article.
|
||||
# Theoretically all attachments have status == inherit so
|
||||
# no attachments should be here. But this statement is to
|
||||
# no attachments should be here. But this statement is to
|
||||
# maintain existing behaviour in case that doesn't hold true.
|
||||
elif post_type == 'attachment':
|
||||
pass
|
||||
|
|
@ -469,7 +469,7 @@ def build_header(title, date, author, categories, tags, slug, attachments=None):
|
|||
header += '\n'
|
||||
return header
|
||||
|
||||
def build_markdown_header(title, date, author, categories, tags, slug,
|
||||
def build_markdown_header(title, date, author, categories, tags, slug,
|
||||
attachments=None):
|
||||
"""Build a header from a list of fields"""
|
||||
header = 'Title: %s\n' % title
|
||||
|
|
@ -494,8 +494,8 @@ def get_ext(out_markup, in_markup='html'):
|
|||
else:
|
||||
ext = '.rst'
|
||||
return ext
|
||||
|
||||
def get_out_filename(output_path, filename, ext, kind,
|
||||
|
||||
def get_out_filename(output_path, filename, ext, kind,
|
||||
dirpage, dircat, categories, wp_custpost):
|
||||
filename = os.path.basename(filename)
|
||||
|
||||
|
|
@ -516,7 +516,7 @@ def get_out_filename(output_path, filename, ext, kind,
|
|||
os.mkdir(pages_dir)
|
||||
out_filename = os.path.join(pages_dir, filename+ext)
|
||||
elif not dirpage and kind == 'page':
|
||||
pass
|
||||
pass
|
||||
# option to put wp custom post types in directories with post type
|
||||
# names. Custom post types can also have categories so option to
|
||||
# create subdirectories with category names
|
||||
|
|
@ -530,7 +530,7 @@ def get_out_filename(output_path, filename, ext, kind,
|
|||
catname = slugify(categories[0])
|
||||
else:
|
||||
catname = ''
|
||||
out_filename = os.path.join(output_path, typename,
|
||||
out_filename = os.path.join(output_path, typename,
|
||||
catname, filename+ext)
|
||||
if not os.path.isdir(os.path.join(output_path, typename, catname)):
|
||||
os.makedirs(os.path.join(output_path, typename, catname))
|
||||
|
|
@ -544,20 +544,20 @@ def get_out_filename(output_path, filename, ext, kind,
|
|||
return out_filename
|
||||
|
||||
def get_attachments(xml):
|
||||
"""returns a dictionary of posts that have attachments with a list
|
||||
"""returns a dictionary of posts that have attachments with a list
|
||||
of the attachment_urls
|
||||
"""
|
||||
items = get_items(xml)
|
||||
names = {}
|
||||
attachments = []
|
||||
|
||||
|
||||
for item in items:
|
||||
kind = item.find('post_type').string
|
||||
filename = item.find('post_name').string
|
||||
post_id = item.find('post_id').string
|
||||
|
||||
|
||||
if kind == 'attachment':
|
||||
attachments.append((item.find('post_parent').string,
|
||||
attachments.append((item.find('post_parent').string,
|
||||
item.find('attachment_url').string))
|
||||
else:
|
||||
filename = get_filename(filename, post_id)
|
||||
|
|
@ -569,7 +569,7 @@ def get_attachments(xml):
|
|||
except KeyError:
|
||||
#attachment's parent is not a valid post
|
||||
parent_name = None
|
||||
|
||||
|
||||
try:
|
||||
attachedposts[parent_name].append(url)
|
||||
except KeyError:
|
||||
|
|
@ -578,13 +578,13 @@ def get_attachments(xml):
|
|||
return attachedposts
|
||||
|
||||
def download_attachments(output_path, urls):
|
||||
"""Downloads wordpress attachments and returns a list of paths to
|
||||
attachments that can be associated with a post (relative path to output
|
||||
"""Downloads wordpress attachments and returns a list of paths to
|
||||
attachments that can be associated with a post (relative path to output
|
||||
directory). Files that fail to download, will not be added to posts"""
|
||||
locations = []
|
||||
for url in urls:
|
||||
path = urlparse(url).path
|
||||
#teardown path and rebuild to negate any errors with
|
||||
#teardown path and rebuild to negate any errors with
|
||||
#os.path.join and leading /'s
|
||||
path = path.split('/')
|
||||
filename = path.pop(-1)
|
||||
|
|
@ -625,16 +625,16 @@ def fields2pelican(fields, out_markup, output_path,
|
|||
attached_files = download_attachments(output_path, urls)
|
||||
except KeyError:
|
||||
attached_files = None
|
||||
else:
|
||||
else:
|
||||
attached_files = None
|
||||
|
||||
ext = get_ext(out_markup, in_markup)
|
||||
if ext == '.md':
|
||||
header = build_markdown_header(title, date, author, categories,
|
||||
header = build_markdown_header(title, date, author, categories,
|
||||
tags, slug, attached_files)
|
||||
else:
|
||||
out_markup = "rst"
|
||||
header = build_header(title, date, author, categories,
|
||||
header = build_header(title, date, author, categories,
|
||||
tags, slug, attached_files)
|
||||
|
||||
out_filename = get_out_filename(output_path, filename, ext,
|
||||
|
|
@ -690,7 +690,7 @@ def fields2pelican(fields, out_markup, output_path,
|
|||
print("downloading attachments that don't have a parent post")
|
||||
urls = attachments[None]
|
||||
orphan_galleries = download_attachments(output_path, urls)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Transform feed, WordPress, Tumblr, Dotclear, or Posterous "
|
||||
|
|
@ -723,7 +723,7 @@ def main():
|
|||
parser.add_argument('--strip-raw', action='store_true', dest='strip_raw',
|
||||
help="Strip raw HTML code that can't be converted to "
|
||||
"markup such as flash embeds or iframes (wordpress import only)")
|
||||
parser.add_argument('--wp-custpost', action='store_true',
|
||||
parser.add_argument('--wp-custpost', action='store_true',
|
||||
dest='wp_custpost',
|
||||
help='Put wordpress custom post types in directories. If used with '
|
||||
'--dir-cat option directories will be created as '
|
||||
|
|
@ -775,7 +775,7 @@ def main():
|
|||
if args.wp_attach and input_type != 'wordpress':
|
||||
error = "You must be importing a wordpress xml to use the --wp-attach option"
|
||||
exit(error)
|
||||
|
||||
|
||||
if input_type == 'wordpress':
|
||||
fields = wp2fields(args.input, args.wp_custpost or False)
|
||||
elif input_type == 'dotclear':
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue