play 2.3 で securesocial3.0 を使う
公式のドキュメントが古いので、使い方をまとめる。
手順
- securesocialを導入する
- 設定
1.導入
1.1 build.sbt の libraryDependencies に securesocialを追加
libraryDependencies ++= Seq( ... "securesocial" %% "securesocial" % "3.0-M3" , ... )
conf/routes に securesocial のルーティングを追加
... -> /auth securesocial.Routes ...
1.3 conf/play.plugins に mail plugin を追加
...
1500:com.typesafe.plugin.CommonsMailerPlugin
...
優先度は状況に応じて
oauthのみを使う場合は特に追加する必要はありません
2.設定
2.1 conf/securesocial.conf
securesocial.confの記述は以前のドキュメントと変わらないので、http://securesocial.ws/guide/configuration.htmlを参考に
用意したら conf/application.conf に include
include "securesocial.conf"
2.2 Global.scala に 自前のRuntimeEnvironmentを作成
サンプルプロジェクトを参考に(コピペ)
object Global extends play.api.GlobalSettings { /** * The runtime environment for this sample app. */ object MyRuntimeEnvironment extends RuntimeEnvironment.Default[DemoUser] { override implicit val executionContext = play.api.libs.concurrent.Execution.defaultContext override lazy val routes = new CustomRoutesService() override lazy val userService: InMemoryUserService = new InMemoryUserService() override lazy val eventListeners = List(new MyEventListener()) override lazy val providers = ListMap( include(new TwitterProvider(routes, cacheService, oauth1ClientFor(TwitterProvider.Twitter))) ) } /** * An implementation that checks if the controller expects a RuntimeEnvironment and * passes the instance to it if required. * * This can be replaced by any DI framework to inject it differently. * * @param controllerClass * @tparam A * @return */ override def getControllerInstance[A](controllerClass: Class[A]): A = { val instance = controllerClass.getConstructors.find { c => val params = c.getParameterTypes params.length == 1 && params(0) == classOf[RuntimeEnvironment[DemoUser]] }.map { _.asInstanceOf[Constructor[A]].newInstance(MyRuntimeEnvironment) } instance.getOrElse(super.getControllerInstance(controllerClass)) } }
既存のものをカスタマイズしたいときはRuntimeEnvironmentのフィールドをoverrideして書き換えてください。
e.g. viewを自前のものに置き換えたいなら、
override lazy val viewTemplates = new MyViewTemplates
securesocial/RuntimeEnvironment.scala at master · jaliss/securesocial · GitHub
実際にコードを見ながらのほうがわかりやすいかと思います。
自前のproviderを使いたいなら、
https://gist.github.com/krrrr38/d709ca3a8cf92e4294b7
を参考に
play.api.libs.json.JsonでオブジェクトをJson化
case class Human(lastName: String, firstName: String, age: Int)
こいつをJsonに変換しようと思います。
結果からいうとこういうソースになります。
case class Human(lastName: String, firstName: String, age: Int) { implicit val humanWrites = new Writes[Human] { def writes(human: Human) = Json.obj( "first" -> human.firstName, "last" -> human.lastName, "age" -> human.age ) } def toJson = Json.stringify(Json.toJson(this)) }
まずはコンバーターを用意する。
implicit val humanWrites = new Writes[Human] { def writes(human: Human) = Json.obj( "first" -> human.firstName, "last" -> human.lastName, "age" -> human.age ) }
そしたらJson.toJsonでJsValueに変換した後、Json.stringifyで文字列に変換
def toJson = Json.stringify(Json.toJson(this))
Json化したらPOSTするなりなんなりと。
val h = new Human("koya", "fukushi", 20) val url = "http://hogehoge.com" WS.url(url).withHeaders("Content-Type" -> "application/json").post(h.toJson)
詳細は
https://www.playframework.com/documentation/ja/2.3.x/ScalaJson
Scalaでpostリクエスト
actorでpostしたいと思って、ぐぐったらまっさきにこれが出てきた。
http://alvinalexander.com/scala/scala-http-post-json-gson-restful-client-example
apache httpclient を使っている。しかし、少し回りくどい気がする。。。
そこで、もう少し探していたら
ScalaWS
いい感じのがあるじゃないか。
WS.url(url).withHeaders("Content-Type" -> "application/json").post(Json.stringify(product.toJson))
pythonのrequestsでfc2動画にログインする
fc2動画のリンク切れチェックのために、ログインして動画のページをスクレイピングする必要があったので、めも
Python Requests and persistent sessions - Stack Overflow
ようはここを見ろと
import requests session def loginToFc2(): global session if session is None: session = requests.session() login_data = {'email': 'your@mail.com', 'pass': 'your_pass'} session.post('https://secure.id.fc2.com/index.php?mode=login&switch_language=en', login_data) return session if __name__ == '__main__': session = loginToFc2() request = session.get("http://video.fc2.com/en/content/20140516Q6YBtKyM") #print request.content #後は煮るなり焼くなり
こんな感じでrequests.getの代わりに、sessionを初期化して、session.getのように使えば良い
play のコンパイル時にエラー
[info] LESS compiling on 3 source(s) [error] [object Object] (/Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js#594) at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:594 (anonymous) [error] at /Users/koya/dev/nudele/nudele/project/target/less/sbt-less-1.0.0.jar:77 (anonymous) [error] at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:659 (anonymous) [error] at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/import-visitor.js:25 (anonymous) [error] at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:664 (anonymous) [error] at /Users/koya/dev/nudele/nudele/project/target/less/sbt-less-1.0.0.jar:58 (anonymous) [error] at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/node/fs.js:266 (anonymous) [error] at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/node/fs.js:107 (anonymous) [error] at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/main/trireme.js:805 (submitTick) [info] [trace] Stack trace suppressed: run last web-assets:less for the full output. [error] (web-assets:less) com.typesafe.sbt.jse.SbtJsTask$JsTaskFailure: [object Object] (/Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js#594) at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:594 (anonymous) [error] at /Users/koya/dev/nudele/nudele/project/target/less/sbt-less-1.0.0.jar:77 (anonymous) [error] at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:659 (anonymous) [error] at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/import-visitor.js:25 (anonymous) [error] at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:664 (anonymous) [error] at /Users/koya/dev/nudele/nudele/project/target/less/sbt-less-1.0.0.jar:58 (anonymous) [error] at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/node/fs.js:266 (anonymous) [error] at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/node/fs.js:107 (anonymous) [error] at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/main/trireme.js:805 (submitTick) [error] application - ! @6l9n8hn08 - Internal server error, for (GET) [/] -> play.PlayExceptions$UnexpectedException: Unexpected exception[JsTaskFailure: [object Object] (/Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js#594) at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:594 (anonymous) at /Users/koya/dev/nudele/nudele/project/target/less/sbt-less-1.0.0.jar:77 (anonymous) at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:659 (anonymous) at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/import-visitor.js:25 (anonymous) at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:664 (anonymous) at /Users/koya/dev/nudele/nudele/project/target/less/sbt-less-1.0.0.jar:58 (anonymous) at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/node/fs.js:266 (anonymous) at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/node/fs.js:107 (anonymous) at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/main/trireme.js:805 (submitTick) ] at play.PlayReloader$$anon$1$$anonfun$play$PlayReloader$$anon$$taskFailureHandler$1.apply(PlayReloader.scala:237) ~[na:na] at play.PlayReloader$$anon$1$$anonfun$play$PlayReloader$$anon$$taskFailureHandler$1.apply(PlayReloader.scala:230) ~[na:na] at scala.Option.map(Option.scala:145) ~[scala-library-2.11.5.jar:na] at play.PlayReloader$$anon$1.play$PlayReloader$$anon$$taskFailureHandler(PlayReloader.scala:230) ~[na:na] at play.PlayReloader$$anon$1$$anonfun$reload$2.apply(PlayReloader.scala:90) ~[na:na] Caused by: com.typesafe.sbt.jse.SbtJsTask$JsTaskFailure: [object Object] (/Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js#594) at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:594 (anonymous) at /Users/koya/dev/nudele/nudele/project/target/less/sbt-less-1.0.0.jar:77 (anonymous) at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:659 (anonymous) at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/import-visitor.js:25 (anonymous) at /Users/koya/dev/nudele/nudele/project/target/node-modules/webjars/less/lib/less/parser.js:664 (anonymous) at /Users/koya/dev/nudele/nudele/project/target/less/sbt-less-1.0.0.jar:58 (anonymous) at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/node/fs.js:266 (anonymous) at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/node/fs.js:107 (anonymous) at /Users/Apigee/src/noderunner/node10/node10src/src/main/javascript/io/apigee/trireme/node10/main/trireme.js:805 (submitTick) at com.typesafe.sbt.jse.SbtJsTask$$anonfun$com$typesafe$sbt$jse$SbtJsTask$$executeJsOnEngine$1.apply(SbtJsTask.scala:195) ~[na:na] at com.typesafe.sbt.jse.SbtJsTask$$anonfun$com$typesafe$sbt$jse$SbtJsTask$$executeJsOnEngine$1.apply(SbtJsTask.scala:167) ~[na:na] at scala.util.Success$$anonfun$map$1.apply(Try.scala:206) ~[scala-library-2.11.5.jar:na] at scala.util.Try$.apply(Try.scala:161) ~[scala-library-2.11.5.jar:na] at scala.util.Success.map(Try.scala:206) ~[scala-library-2.11.5.jar:na]
上のようなエラーが出た
JsTaskFailure while less compilation · Issue #2662 · playframework/playframework · GitHub
参考にしたら治った。
Beautiful soup 同じ階層の要素を列挙
現在の階層からルートまで検索したい時があったので
while elm is not None: for next in elm.next_siblings: print next.name for prev in elm.previous_siblings: print prev.name elm = elm.parent if elm is not None: print elm.name
1.後の要素をすべて列挙
2.前の要素をすべて列挙
3.一つ上の階層に移動
4.1に戻る