diff --git a/templates/user.html b/templates/user.html
new file mode 100644
index 0000000..cf89445
--- /dev/null
+++ b/templates/user.html
@@ -0,0 +1,19 @@
+{% extends 'base.html' %}
+{% block head %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% endblock %} {% block body %} Redirecting you to the tweet in a moment. Or click here. {% endblock %}
\ No newline at end of file
diff --git a/test_api.py b/test_api.py
index c0f24cf..58e752a 100644
--- a/test_api.py
+++ b/test_api.py
@@ -35,4 +35,10 @@ def test_api_include_rtf_nomedia():
resp = client.get(testMediaTweet.replace("https://twitter.com","https://api.vxtwitter.com")+"?include_rtf=ifnomedia",headers={"User-Agent":"test"})
jData = resp.get_json()
assert resp.status_code==200
- assert not any(".rtf" in i for i in jData["mediaURLs"])
\ No newline at end of file
+ assert not any(".rtf" in i for i in jData["mediaURLs"])
+
+def test_api_user():
+ resp = client.get(testUser.replace("https://twitter.com","https://api.vxtwitter.com")+"?include_rtf=true",headers={"User-Agent":"test"})
+ jData = resp.get_json()
+ assert resp.status_code==200
+ assert jData["screen_name"]=="jack"
\ No newline at end of file
diff --git a/test_vx_embeds.py b/test_vx_embeds.py
index d23f744..67fa44d 100644
--- a/test_vx_embeds.py
+++ b/test_vx_embeds.py
@@ -40,6 +40,11 @@ def test_embed_FromScratch():
client.get(testMediaTweet.replace("https://twitter.com",""),headers={"User-Agent":"test"})
client.get(testMultiMediaTweet.replace("https://twitter.com",""),headers={"User-Agent":"test"})
+def test_embed_User():
+ cache.clearCache()
+ resp = client.get(testUser.replace("https://twitter.com",""),headers={"User-Agent":"test"})
+ assert resp.status_code==200
+
def test_embed_FromCache():
cache.clearCache()
twitfix.getTweetData(testTextTweet)
diff --git a/twitfix.py b/twitfix.py
index 8bc082a..ca46813 100644
--- a/twitfix.py
+++ b/twitfix.py
@@ -16,7 +16,7 @@ import twExtract as twExtract
from cache import addVnfToLinkCache,getVnfFromLinkCache
import vxlogging as log
from utils import getTweetIdFromUrl, pathregex
-from vxApi import getApiResponse
+from vxApi import getApiResponse, getApiUserResponse
from urllib.parse import urlparse
from PyRTF.Elements import Document
from PyRTF.document.section import Section
@@ -138,6 +138,17 @@ def renderArticleTweetEmbed(tweetData,appnameSuffix=""):
color=config['config']['color']
)
+def renderUserEmbed(userData,appnameSuffix=""):
+ return render_template("user.html",
+ user=userData,
+ host=config['config']['url'],
+ desc=userData["description"],
+ urlEncodedDesc=urllib.parse.quote(userData["description"]),
+ link=f'https://twitter.com/{userData["screen_name"]}',
+ appname=config['config']['appname'],
+ color=config['config']['color']
+ )
+
@app.route('/robots.txt')
def robots():
return "User-agent: *\nDisallow: /"
@@ -181,6 +192,11 @@ def getTweetData(twitter_url,include_txt="false",include_rtf="false"):
addVnfToLinkCache(twitter_url,tweetData)
return tweetData
+def getUserData(twitter_url):
+ rawUserData = twExtract.extractUser(twitter_url,workaroundTokens=config['config']['workaroundTokens'].split(','))
+ userData = getApiUserResponse(rawUserData)
+ return userData
+
def determineEmbedTweet(tweetData):
# Determine which tweet, i.e main or QRT, to embed the media from.
# if there is no QRT, return the main tweet => default behavior
@@ -196,6 +212,7 @@ def determineEmbedTweet(tweetData):
@app.route('/') # Default endpoint used by everything
def twitfix(sub_path):
+ isApiRequest=request.url.startswith("https://api.vx") or request.url.startswith("http://api.vx")
if sub_path in staticFiles:
if 'path' not in staticFiles[sub_path] or staticFiles[sub_path]["path"] == None:
staticFiles[sub_path]["path"] = sub_path
@@ -204,9 +221,26 @@ def twitfix(sub_path):
sub_path = "i/" + sub_path
match = pathregex.search(sub_path)
if match is None:
+ # test for .com/username
+ if sub_path.count("/") == 0:
+ username=sub_path
+ extra=None
+ else:
+ # get first subpath
+ username=sub_path.split("/")[0]
+ extra = sub_path.split("/")[1]
+ if extra in [None,"with_replies","media","likes","highlights","superfollows","media"] and username != "" and username != None:
+ userData = getUserData(f"https://twitter.com/{username}")
+ if isApiRequest:
+ if userData is None:
+ abort(404)
+ return userData
+ else:
+ if userData is None:
+ return message(msgs.failedToScan)
+ return renderUserEmbed(userData)
abort(404)
twitter_url = f'https://twitter.com/i/status/{getTweetIdFromUrl(sub_path)}'
- isApiRequest=request.url.startswith("https://api.vx") or request.url.startswith("http://api.vx")
include_txt="false"
include_rtf="false"
diff --git a/vxApi.py b/vxApi.py
index 726dec2..b183ffc 100644
--- a/vxApi.py
+++ b/vxApi.py
@@ -3,6 +3,21 @@ from datetime import datetime
from configHandler import config
from utils import stripEndTCO
+def getApiUserResponse(user):
+ return {
+ "id": user["id"],
+ "screen_name": user["screen_name"],
+ "name": user["name"],
+ "profile_image_url": user["profile_image_url_https"],
+ "description": user["description"],
+ "location": user["location"],
+ "followers_count": user["followers_count"],
+ "following_count": user["friends_count"],
+ "tweet_count": user["statuses_count"],
+ "created_at": user["created_at"],
+ "protected": user["protected"],
+ }
+
def getApiResponse(tweet,include_txt=False,include_rtf=False):
tweetL = tweet["legacy"]
if "user_result" in tweet["core"]: