From 30c38cafff10866fb377c55a23ae0bf358613968 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 25 Sep 2013 21:18:47 +0100 Subject: [PATCH] Add a couple of endpoints, one a stub, to be able to read topics using the official client. Many things work. Huzzah. Convo may also work now. --- lib/tapatalker.rb | 92 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 6 deletions(-) diff --git a/lib/tapatalker.rb b/lib/tapatalker.rb index e772d8d..6e3d437 100644 --- a/lib/tapatalker.rb +++ b/lib/tapatalker.rb @@ -69,8 +69,10 @@ helpers do XMLRPC::Base64.new( string ) end - def make_avatar_url( template_txt ) - template_txt.to_s.gsub( "{size}", "160" ) + def make_avatar_url( template_txt, size = 120 ) + template_txt.to_s. + gsub(/\A\/\//, "http://"). # srsly wat, discourse? Well, it's probably for selection between HTTP or HTTPS more easily. But still. + gsub( "{size}", size.to_s ) # url parameter end # Clean up the text, converting it to BBCode (TODO) unless use_html @@ -81,6 +83,50 @@ helpers do html_text end + + def build_tapatalk_topic( discourse_topic, extra = {} ) + result = { + 'forum_id' => discourse_topic["category_id"].to_s, + 'topic_id' => discourse_topic["id"].to_s, + 'topic_title' => binary_xmlrpc( discourse_topic["title"].to_s ), + # 'prefix' => binary_xmlrpc( "" ), # optional + 'post_author_name' => binary_xmlrpc( "" ), + # 'post_author_id' => 0, # required, Int (apparently), level 4 + # 'is_subscribed' => false, # optional + # 'can_subscribe' => false, # optiona; + # 'is_closed' => false, # optional + # 'icon_url' => "" # optional + # participated_uids # optional, level 4 + 'post_time' => make_xmlrpc_datetime( discourse_topic['last_posted_at'] ), + 'reply_number' => discourse_topic['posts_count'].to_i, # reply_count ? + 'new_post' => !!discourse_topic['unseen'], + 'view_number' => discourse_topic['views'].to_i, + # 'short_content' => binary_xmlrpc( "" ) # api level 4, not provided by discourse in some calls + + } + + # Fill in some association-related data + if extra[:categories] + category = extra[:categories].find {|hsh| hsh["id"] == discourse_topic["category_id"] } || {} + result["forum_name"] = binary_xmlrpc( category.fetch( "name", "Uncategorised" ) ) + end + + if discourse_topic["posters"] + orig_poster = discourse_topic["posters"].find {|hsh| hsh['description'].to_s =~ /Original Poster/i } + + result["post_author_id"] = orig_poster["user_id"] if orig_poster + if extra[:users] && result["post_author_id"] + user = extra[:users].find {|hsh| hsh["id"] == result["post_author_id"] } + if user + result["post_author_name"] = binary_xmlrpc( user["username"].to_s ) + result["icon_url"] = make_avatar_url( user["avatar_template"] ) + end + end + + end + + result + end # Try to keep this instance around for as long as possible... @@ -210,7 +256,7 @@ helpers do result = categories.collect {|hsh| tmp = { 'forum_id' => hsh['id'].to_s, - 'forum_name' => hsh['name'].to_s, # FIXME: python encodes this to UTF8. Can't be nil + 'forum_name' => binary_xmlrpc( hsh['name'].to_s ), # FIXME: python encodes this to UTF8. Can't be nil 'parent_id' => "-1", # no such thing as sub-categories in Discourse 'sub_only' => false, # 'child' => [], # Don't return this if we have no children @@ -221,16 +267,50 @@ helpers do } # FIXME: may not be right? - if return_description - tmp['description'] = hsh['description'] - end + # if return_description + # tmp['description'] = binary_xmlrpc( hsh['description'].to_s ) + # end tmp } + + pp result respond_xmlrpc( result ) end + # FIXME: STUB. + # In API level 4, we can say this doesn't exist and force tapatalk to use get_topic + def xmlrpc_get_unread_topic( start_num = 0, last_num = 0, search_id = nil, filters = nil ) + result = { + 'result' => true, + # optional + # 'result_text' => binary_xmlrpc( '' ), + # 'search_id' => '', + } + + result['topics'] = [].collect {|hsh| build_tapatalk_topic( hsh ) } + result['total_topic_num'] = result['topics'].count + + respond_xmlrpc( result ) + end + + def xmlrpc_get_latest_topic( start_num = 0, last_num = 0, search_id = nil, filters = nil ) + + result = { 'result' => true } + + latest_topics = discourse.topics_latest({}) + topic_list = latest_topics.fetch( "topic_list" ) + topics = topic_list.fetch( "topics" ) + + result['topics'] = topics.collect {|hsh| + build_tapatalk_topic( hsh, :users => latest_topics["users"], :categories => latest_topics["categories"] ) + } + result['total_topic_num'] = result['topics'].count # api level 4 + + respond_xmlrpc( result ) + end + def xmlrpc_get_topic( forum_id, start_num = 0, last_num = 0, mode = "DATE" ) category = if forum_id == "0" && %w|ANN TOP|.include?(mode)