Forráskód Böngészése

Implement user_id to screen_name router

jackyzy823 5 éve
szülő
commit
52af6b2746
5 módosított fájl, 47 hozzáadás és 2 törlés
  1. 6 0
      src/api.nim
  2. 12 0
      src/parser.nim
  3. 10 0
      src/redis_cache.nim
  4. 14 0
      src/routes/timeline.nim
  5. 5 2
      src/routes/unsupported.nim

+ 6 - 0
src/api.nim

@@ -40,6 +40,12 @@ proc getProfile*(username: string): Future[Profile] {.async.} =
     url = userShow ? ps
   result = parseUserShow(await fetch(url, oldApi=true), username)
 
+proc getProfileById*(userId: string): Future[Profile] {.async.} =
+  let
+    ps = genParams({"user_id": userId})
+    url = userShow ? ps
+  result = parseUserShowId(await fetch(url, oldApi=true), userId)
+
 proc getTimeline*(id: string; after=""; replies=false): Future[Timeline] {.async.} =
   let
     ps = genParams({"userId": id, "include_tweet_replies": $replies}, after)

+ 12 - 0
src/parser.nim

@@ -38,6 +38,18 @@ proc parseUserShow*(js: JsonNode; username: string): Profile =
 
   result = parseProfile(js)
 
+proc parseUserShowId*(js: JsonNode; userId: string): Profile =
+  if js.isNull:
+    return Profile(id: userId)
+
+  with error, js{"errors"}:
+    result = Profile(id: userId)
+    if error.getError == suspended:
+      result.suspended = true
+    return
+
+  result = parseProfile(js)
+
 proc parseGraphProfile*(js: JsonNode; username: string): Profile =
   if js.isNull: return
   with error, js{"errors"}:

+ 10 - 0
src/redis_cache.nim

@@ -78,6 +78,7 @@ proc cache*(data: Profile) {.async.} =
   pool.withAcquire(r):
     r.startPipelining()
     discard await r.setex(name.profileKey, baseCacheTime, compress(toFlatty(data)))
+    discard await r.setex("i:" & data.id , baseCacheTime, data.username)
     discard await r.hset(name.pidKey, name, data.id)
     discard await r.flushPipeline()
 
@@ -110,6 +111,15 @@ proc getCachedProfile*(username: string; fetch=true): Future[Profile] {.async.}
   elif fetch:
     result = await getProfile(username)
 
+proc getCachedProfileScreenName*(userId: string): Future[string] {.async.} =
+  let username = await get("i:" & userId)
+  if username != redisNil:
+      result = username
+  else:
+    let profile = await getProfileById(userId)
+    result = profile.username
+    await cache(profile)
+
 proc getCachedPhotoRail*(name: string): Future[PhotoRail] {.async.} =
   if name.len == 0: return
   let rail = await get("pr:" & toLower(name))

+ 14 - 0
src/routes/timeline.nim

@@ -105,8 +105,22 @@ template respTimeline*(timeline: typed) =
     resp Http404, showError("User \"" & @"name" & "\" not found", cfg)
   resp t
 
+template respUserId*() =
+  cond @"user_id".len > 0
+  let username = await getCachedProfileScreenName(@"user_id")
+  if username.len > 0:
+    redirect("/" & username)
+  else:
+    resp Http404, showError("User not found", cfg)
+
 proc createTimelineRouter*(cfg: Config) =
   router timeline:
+    get "/i/user/@user_id":
+      respUserId()
+
+    get "/intent/user":
+      respUserId()
+
     get "/@name/?@tab?/?":
       cond '.' notin @"name"
       cond @"name" notin ["pic", "gif", "video"]

+ 5 - 2
src/routes/unsupported.nim

@@ -11,10 +11,13 @@ proc createUnsupportedRouter*(cfg: Config) =
       resp renderMain(renderFeature(), request, cfg, themePrefs())
 
     get "/about/feature": feature()
-    get "/intent/?@i?": feature()
     get "/login/?@i?": feature()
     get "/@name/lists/?": feature()
 
+    get "/intent/?@i?": 
+      cond @"i" notin ["user"]
+      feature()
+
     get "/i/@i?/?@j?":
-      cond @"i" notin ["status", "lists"]
+      cond @"i" notin ["status", "lists" , "user"]
       feature()