From bac73b1a858c6faac64a2846bd872c0c1c5b050e Mon Sep 17 00:00:00 2001 From: "Ivan I. Ovchinnikov" Date: Tue, 11 Apr 2023 19:09:03 +0300 Subject: [PATCH] l4 checked --- src/rss_parse.erl | 50 +++++++++++++++++++++++++++++++++++------------ src/rss_queue.erl | 24 +++++++++++++++++++++++ 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/rss_parse.erl b/src/rss_parse.erl index 7bdaf58..93ce79e 100644 --- a/src/rss_parse.erl +++ b/src/rss_parse.erl @@ -13,13 +13,15 @@ is_rss2_feed(Name)-> % Возвращает список элементов get_feed_items(N) -> - xmerl_xpath:string("//channel/item", N). + xmerl_xpath:string("//item", N). % пока не проверена (не на чем, а функцию поэлементоно разбирающую список есть ощущение, что я буду писать в одном из следующих пунктов) get_item_time(Item) -> - [M] = Item, [#xmlText{value=Text}] = xmerl_xpath:string("pubDate/text()", M), - {{Year,Month,Date},{Hour,Min,Sec}} = httpd_util:convert_request_date(Text), - calendar:datetime_to_gregorian_seconds({{Year,Month,Date},{Hour,Min,Sec}}). + PubDateXPath = "//pubDate", + [PubDateNode | _] = xmerl_xpath:string(PubDateXPath, Item), + [PubDate | _] = PubDateNode#xmlElement.content, + DateTime = httpd_util:convert_request_date(PubDate#xmlText.value), % bad_time if wrong + calendar:datetime_to_gregorian_seconds(DateTime). % @private % @doc Эта вспомогательная функция просматривает заданный XML элемент @@ -41,11 +43,35 @@ extract_xml(Comment = #xmlComment{}) -> extract_xml(Other) -> Other. -compare_feed_items(OldItem, NewItem) -> - [A] = OldItem, [B] = NewItem, - G1 = xmerl_xs:select("guid", A), G2 = xmerl_xs:select("guid", B), - T1 = xmerl_xs:select("title", A), T2 = xmerl_xs:select("title", B), - L1 = xmerl_xs:select("link", A), L2 = xmerl_xs:select("link", B), - ((G1 /= []) andalso (G2 /= []) andalso (G1 == G2)) orelse - ((T1 /= []) andalso (T2 /= []) andalso (T1 == T2)) orelse - ((L1 /= []) andalso (L2 /= []) andalso (L1 == L2)). +compare_feed_items(OldItemRow, NewItemRow) -> + OldItem = extract_xml(OldItemRow), + NewItem = extract_xml(NewItemRow), + + case OldItem =:= NewItem of + true -> same; + _ -> + Handler = fun(E, Acc) -> + Acc or is_updated(OldItem, NewItem, E) + end, + Acc = false, + ListXPathAttrs = ["//guid", "//title", "//link"], + + case lists:foldl(Handler, Acc, ListXPathAttrs) of + true -> updated; + _ -> different + end + end. + +is_updated(OldItem, NewItem, XPathAttr) -> + OldAttrValue = xmerl_xpath:string(XPathAttr, OldItem), + case OldAttrValue of + [] -> false; + _ -> NewAttrValue = xmerl_xpath:string(XPathAttr, NewItem), + case NewAttrValue of + [] -> false ; + _ -> + [OldGUID] = OldAttrValue, + [NewGUID] = NewAttrValue, + OldGUID == NewGUID + end + end. diff --git a/src/rss_queue.erl b/src/rss_queue.erl index 53e333a..93ac081 100644 --- a/src/rss_queue.erl +++ b/src/rss_queue.erl @@ -35,6 +35,10 @@ server(Queue) -> % 2.1 Пока состояние очереди должно server(Queue) end. +%% @doc Поиск в листе элемента +search_item(RSSItem, []) -> + {different, RSSItem}; + %% @doc Поиск элемента search_item(RSSItem, Queue) -> [Head | Tail] = Queue, @@ -64,6 +68,7 @@ get_all(QPid) when is_pid(QPid) -> QPid ! {get_all, self()}, receive {QPid, List} -> + io:format("length ~p~n",[length(List)]), List after 1000 -> {error, timeout} @@ -75,6 +80,25 @@ test() -> {XML, _} = xmerl_scan:file("digg-science-rss2.xml"), {XMLOTHER, _} = xmerl_scan:file("digg-science-rss1.xml"), add_feed(PID, XML), + get_all(PID), add_feed(PID, XMLOTHER), + get_all(PID), add_feed(PID, XML), get_all(PID). + + +%% 12> rss_queue:test(). +%% =ERROR REPORT==== 11-Apr-2023::18:53:55.974721 === +%% Error in process <0.125.0> with exit value: +%% {{badmatch,[]}, +%% [{rss_queue,search_item,2,[{file,"rss_queue.erl"},{line,40}]}, +%% {rss_queue,push_item,2,[{file,"rss_queue.erl"},{line,16}]}, +%% {rss_queue,server,1,[{file,"rss_queue.erl"},{line,31}]}]} +%% дополнительно потребовало написания функции поиска для принимаемого пустого списка с явным возвратом атома дифф + +%% 11> rss_queue:test(). +%% length 40 +%% length 43 +%% length 43 + +%% очевидно, что в результате добавления второго файла добавилось 3 новости, более подробно можно отследить операции, логируя каждое изменение списка (функции добавления фида, поиска и добавления итемов)