diff --git a/README.md b/README.md index 4e505315b8f0e494fadf2df316349f072b875ef0..cc5b3aa40b9a5c27555a87f4b3f945fc210baf34 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ WordPress plugin. ## Supported Sources - [Ecwid](https://support.ecwid.com/hc/en-us/articles/207099979-Import-Export) +- [DPSounds](https://dpsounds.com) custom CSV format ## Usage `wooify.py adapter input_file` diff --git a/wooify/adapters/adapter.py b/wooify/adapters/adapter.py index b5c44a7cc8f57a2a7136ba66ddfc747bd49d2d0d..fab88d2a354ae39cca85b1739f90a4be86027b0d 100644 --- a/wooify/adapters/adapter.py +++ b/wooify/adapters/adapter.py @@ -27,6 +27,8 @@ class Adapter(object): def _clean_html(self, html_string): """Remove all attributes from HTML string.""" + if not html_string: + return '' cleaner = lxml.html.clean.Cleaner( allow_tags=ALLOWED_HTML_TAGS, remove_unknown_tags=False, page_structure=False, safe_attrs_only=True, safe_attrs=frozenset()) diff --git a/wooify/adapters/dpsounds.py b/wooify/adapters/dpsounds.py new file mode 100644 index 0000000000000000000000000000000000000000..62cab61a91873f598f7fe71371dbe50ddb9a2cb0 --- /dev/null +++ b/wooify/adapters/dpsounds.py @@ -0,0 +1,73 @@ +import csv +import json +import hashlib +from .adapter import Adapter as BaseAdapter +from ..constants import (ALLOWED_HTML_TAGS, HTML_FIELDS, + WOO_IMP_EXP_PRODUCT_FIELDS) + +DP_TRACK_URL_BASE = 'https://ant.sr/dpsounds-audio' +DP_TRACK_CATEGORIES = json.dumps([{'name': 'Music', 'slug': 'music'}]) +DP_TRACK_ATTRIBUTES = ['Time', 'Origin'] +DP_TRACK_PRICE = 1 + + +class DpsoundsAdapter(BaseAdapter): + """Input handler for spreadsheets received from my dad + for dpsounds.com. + Headers: + "Source Part","Source Track","Track", + "Title","Time","Origin","Tags", + "Alternative Takes","Compilation". + """ + + def parse(self, filename): + """Parse a CSV file for DPSounds.com.""" + def parse_row(r): + """Parse a row of Dad's CSV file and rearrange the fields for + WooCommerce.""" + name = "Track {}".format(r['Track']) + if r['Title']: + name += " - {}".format(r['Title']) + tags = ','.join([t.strip() for t in r['Tags'].split(',')]) + file_url = "{url_base}/{part}-{track:02d}.mp3".format( + url_base=DP_TRACK_URL_BASE, + part=r['Source Part'], + track=int(r['Source Track'])) + filehash = hashlib.md5(file_url.encode('utf-8')).hexdigest() + files = json.dumps({ + filehash: {'name': name, 'file': file_url}}) + # TODO: alternative takes + # TODO: compilation (album) + # TODO: Description text to include attributes. + attributes = [{ + 'name': attr, + 'value': r[attr], + 'position': idx, + 'is_visible': '1', + 'is_variation': '0', + 'is_taxonomy': '0' + } for idx, attr in enumerate(DP_TRACK_ATTRIBUTES)] + product = dict(WOO_IMP_EXP_PRODUCT_FIELDS) + product.update({ + "Product Name": name, + "Tags": tags, + "Categories": DP_TRACK_CATEGORIES, + "Downloadable": 'yes', + "Virtual": 'yes', + "Sold Individually": 'yes', + "Downloadable Files": files, + "Download Type": "music", + "Price": DP_TRACK_PRICE, + "Regular Price": DP_TRACK_PRICE, + "Attributes": json.dumps(attributes) + }) + return product + + with open(filename) as csv_in: + csv_reader = csv.DictReader(csv_in) + raw_category_names = [] + for row in csv_reader: + product = parse_row(row) + self.products.append(product) + +adapter_cls = DpsoundsAdapter diff --git a/wooify/adapters/ecwid.py b/wooify/adapters/ecwid.py index 06d1de239f07e08d2b3429c7c14767b2ba2e496c..411bf79e42ec2fb55930da9dd0df810644b1146d 100644 --- a/wooify/adapters/ecwid.py +++ b/wooify/adapters/ecwid.py @@ -57,10 +57,10 @@ class EcwidAdapter(BaseAdapter): categories = self._expand_categories(raw_category_names) for product in self.products: if 'Categories' in product and product['Categories']: - product['Categories'] = [{ + product['Categories'] = json.dumps([{ 'name': categories[c]['Name'], 'slug': categories[c]['Slug']} - for c in product['Categories']] + for c in product['Categories']]) self.categories = categories.values() def _expand_categories(self, raw_category_names):