Skip to content

Commit 496fb57

Browse files
committed
#21 Add LocalStore and can autologin padplus
1 parent 592a1c6 commit 496fb57

File tree

7 files changed

+146
-8
lines changed

7 files changed

+146
-8
lines changed

wechaty-puppet-padplus/pom.xml

+13-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,19 @@
4646
<artifactId>javase</artifactId>
4747
<version>3.4.0</version>
4848
</dependency>
49-
49+
<dependency>
50+
<groupId>org.fusesource.leveldbjni</groupId>
51+
<artifactId>leveldbjni-all</artifactId>
52+
<version>1.8</version>
53+
</dependency>
54+
<dependency>
55+
<groupId>org.junit.jupiter</groupId>
56+
<artifactId>junit-jupiter-engine</artifactId>
57+
</dependency>
58+
<dependency>
59+
<groupId>org.junit.jupiter</groupId>
60+
<artifactId>junit-jupiter-params</artifactId>
61+
</dependency>
5062
</dependencies>
5163
<build>
5264
<plugins>

wechaty-puppet-padplus/src/main/scala/wechaty/padplus/PuppetPadplus.scala

+18-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package wechaty.padplus
22

33
import com.typesafe.scalalogging.LazyLogging
44
import wechaty.padplus.grpc.PadPlusServerOuterClass.ApiType
5-
import wechaty.padplus.support.{ContactRawSupport, GrpcEventSupport, GrpcSupport}
5+
import wechaty.padplus.support.{ContactRawSupport, GrpcEventSupport, GrpcSupport, LocalStoreSupport}
66
import wechaty.puppet.schemas.Image.ImageType.Type
77
import wechaty.puppet.schemas.Puppet.PuppetOptions
88
import wechaty.puppet.schemas._
@@ -14,22 +14,36 @@ import wechaty.puppet.{Puppet, ResourceBox}
1414
* @author <a href="mailto:[email protected]">Jun Tsai</a>
1515
* @since 2020-06-21
1616
*/
17-
class PuppetPadplus(val option:PuppetOptions)
17+
class PuppetPadplus(val option:PuppetOptions,val storePath:String="/tmp/padplus")
1818
extends Puppet
1919
with ContactRawSupport
2020
with ContactSupport
2121
with GrpcSupport
2222
with GrpcEventSupport
23+
with LocalStoreSupport
2324
with LazyLogging {
25+
private var selfUni:Option[String] = None
2426
def start(): Unit ={
2527
startGrpc(option.endPoint.get)
26-
request(ApiType.GET_QRCODE)
28+
//waiting stream start....
29+
logger.info("waiting stream start....")
30+
awaitStreamStart()
31+
startLocalStore()
32+
getUin match{
33+
case Some(str) =>
34+
selfUni = Some(str)
35+
logger.debug("found uin in local store:{}",selfUni)
36+
request(ApiType.INIT)
37+
case _ =>
38+
request(ApiType.GET_QRCODE)
39+
}
2740
}
2841
def stop(): Unit = {
2942
stopGrpc()
43+
stopLocalStore()
3044
}
3145

32-
override def selfIdOpt(): Option[String] = None
46+
override def selfIdOpt(): Option[String] = selfUni
3347

3448
override def roomAdd(roomId: String, contactId: String): Unit = ???
3549

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package wechaty.padplus.internal
2+
3+
import java.io.File
4+
5+
import com.google.protobuf.ByteString
6+
import org.fusesource.leveldbjni.JniDBFactory._
7+
import org.iq80.leveldb.{DB, Options}
8+
9+
10+
/**
11+
*
12+
* @author <a href="mailto:[email protected]">Jun Tsai</a>
13+
* @since 2020-06-22
14+
*/
15+
class LocalStore(storePath:String) {
16+
private var dbOpt :Option[DB] = None
17+
def start(): Unit ={
18+
val options = new Options()
19+
options.createIfMissing(true)
20+
val db= factory.open(new File(storePath), options)
21+
dbOpt = Some(db)
22+
}
23+
def put(key: ByteString, value: ByteString): Unit = {
24+
db.put(key.toByteArray,value.toByteArray)
25+
}
26+
def put(key: String, value: String): Unit = {
27+
put(ByteString.copyFromUtf8(key),ByteString.copyFromUtf8(value))
28+
}
29+
def get(key:String): Option[ByteString]={
30+
get(ByteString.copyFromUtf8(key))
31+
}
32+
def get(key:ByteString): Option[ByteString]={
33+
val value = db.get(key.toByteArray)
34+
if(value != null) Some(ByteString.copyFrom(value))
35+
else None
36+
}
37+
def delete(key:ByteString): Unit ={
38+
db.delete(key.toByteArray)
39+
}
40+
private def db={
41+
dbOpt match{
42+
case Some(d) => d
43+
case _=> throw new IllegalStateException("db is null,database not init?")
44+
}
45+
}
46+
def close(): Unit ={
47+
db.close()
48+
}
49+
}

wechaty-puppet-padplus/src/main/scala/wechaty/padplus/support/GrpcEventSupport.scala

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package wechaty.padplus.support
22

33
import java.io.{File, FileOutputStream}
44
import java.util
5+
import java.util.concurrent.{CountDownLatch, TimeUnit}
56

67
import com.google.zxing.client.j2se.BufferedImageLuminanceSource
78
import com.google.zxing.common.HybridBinarizer
@@ -23,11 +24,15 @@ import wechaty.puppet.{Puppet, ResourceBox}
2324
* @since 2020-06-21
2425
*/
2526
trait GrpcEventSupport extends StreamObserver[StreamResponse]{
26-
self: GrpcSupport with Puppet with LazyLogging=>
27+
self: GrpcSupport with LocalStoreSupport with Puppet with LazyLogging=>
2728

29+
private val countDownLatch = new CountDownLatch(1)
2830

31+
32+
protected def awaitStreamStart()=countDownLatch.await(10,TimeUnit.SECONDS)
2933
override def onNext(response: StreamResponse): Unit = {
3034
logger.debug("stream response:{}",response)
35+
countDownLatch.countDown()
3136

3237
val traceId = response.getTraceId
3338
if(!isBlank(traceId)){
@@ -62,7 +67,7 @@ trait GrpcEventSupport extends StreamObserver[StreamResponse]{
6267
logger.debug("Scan QR Code to login: %s\nhttps://api.qrserver.com/v1/create-qr-code/?data=%s\n".format(payload.status, payload.qrcode))
6368
emit(PuppetEventName.SCAN,payload)
6469
case _ =>
65-
// val uin = response.getUin()
70+
saveUin(response.getUinBytes)
6671
// val user = objectMapper.readTree(response.getData())
6772
// val userName = user.get("userName").asText()
6873

wechaty-puppet-padplus/src/main/scala/wechaty/padplus/support/GrpcSupport.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ trait GrpcSupport {
132132
request.setRequestId(requestId)
133133
val traceId= UUID.randomUUID().toString
134134
request.setTraceId(traceId)
135-
grpcClient.request(request.build())
135+
val response = grpcClient.request(request.build())
136+
logger.debug("request->response:{}",response)
137+
response
136138
}
137139
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package wechaty.padplus.support
2+
3+
import com.google.protobuf.ByteString
4+
import wechaty.padplus.PuppetPadplus
5+
import wechaty.padplus.internal.LocalStore
6+
7+
/**
8+
*
9+
* @author <a href="mailto:[email protected]">Jun Tsai</a>
10+
* @since 2020-06-22
11+
*/
12+
trait LocalStoreSupport {
13+
self:PuppetPadplus=>
14+
protected var store:LocalStore = _
15+
private val uinKey = ByteString.copyFromUtf8("uin")
16+
protected def saveUin(uin:ByteString): Unit ={
17+
if(!uin.isEmpty){
18+
store.put(uinKey,uin)
19+
}
20+
}
21+
protected def getUin: Option[String]={
22+
store.get(uinKey).map(_.toStringUtf8)
23+
}
24+
protected def startLocalStore(): Unit ={
25+
store = new LocalStore(storePath)
26+
store.start()
27+
}
28+
protected def stopLocalStore(): Unit ={
29+
if(store != null)
30+
store.close()
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2014,2015,2016 the original author or authors. All rights reserved.
2+
// site: http://www.ganshane.com
3+
package wechaty.padplus.internal
4+
5+
import org.junit.jupiter.api.{Assertions, Test}
6+
7+
8+
/**
9+
* Created by jcai on 14-8-17.
10+
*/
11+
class LocalStoreTest {
12+
@Test
13+
def test_version() {
14+
val store = new LocalStore("/tmp/test.local")
15+
store.start()
16+
for (v <- 0 until 100) {
17+
store.put("asdf", "fdsa")
18+
store.put("sdf", "fdsa")
19+
store.put("df", "fdsa")
20+
}
21+
Assertions.assertEquals("fdsa", store.get("asdf").get.toStringUtf8)
22+
store.close()
23+
}
24+
}

0 commit comments

Comments
 (0)