Wesley Kerfoot
3 years ago
7 changed files with 334 additions and 187 deletions
@ -1,105 +0,0 @@ |
|||
import httpClient, uri, json, os, strformat, sequtils, strutils, options, sugar, types |
|||
import tables, options, times |
|||
import auth |
|||
|
|||
from nimcrypto.sysrand import randomBytes |
|||
from xmltree import escape |
|||
|
|||
proc parseTwitterTS(ts : string) : DateTime = |
|||
ts.parse("ddd MMM dd hh:mm:ss YYYY") |
|||
|
|||
proc listTweets*(user : string) : JsonNode = |
|||
# Lists tweets from a given user |
|||
# XXX use Tweet type |
|||
let client = tweetClient(getBearerToken()) |
|||
let userIdReq = fmt"/2/users/by?usernames={user}" |
|||
var url = fmt"https://api.twitter.com{userIdReq}" |
|||
|
|||
let userId = client.request(url, httpMethod = HttpGet).body.parseJson{"data"}[0]{"id"}.getStr |
|||
|
|||
let tweetsReq = fmt"/2/users/{userId}/tweets" |
|||
url = fmt"https://api.twitter.com{tweetsReq}" |
|||
return client.request(url, httpMethod = HttpGet).body.parseJson |
|||
|
|||
proc getTweetConvo*(tweetID : string) : JsonNode = |
|||
# Gets the conversation info for a given tweet |
|||
let client = tweetClient(getBearerToken()) |
|||
let userIdReq = fmt"/2/tweets?ids={tweetID}&tweet.fields=conversation_id,author_id" |
|||
var url = fmt"https://api.twitter.com{userIdReq}" |
|||
|
|||
let tweetInfo = client.request(url, httpMethod = HttpGet).body.parseJson |
|||
|
|||
tweetInfo |
|||
|
|||
proc getTweet*(tweetID : string) : string = |
|||
# Grabs a single tweet |
|||
# XXX use Tweet type |
|||
let client = tweetClient(getBearerToken()) |
|||
let reqTarget = fmt"/1.1/statuses/show.json?id={tweetID}&tweet_mode=extended" |
|||
let url = fmt"https://api.twitter.com{reqTarget}" |
|||
|
|||
client.request(url, httpMethod = HttpGet).body |
|||
|
|||
proc getHome*(count: int) : string = |
|||
# Gets your home timeline |
|||
let client = tweetClient(getBearerToken()) |
|||
let reqTarget = fmt"/1.1/statuses/user_timeline.json?count={count}&trim_user=1&exclude_replies=1" |
|||
let url = fmt"https://api.twitter.com{reqTarget}" |
|||
|
|||
client.request(url, httpMethod = HttpGet).body |
|||
|
|||
iterator getThread*(tweetStart : string) : Tweet = |
|||
let client = tweetClient(getBearerToken()) |
|||
var reqTarget = fmt"/2/tweets/search/recent?query=conversation_id:{tweetStart}&tweet.fields=in_reply_to_user_id,author_id,created_at,conversation_id" |
|||
var url = fmt"https://api.twitter.com{reqTarget}" |
|||
|
|||
var currentPage : JsonNode |
|||
|
|||
currentPage = client.request(url, httpMethod = HttpGet).body.parseJson |
|||
|
|||
while true: |
|||
if currentPage{"meta", "result_count"}.getInt == 0: |
|||
break |
|||
for tweet in currentPage{"data"}: |
|||
yield Tweet( |
|||
id: tweet{"id"}.getStr, |
|||
in_reply: tweet{"in_reply_to_user_id"}.getStr, |
|||
author_id: tweet{"author_id"}.getStr, |
|||
text: tweet{"text"}.getStr, |
|||
created_at: tweet{"created_at"}.getStr, |
|||
conversation_id: tweet{"conversation_id"}.getStr |
|||
) |
|||
|
|||
let paginationToken = currentPage{"meta"}{"next_token"} |
|||
|
|||
if paginationToken == nil: |
|||
break |
|||
|
|||
reqTarget = fmt"/2/tweets/search/recent?query=conversation_id:{tweetStart}&tweet.fields=in_reply_to_user_id,author_id,created_at,conversation_id&next_token={paginationToken.getStr}" |
|||
url = fmt"https://api.twitter.com{reqTarget}" |
|||
currentPage = client.request(url, httpMethod = HttpGet).body.parseJson |
|||
|
|||
proc convertWords(tweet : Tweet) : string = |
|||
let words = tweet.text.split(" ") |
|||
var stripped : seq[string] |
|||
for chunk in words: |
|||
for word in chunk.splitLines: |
|||
if word.len > 3 and word[0..3] == "http": |
|||
let parsedUri = word.parseUri |
|||
let scheme = parsedUri.scheme |
|||
let hostname = parsedUri.hostname |
|||
let path = parsedUri.path |
|||
if (scheme.len > 0 and hostname.len > 0): |
|||
let url = xmltree.escape(fmt"{scheme}://{hostname}{path}") |
|||
stripped &= url |
|||
elif word.len > 0 and word[0] != '@': |
|||
stripped &= word |
|||
else: |
|||
continue |
|||
stripped.join(" ") |
|||
|
|||
proc renderThread*(tweetID : string) : Option[seq[string]] = |
|||
let thread = toSeq(getThread(tweetID)).map(convertWords).map(capitalizeAscii) |
|||
if thread.len == 0: |
|||
return none(seq[string]) |
|||
some(thread) |
@ -0,0 +1,129 @@ |
|||
import httpClient, uri, json, os, strformat, sequtils, strutils, options, sugar, types |
|||
import tables, options, times, twitter |
|||
import auth |
|||
|
|||
from nimcrypto.sysrand import randomBytes |
|||
from xmltree import escape |
|||
|
|||
proc parseTwitterTS(ts : string) : DateTime = |
|||
ts.parse("ddd MMM dd hh:mm:ss YYYY") |
|||
|
|||
proc listTweets*(user : string, token : AccessToken) : JsonNode = |
|||
# Lists tweets from a given user |
|||
# XXX use Tweet type |
|||
let client = tweetClient("Bearer " & token.access_token) |
|||
let userIdReq = fmt"/2/users/by?usernames={user}" |
|||
var url = fmt"https://api.twitter.com{userIdReq}" |
|||
|
|||
let userId = client.request(url, httpMethod = HttpGet).body.parseJson{"data"}[0]{"id"}.getStr |
|||
|
|||
let tweetsReq = fmt"/2/users/{userId}/tweets" |
|||
url = fmt"https://api.twitter.com{tweetsReq}" |
|||
return client.request(url, httpMethod = HttpGet).body.parseJson |
|||
|
|||
proc getTweetConvo*(tweetID : string, token : AccessToken) : JsonNode = |
|||
# Gets the conversation info for a given tweet |
|||
let client = tweetClient("Bearer " & token.access_token) |
|||
let userIdReq = fmt"/2/tweets?ids={tweetID}&tweet.fields=conversation_id,author_id" |
|||
var url = fmt"https://api.twitter.com{userIdReq}" |
|||
|
|||
let tweetInfo = client.request(url, httpMethod = HttpGet).body.parseJson |
|||
|
|||
tweetInfo |
|||
|
|||
proc getTweet*(tweetID : string, token : AccessToken) : string = |
|||
# Grabs a single tweet |
|||
# XXX use Tweet type |
|||
let client = tweetClient("Bearer " & token.access_token) |
|||
let reqTarget = fmt"/1.1/statuses/show.json?id={tweetID}&tweet_mode=extended" |
|||
let url = fmt"https://api.twitter.com{reqTarget}" |
|||
|
|||
client.request(url, httpMethod = HttpGet).body |
|||
|
|||
proc getHome*(count: int, token : AccessToken) : string = |
|||
# Gets your home timeline |
|||
let client = tweetClient("Bearer " & token.access_token) |
|||
let reqTarget = fmt"/1.1/statuses/user_timeline.json?count={count}&trim_user=1&exclude_replies=1" |
|||
let url = fmt"https://api.twitter.com{reqTarget}" |
|||
|
|||
client.request(url, httpMethod = HttpGet).body |
|||
|
|||
iterator getThread*(tweetStart : string, token : AccessToken) : Tweet = |
|||
|
|||
var reqParams : Params # params for the actual API request |
|||
|
|||
let consumerKey = "TWITTER_CONSUMER_KEY".getEnv |
|||
let secret = "TWITTER_CONSUMER_SECRET".getEnv |
|||
|
|||
var consumerToken = newConsumerToken(consumerKey, secret) |
|||
|
|||
var twitterAPI = newTwitterAPI(consumerToken, token.access_token, token.access_token_secret) |
|||
|
|||
reqParams["status"] = "testing123" |
|||
reqParams["include_entities"] = "true" |
|||
echo fmt"tweetStart = {tweetStart}" |
|||
|
|||
#var reqTarget = fmt"/2/tweets/search/recent?query=conversation_id:{tweetStart}&tweet.fields=in_reply_to_user_id,author_id,created_at,conversation_id" |
|||
var url = "https://api.twitter.com/1.1/statuses/update.json" |
|||
|
|||
var currentPage : string |
|||
|
|||
echo fmt"url = {url}" |
|||
|
|||
# Simply get. |
|||
var resp = twitterAPI.get("account/verify_credentials.json") |
|||
echo resp.status |
|||
|
|||
# Using proc corresponding twitter REST APIs. |
|||
resp = twitterAPI.statusesUpdate("testing 1 2 3") |
|||
echo parseJson(resp.body) |
|||
|
|||
#while true: |
|||
#if currentPage{"meta", "result_count"}.getInt == 0: |
|||
#break |
|||
#for tweet in currentPage{"data"}: |
|||
#yield Tweet( |
|||
#id: tweet{"id"}.getStr, |
|||
#in_reply: tweet{"in_reply_to_user_id"}.getStr, |
|||
#author_id: tweet{"author_id"}.getStr, |
|||
#text: tweet{"text"}.getStr, |
|||
#created_at: tweet{"created_at"}.getStr, |
|||
#conversation_id: tweet{"conversation_id"}.getStr |
|||
#) |
|||
|
|||
#let paginationToken = currentPage{"meta"}{"next_token"} |
|||
|
|||
#if paginationToken == nil: |
|||
#break |
|||
|
|||
#echo "Getting next page" |
|||
|
|||
#reqTarget = fmt"/2/tweets/search/recent?query=conversation_id:{tweetStart}&tweet.fields=in_reply_to_user_id,author_id,created_at,conversation_id&next_token={paginationToken.getStr}" |
|||
#url = fmt"https://api.twitter.com{reqTarget}" |
|||
#currentPage = client.request(url, httpMethod = HttpGet).body.parseJson |
|||
|
|||
proc convertWords(tweet : Tweet) : string = |
|||
let words = tweet.text.split(" ") |
|||
var stripped : seq[string] |
|||
for chunk in words: |
|||
for word in chunk.splitLines: |
|||
if word.len > 3 and word[0..3] == "http": |
|||
let parsedUri = word.parseUri |
|||
let scheme = parsedUri.scheme |
|||
let hostname = parsedUri.hostname |
|||
let path = parsedUri.path |
|||
if (scheme.len > 0 and hostname.len > 0): |
|||
let url = xmltree.escape(fmt"{scheme}://{hostname}{path}") |
|||
stripped &= url |
|||
elif word.len > 0 and word[0] != '@': |
|||
stripped &= word |
|||
else: |
|||
continue |
|||
stripped.join(" ") |
|||
|
|||
proc renderThread*(tweetID : string, token : AccessToken) : Option[seq[string]] = |
|||
let thread = toSeq(getThread(tweetID, token)).map(convertWords).map(capitalizeAscii) |
|||
echo $thread |
|||
if thread.len == 0: |
|||
return none(seq[string]) |
|||
some(thread) |
Loading…
Reference in new issue