動かざることバグの如し

近づきたいよ 君の理想に

Jqueryを使わずにリンク先のURLを一括置き換え

GTMでJQuery使おうとしたら$なんてねーよっtw怒られた そりゃそーか

コード

var links = document.querySelectorAll('a');
Array.prototype.forEach.call(links, function (elm, i) {
    elm.href = "http://stackoverflow.com";
});

動作サンプル

そんなに難しくなかったは けどArray.prototype.forEach.callとかいう気持ち悪い書き方いい加減なんとかなって欲しい(他力本願

kotlin-Androidでテキスト入力ダイアログを表示する

環境

  • Kotlin 1.2
  • AndroidStudio 3.0

コード

抜粋にて表示ID=mybtnのボタンをクリックしたときにダイアログが出て、OK押すと入力した文字列でトースト表示

val mybtn = findViewById<Button>(R.id.mybtn)
mybtn.setOnClickListener {
    val myedit = EditText(this)
    val dialog = AlertDialog.Builder(this)
    dialog.setTitle("文字を入力してください")
    dialog.setView(myedit)
    dialog.setPositiveButton("OK", DialogInterface.OnClickListener {_, _ ->
        // OKボタン押したときの処理
        val userText = myedit.getText().toString()
        Toast.makeText(this, "$userText と入力しました", Toast.LENGTH_SHORT).show()
    })
    dialog.setNegativeButton("キャンセル", null)
    dialog.show()
}

kotlin-AndroidでHTTPで取得したデータを表示する

環境

やりたいこと

URL指定したらHTTPリクエストしてデータを取得、表示まで

基礎を学ぶ用なので必要最低限のコードのみ

ライブラリの追加

自分でゴリゴリHttpURLConnection書くのはツラみがあるのでokhttpというライブラリを使う。

元々JavaのライブラリだがKotlinにも対応しているので問題ない。古いQiitaの記事とかだと未対応だから~って書いてあるが。

build.gradleのdependencies項目に以下を追記 これだけ

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
(略)
    compile 'com.squareup.okhttp3:okhttp:3.10.0'
}

コード

先にMainActivityにid=mytextのテキストビューを追加しておく

外部からデータを取得するメソッド ふつうはJSONとかだが、サンプルとしてここではGoogleのサイトを取得している

class MainActivity : AppCompatActivity() {
(略)
}

fun getHtml(): String {
    val client = OkHttpClient()
    val req = Request.Builder().url("http://google.com").get().build()
    val resp = client.newCall(req).execute()
    return resp.body()!!.string()
}

次にパーミッション。AndroidManifest.xml<uses-permission android:name="android.permission.INTERNET" />を追加

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.user.fetchsample">

    <application>
        (略)
    </application>
    <uses-permission android:name="android.permission.INTERNET" />

</manifest>

でメインの処理を書く。が、以下は動きそうで動かない ネットワーク通信はメインスレッドで行っていけなく、非同期通信しなければならない。(android.os.NetworkOnMainThreadExceptionが発生する)

// NOT WORK
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val tview = findViewById<TextView>(R.id.mytext)
        val result = getHtml()
        tview.setText(result)

仕方ないのでAsyncTaskを使う。AsyncTaskクラスを継承したMyAsyncTaskをMainActivityクラス内に記述。doInBackground()は非同期で行いたい処理の内容、onPostExecute()はdoInBackground()終了後にメインスレッドで実行される処理の内容である

    inner class MyAsyncTask: AsyncTask<Void, Void, String>() {

        override fun doInBackground(vararg p0: Void?): String? {
            return getHtml()
        }

        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            val tview = findViewById<TextView>(R.id.mytext)
            tview.setText(result)

        }
    }

で以下で非同期処理が実行される

MyAsyncTask().execute()

ソース全体は以下

package com.example.user.fetchsample

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import okhttp3.OkHttpClient
import okhttp3.Request

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        MyAsyncTask().execute()
    }

    inner class MyAsyncTask: AsyncTask<Void, Void, String>() {

        override fun doInBackground(vararg p0: Void?): String? {
            return getHtml()
        }

        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            val tview = findViewById<TextView>(R.id.mytext)
            tview.setText(result)

        }
    }

}

fun getHtml(): String {
    val client = OkHttpClient()
    val req = Request.Builder().url("http://google.com").get().build()
    val resp = client.newCall(req).execute()
    return resp.body()!!.string()
}

サンプルとはいえgetHtml()がグローバルなところにいるのはいかがなものかと思いつつ、今日は眠いのでここまで

参考リンク

はてなブログの読者数を取得する隠しAPI

http://blog.hatena.ne.jp/api/init?blog=取得したいブログのTOPURLはてなブログの読者数を取得できる。

  • 一部オプションは必要(下記参照
  • 認証不要
  • 独自ドメインのブログでも可

認証不要はデカい。結構使えそう

curl -H "X-Requested-With: XMLHttpRequest" "http://blog.hatena.ne.jp/api/init?blog=http://thr3a.hatenablog.com/" | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   529    0   529    0     0   5169      0 --:--:-- --:--:-- --:--:--  5186
{
  "blog_name": "動かざることバグの如し",
  "should_show_invitation_pc_link": true,
  "subscribe": false,
  "private": {},
  "blog": "http://thr3a.hatenablog.com/",
  "cookie_received": false,
  "is_public": true,
  "can_open_editor": false,
  "subscribe_url": "http://blog.hatena.ne.jp/thr3a/thr3a.hatenablog.com/subscribe",
  "quote": {
    "should_navigate_to_login": true,
    "star_addable": false,
    "stockable": true,
    "supported": false
  },
  "editable": false,
  "subscribes": "29",
  "commentable": false,
  "blog_url": "http://thr3a.hatenablog.com/"
}

てか早くはてなブログID一覧のAPI公開してくれ(

参考URL

Imagemagickで画像の上下左右に余白を追加する

言わずと知れた最強画像処理コマンドImagemagickのネタ

やりたいこと

  • 画像の上下左右に白の余白を追加したい
  • 最終的には画像の解像度は変更せずに余白を追加したい(つまりオリジナルの部分は小さくなる

失敗例

imagemagick 余白」で検索すると余白追加には-spliceというオプションが有効らしい。早速使ってみる。

元画像(300x300px)

f:id:thr3a:20180325161203p:plain

convert icon.png -mattecolor "#fff" -splice 25x25 icon_padding.png

結果

f:id:thr3a:20180325161207p:plain

え、あそういう?どうも上下左右には一回でできないっぽい。使えない子だな

成功例

-frameオプションを使うと一発で余白追加できる。もともとはその名の通りフレーム追加用のオプションだが#fff指定すれば事実上の余白になるって戦法

convert icon.png -mattecolor "#fff" -frame 50x50 icon_padding.png

f:id:thr3a:20180325161204p:plain

画像の解像度そのものは変えたくないって場合は元画像の解像度で-resizeすればよい。

convert icon.png -mattecolor "#fff" -frame 50x50 -resize 300x300 icon_padding_resize.png

f:id:thr3a:20180325161210p:plain

やったね