From 54e6dd0462cc0f850e4ab4e68157bc368df90b64 Mon Sep 17 00:00:00 2001 From: Alexandr Nesterenko Date: Sat, 9 Jul 2016 16:20:01 -0700 Subject: [PATCH] create feed is ready --- frontend/frontend/setup_tool.py | 31 ++++++- .../static/frontend/assets/js/setup-tool.js | 88 +++++++++++++++++-- .../frontend/templates/frontend/setup.html | 2 +- frontend/frontend/urls.py | 1 + frontend/frontend/views.py | 43 ++++++++- 5 files changed, 154 insertions(+), 11 deletions(-) diff --git a/frontend/frontend/setup_tool.py b/frontend/frontend/setup_tool.py index 4a39921..48b59d1 100644 --- a/frontend/frontend/setup_tool.py +++ b/frontend/frontend/setup_tool.py @@ -98,7 +98,7 @@ def get_selection_tag_ids(item_tag_ids, html_json): for name in item_tag_ids: tag_id = item_tag_ids[name] parent_stacks[name] = _build_parent_stack(html_json, tag_id) - #import pdb; pdb.set_trace() + # get fork fork_stack = _get_fork_stack(parent_stacks) @@ -128,3 +128,32 @@ def get_selection_tag_ids(item_tag_ids, html_json): selection_ids[name].append(ids[name]) return selection_ids + +def _path_stack_to_xpath(stack): + stack + +def build_xpathes_for_items(item_tag_ids, html_json): + parent_stacks = {} + + # buld parent stacks for every item name + for name in item_tag_ids: + tag_id = item_tag_ids[name] + parent_stacks[name] = _build_parent_stack(html_json, tag_id) + + # get fork + fork_stack = _get_fork_stack(parent_stacks) + + # get fork path + fork_path = [tag[I_TAGNAME] for tag in fork_stack] + + # get pathes for items + fork_len = len(fork_path) - 1 + selection_pathes = {name:_build_path(parent_stacks[name][fork_len:]) for name in parent_stacks} + + # build xpathes + feed_xpath = '/' + '/'.join(fork_path) + item_xpathes = {} + for name in selection_pathes: + item_xpathes[name] = '/'.join([repr(path_item) for path_item in selection_pathes[name]]) + + return [feed_xpath, item_xpathes] diff --git a/frontend/frontend/static/frontend/assets/js/setup-tool.js b/frontend/frontend/static/frontend/assets/js/setup-tool.js index baad091..0c6c394 100644 --- a/frontend/frontend/static/frontend/assets/js/setup-tool.js +++ b/frontend/frontend/static/frontend/assets/js/setup-tool.js @@ -168,6 +168,7 @@ function Item(name, button) { $(button).css('color', 'white'); break; } + updateCreateButton(); } /** @@ -289,11 +290,7 @@ function buildJsonFromHtml(doc) { return iframeHtmlJson; } -function requestSelection() { - var htmlJson = buildJsonFromHtml($('iframe').contents()); - - // gather selected tag-ids - var name_ids = {}; +function gatherSelectedTagIds(name_ids) { var selected_any = false; for (var name in items) { if ([STATE_SELECTING, STATE_SELECTED].indexOf(items[name].state) != -1) { @@ -301,6 +298,15 @@ function requestSelection() { selected_any = true; } } + return selected_any; +} + +function requestSelection() { + var htmlJson = buildJsonFromHtml($('iframe').contents()); + + // gather selected tag-ids + var name_ids = {}; + selected_any = gatherSelectedTagIds(name_ids); if (selected_any) return new Promise(function(resolve, reject){ @@ -353,6 +359,7 @@ function onIframeElementHover(event) { } else { // mouseleave // clear all hover styles + // if mouseleave calls after mouseenter we may have a problem styleTool.unstyleAll('hover'); } } @@ -388,11 +395,79 @@ function onItemButtonClick(event) { curItemData = null; } } +//// +// ++++ Create button logic +//// +function updateCreateButton() { + var active = false; + + for (var name in items) + if (items[name].state == STATE_SELECTED) { + active = true; + break; + } + + if (active) + $('#create').removeClass('disabled'); + else + $('#create').addClass('disabled'); +} + +function onCreateButtonClick() { + var active = !$('#create').hasClass('disabled'); + if (active) + //todo: freeze UI + createFeed().then(function(feed_page_url){ + alert(feed_page_url); + //window.location.href = feed_page_url; + }, function(error){ + //todo: unfreez UI + console.log('Server error: '+ error); + }); +} + +function createFeed() { + var htmlJson = buildJsonFromHtml($('iframe').contents()); + + // gather selected tag-ids + var name_ids = {}; + selected_any = gatherSelectedTagIds(name_ids); + + if (selected_any) + return new Promise(function(resolve, reject){ + $.ajax({ + type: 'POST', + url: "/setup_create_feed", + data: JSON.stringify({ html: htmlJson, names: name_ids, url:$('#create').data('page-url') }), + contentType: "application/json; charset=utf-8", + dataType: "json", + headers: {"X-CSRFToken": getCookie('csrftoken')}, + success: function(data){ + resolve(data) + }, + failure: function(errMsg) { + reject(errMsg); + } + }); + console.log(JSON.stringify(htmlJson)); + }); + else { + return new Promise(function(resolve, reject){ + setTimeout(function(){ resolve({}); }, 0); + }); + } +} +//// +// ++++ Create button logic +//// + $(document).ready(function(){ items['title'] = new Item('title', $('#st-title')[0]); items['description'] = new Item('description', $('#st-description')[0]); - + + $('#create').click(onCreateButtonClick); + $('iframe').load(function(){ // init id2el $('iframe').contents().find('*[tag-id]').each(function(){ @@ -401,7 +476,6 @@ $(document).ready(function(){ // attach iframe elements event handlers $('iframe').contents().on('click', '*[tag-id]', onIframeElementClick); $('iframe').contents().on('mouseenter mouseleave', '*[tag-id]', onIframeElementHover); - }); blinkButton($('#st-title'), 3); diff --git a/frontend/frontend/templates/frontend/setup.html b/frontend/frontend/templates/frontend/setup.html index fe8e335..4afdc28 100644 --- a/frontend/frontend/templates/frontend/setup.html +++ b/frontend/frontend/templates/frontend/setup.html @@ -8,7 +8,7 @@ and . - + diff --git a/frontend/frontend/urls.py b/frontend/frontend/urls.py index 11f8678..af9b30c 100644 --- a/frontend/frontend/urls.py +++ b/frontend/frontend/urls.py @@ -26,3 +26,4 @@ urlpatterns = i18n_patterns( ) urlpatterns.append(url(r'^setup_get_selected_ids$', views.setup_get_selected_ids, name='setup_get_selected_ids')) +urlpatterns.append(url(r'^setup_create_feed$', views.setup_create_feed, name='setup_create_feed')) diff --git a/frontend/frontend/views.py b/frontend/frontend/views.py index bea6832..6c8aa34 100644 --- a/frontend/frontend/views.py +++ b/frontend/frontend/views.py @@ -11,7 +11,8 @@ from django.core.urlresolvers import reverse from .forms import IndexForm from .settings import DOWNLOADER_PAGE_URL -from .setup_tool import get_selection_tag_ids +from .setup_tool import get_selection_tag_ids, build_xpathes_for_items +from .models import Feed, Field, FeedField def index(request): if request.method == 'GET' and 'url' in request.GET: @@ -33,7 +34,12 @@ def index(request): def setup(request): if request.method == 'GET' and 'url' in request.GET: external_page_url = DOWNLOADER_PAGE_URL + urllib.quote(request.GET['url'], safe='') - return render(request, 'frontend/setup.html', {'external_page_url': external_page_url}) + return render(request, 'frontend/setup.html', + { + 'external_page_url': external_page_url, + 'page_url': request.GET['url'], + 'feed_page_url': reverse('setup_create_feed') # todo: replace with feedpage + }) return HttpResponseBadRequest('Url is required') @@ -64,3 +70,36 @@ def setup_get_selected_ids(request): return HttpResponseBadRequest('html is invalid') return HttpResponse(json.dumps(get_selection_tag_ids(item_names, html_json))) + +def _create_feed(url, xpathes): + feed_xpath = xpathes[0] + item_xpathes = xpathes[1] + + #import pdb; pdb.set_trace() + feed = Feed(uri=url, xpath=feed_xpath) + feed.save() + + fields = Field.objects.all() + + for field in fields: + ff = FeedField(feed=feed, field=field, xpath=item_xpathes[field.name]) + ff.save() + + return feed.id + +def setup_create_feed(request): + if request.method == 'POST': + obj = json.loads(request.body) + if 'html' not in obj or 'names' not in obj or 'url' not in obj: + return HttpResponseBadRequest('"html", "names" and "url" parameters are required') + html_json = obj['html'] + item_names = obj['names'] + url = obj['url'] + + if not _validate_html(html_json): + return HttpResponseBadRequest('html is invalid') + + xpathes = build_xpathes_for_items(item_names, html_json) + feed_id = _create_feed(url, xpathes) + + return HttpResponse(feed_id)