//版本日志: // 2009.9.17, 添加了对滴(Dii)微博的支持(不太稳定) // 2009.9.18, 添加了对腾讯(QQ)滔滔的支持 // 2009.10.10, 修正了MEME(咪咪)提交页面地址 // 2009.10.18, 增加火兔(原嘀咕)微博的支持, 同时雅虎咪咪和网址缩短域名bit被墙, 翻墙后不影响全部功能 // 2009.10.22, 去掉MEME更新, 同时把缩短域名服务更换为urlshot.cn. // 2009.11.03, 修改缩短域名服务为更强大的tr.im. // 2010.02.04, 增加Follow5和网易微博, 更换Twitter API, 修正Dii同步. const TWEET_MAXLEN = 140; const TWEET_SHORT_URL_MAX_LENGTH = 17; const URL_SHORTENER_API = 'http://api.tr.im/v1/trim_simple?username=syncmicroblog&password=086420&url='; var multiServiceUpdater = { registeredServices: [ { selector: '#QQ', method: 'updateQQ' }, { selector: '#163', method: 'update163' }, { selector: '#F5', method: 'updateF5' }, { selector: '#SINA', method: 'updateSina' }, { selector: '#DII', method: 'updateDii' }, { selector: '#KAIXIN', method: 'updateKaixin' }, { selector: '#9911', method: 'update9911' }, { selector: '#HUOTU', method: 'updateHuotu' }, { selector: '#ZUOSA', method: 'updateZuosa' }, { selector: '#LEIHOU', method: 'updateLeihou' }, { selector: '#TWITTER', method: 'updateTwitter' }, { selector: '#TEST', method: 'updateTest' }, ], parseActions: function(finalStatusText) { var actions = []; for (var i = 0; i < this.registeredServices.length; i++) { var service = this.registeredServices[i]; if (!service.selector) continue; if (finalStatusText.indexOf(' ' + service.selector) != -1) { finalStatusText = finalStatusText.replace(new RegExp(' ' + service.selector), ''); actions.push(service.selector); } } if (actions.length == 0) { for (var i = 0; i < this.registeredServices.length; i++) { var service = this.registeredServices[i]; if (!service.selector) continue; if ('#TEST' == service.selector) continue; actions.push(service.selector); } } return { 'status': finalStatusText, 'actions': actions }; }, updateStatus: function(finalStatusText) { var result = this.parseActions(finalStatusText); this.processUpdate(result.status, result.actions); }, processUpdate: function(finalStatusText, actions) { if (actions.length <= 0) return; // no action to be processed var action = actions.shift(); var thisObj = this; var cb = function() { // process the next action thisObj.processUpdate(finalStatusText, actions); }; for (var i = 0; i < this.registeredServices.length; i++) { var service = this.registeredServices[i]; if (!service.selector) continue; if (action == service.selector) { this[service.method](finalStatusText, cb); return; } } displayMessage('Unknown action: ' + action); if (cb) cb(); }, updateTest: function(finalStatusText, cb) { displayMessage("Test service updated: " + finalStatusText); if (cb) cb(); }, updateTwitter: function(finalStatusText, cb) { var updateUrl = "http://519it.net/twip/statuses/update.json"; var updateParams = { source: "ubiquity", status: finalStatusText }; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "json", error: function() { displayMessage("[Twitter] Failed to update the status: Not logged in?"); }, success: function() { displayMessage("[Twitter] Status updated: " + finalStatusText); }, complete: function(XMLHttpRequest, textStatus) { if (cb) cb(); }, }); }, updateLeihou: function(finalStatusText, cb) { var updateUrl = "http://leihou.com/statuses/update.json"; var updateParams = { source: "ubiquity", status: finalStatusText }; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "json", error: function() { displayMessage("[Leihou] Failed to update the status: Not logged in?"); }, success: function() { displayMessage("[Leihou] Status updated: " + finalStatusText); }, complete: function(XMLHttpRequest, textStatus) { if (cb) cb(); }, }); }, updateHuotu: function(finalStatusText, cb) { var updateUrl = "http://api.minicloud.com.cn/statuses/update.json"; var updateParams = { source: "ubiquity", content: finalStatusText }; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "json", error: function() { displayMessage("[Huotu] Failed to update the status: Not logged in?"); }, success: function() { displayMessage("[Huotu] Status updated: " + finalStatusText); }, complete: function(XMLHttpRequest, textStatus) { if (cb) cb(); }, }); }, updateZuosa: function(finalStatusText, cb) { var updateUrl = "http://api.zuosa.com/statuses/update.json"; var updateParams = { source: "ubiquity", status: finalStatusText }; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "json", error: function() { displayMessage("[Zuosa] Failed to update the status: Not logged in?"); }, success: function() { displayMessage("[Zuosa] Status updated: " + finalStatusText); }, complete: function(XMLHttpRequest, textStatus) { if (cb) cb(); }, }); }, update9911: function(finalStatusText, cb) { var updateUrl = "http://api.9911.com/statuses/update.json"; var updateParams = { source: "ubiquity", status: finalStatusText }; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "json", error: function() { displayMessage("[9911] Failed to update the status: Not logged in?"); }, success: function() { displayMessage("[9911] Status updated: " + finalStatusText); }, complete: function(XMLHttpRequest, textStatus) { if (cb) cb(); }, }); }, updateKaixin: function(finalStatusText, cb) { var updateUrl = "http://www.kaixin001.com/friend/status_submit.php?rnd=" + Math.random(); var updateParams = { state: finalStatusText, }; var thisObj = this; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "html", error: function() { displayMessage("[Kaixin] Failed to update the status: Not logged in?"); }, success: function(data, textStatus) { displayMessage("[Kaixin] Status updated: " + finalStatusText); }, complete: function(XMLHttpRequest, textStatus) { if (cb) cb(); }, }); }, updateDii: function(finalStatusText, cb) { var updateUrl = "http://m.dii.cn/wap/update.action"; var updateParams = { content: finalStatusText, }; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "html", error: function() { displayMessage("[Dii] Failed to update the status: Not logged in?"); }, success: function(data, textStatus) { displayMessage("[Dii] Status updated: " + finalStatusText); }, complete: function(XMLHttpRequest, textStatus) { if (cb) cb(); }, }); }, updateSina: function(finalStatusText, cb) { var updateUrl = "http://t.sina.com.cn/mblog/publish.php?rnd=" + Math.random(); var updateParams = { content: finalStatusText, from: 'myprofile' }; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "json", error: function() { displayMessage("[Sina] Failed to update the status: Not logged in?"); }, success: function(data, textStatus) { displayMessage("[Sina] Status updated: " + finalStatusText); }, complete: function(XMLHttpRequest, textStatus) { if (cb) cb(); }, beforeSend: function(req) { req.withCredentials = true; req.setRequestHeader('Referer', 'http://t.sina.com.cn/mymblog.php'); }, }); }, update163: function(finalStatusText, cb) { var updateUrl = "http://t.163.com/statuses/update.do"; var updateParams = { status: finalStatusText, }; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "json", error: function() { displayMessage("[163] Failed to update the status: Not logged in?"); }, success: function(data, textStatus) { displayMessage("[163] Status updated: " + finalStatusText); }, complete: function(XMLHttpRequest, textStatus) { if (cb) cb(); }, }); }, updateF5: function(finalStatusText, cb) { var updateUrl = "http://m.follow5.com/mwfm/unote?c=wn¬eToken=" + Math.random(); var updateParams = { noteContent: finalStatusText, }; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "html", error: function() { displayMessage("[Follow5] Failed to update the status: Not logged in?"); }, success: function(data, textStatus) { displayMessage("[Follow5] Status updated: " + finalStatusText); }, complete: function(XMLHttpRequest, textStatus) { if (cb) cb(); }, }); }, updateQQ: function(finalStatusText, cb, retryFlag) { var updateUrl = "http://www.taotao.com/v1/mydaoke/post?rnd=" + Math.random() + "&synqqsign=0&content=" + encodeURIComponent(finalStatusText); var updateParams = { // content: finalStatusText, }; var thisObj = this; jQuery.ajax({ type: "POST", url: updateUrl, data: updateParams, dataType: "html", error: function() { if (!retryFlag) { displayMessage("[QQ] Failed to update. Try one more time."); thisObj.updateQQ(finalStatusText, cb, 'retry'); } else { displayMessage("[QQ] Failed to update the status: Not logged in?"); if (cb) cb(); } }, success: function(data, textStatus) { displayMessage("[QQ] Status updated: " + finalStatusText); if (cb) cb(); }, beforeSend: function(req) { req.withCredentials = true; req.setRequestHeader('Referer', 'http://www.taotao.com/v1/mydaoke/t.1/p.1'); }, }); }, }; CmdUtils.CreateCommand({ name: ['t', 'twitter', 'tweet'], icon: "http://519it.net/qq/twitter.ico", arguments: [ {role: 'status', nountype: noun_arb_text, label: 'query'} ], homepage: "http://bwskyer.com", description: "Posts to Twitter/Leihou/Zuosa/Digu/9911;QQ/163/Follow5/Sina/Dii/Kaixin.", help: "You need to log in before using this command to update status services.", preview: function(pblock, args) { var statusText = args.status.text; var result = multiServiceUpdater.parseActions(statusText); var statusLength = result.status.length; var usesUrlShortener = statusText.indexOf('#URL') != -1; if (usesUrlShortener) statusLength += TWEET_SHORT_URL_MAX_LENGTH - 4; var previewData = { status: result.status, chars: TWEET_MAXLEN - statusLength }; var previewTemplate = "Updates your Twitter/Leihou/Zuosa/Digu/9911/QQ/163/Follow5/Sina/Dii/Kaixin status to:
${status}

Characters remaining: ${chars}"; var truncateTemplate = "
The last ${truncate} characters will be truncated!"; var shortenInstructionText = "
To link to the current page, type #URL as part of your tweet."; var urlWillBeShortenedText = "
The text #URL will be replaced with an http://tr.im/ link to the current page."; var actionsTemplate = "
The status will be updated on:${services}."; var previewHTML = CmdUtils.renderTemplate(previewTemplate, previewData); if (usesUrlShortener) previewHTML += urlWillBeShortenedText; else previewHTML += shortenInstructionText; if (previewData.chars < 0) { var truncateData = { truncate: 0 - previewData.chars }; previewHTML += CmdUtils.renderTemplate(truncateTemplate, truncateData); } var servicesToBeUpdated = ''; for (var i = 0; i < result.actions.length; i++) { servicesToBeUpdated += ' ' + result.actions[i].substring(1); } previewHTML += CmdUtils.renderTemplate(actionsTemplate, {services: servicesToBeUpdated}); pblock.innerHTML = previewHTML; }, execute: function(args) { var statusText = args.status.text; if(statusText.length < 1) { displayMessage("Twitter requires a status to be entered"); return; } var usesUrlShortener = statusText.indexOf(' #URL') != -1; var thisObj = this; var postUpdate = function( shortURL ) { var finalStatusText = statusText.replace('#URL', shortURL); multiServiceUpdater.updateStatus(finalStatusText); } if (usesUrlShortener) { var urlToShorten = Application.activeWindow.activeTab.document.location.href; jQuery.get( URL_SHORTENER_API + encodeURIComponent(urlToShorten), null, postUpdate); } else { postUpdate(''); } }, });