一道小題

  1.  有一個 Array 如下
  2.  
  3.  $dict = ['a' , 'b' , 'c' , 'd' , 'e' ];
  4.  
  5.  目前有一個變數 $i 控制想輸出的 Array
  6.  
  7.  當 $i = a 時回傳 abcde
  8.  當 $i = b 時回傳 bcdea
  9.  當 $i = d 時回傳 deabc
  10.  
  11.  怎麼寫比較漂亮?
  12.  想知道是否就只能用迴圈跑?

# 想到的解法如下

## 方法一 (直覺.但很多計算)

1. 取出目前 $i 值的位置
2. 取兩種 array (1. 由這位置取到尾, 2.再取 0 到這值置)
3. 最後將這兩種合起來

  1.  <?php
  2.  $dict = ['a' , 'b' , 'c' , 'd' , 'e'];
  3.  
  4.  $position    = array_search('c', $dict);
  5.  $totalSize   = count($dict);
  6.  $findOut     = array_slice($dict, $position, $totalSize);
  7.  $findOutSize = count($findOut);
  8.  
  9.  if ($findOutSize < $totalSize) {
  10.      $appendSize = $totalSize - $findOutSize;
  11.      $appendDict = array_slice($dict, 0, $appendSize);
  12.  }else{
  13.      $appendDict = [];
  14.  }
  15.  
  16.  print_r(array_merge($findOut, $appendDict));

## 方法二 (用遞歸.不算直覺.但快很多)

  1.  <?php
  2.  function genResult(array $dict, $startChar) {
  3.      if ($dict[0] === $startChar) return $dict;
  4.  
  5.      array_push($dict, array_shift($dict));
  6.     
  7.      return genResult($dict, $startChar);
  8.  }
  9.  
  10.  print_r(genResult(['a' , 'b' , 'c' , 'd' , 'e'], 'c'));

Lumen 安裝使用 Elixir

小筆記.直接進入主題

# 進入專案

  1. cd /path/to/lumen/project

# 安裝 gulp 和 laravel elixir package

  1. npm install gulp --save-dev
  2. npm install laravel-elixir --save-dev

# 放置 gulpfile.js

  1. touch gulpfile.js

# 添加以下內容到 gulpfile.js

DownLoad: gulpfile.js
  1.  var elixir = require('laravel-elixir'),
  2.      clean  = require('gulp-clean');
  3.  
  4.  // 設置 詳細可以打開 elixir 的 Config.js 參看
  5.  // elixir.config.sourcemaps = true;
  6.  // elixir.config.publicDir  = "public";
  7.  // elixir.config.assetsDir  = "resources/assets/";
  8.  // elixir.config.bowerDir   = "vendor/bower_components";
  9.  
  10.  // 自定義簡單的 task
  11.  gulp.task('clean', function () {
  12.      return gulp.src([
  13.          'public/foo',
  14.          'public/bar'
  15.      ])
  16.      .pipe(clean({ force: true }));
  17.  });
  18.  
  19.  // 自定義複雜的 task
  20.  elixir.extend("copySomething", function() {
  21.      gulp.task('copySomething', function() {
  22.          return gulp.src('resources/foo/bar/**/*').pipe(gulp.dest('public/foo/bar'));
  23.      });
  24.  
  25.      // 註冊到監控事件裡面,每次改動時指定檔案時都會觸發這個 task
  26.      this.registerWatcher('copySomething', "resources/foo/bar/**/*");
  27.  
  28.      return this.queueTask('copySomething');
  29.  });
  30.  
  31.  elixir(function(mix) {
  32.      mix.styles('app.css').scripts('app.js');
  33.  });

通過 Gandi API 查詢域名

直接記錄測試用的代碼.

package.json

DownLoad: package.json
  1.  {
  2.    "dependencies": {
  3.      "xmlrpc": "^1.3.0"
  4.    }
  5.  }

index.js

DownLoad: index.js
  1.  var xmlrpc = require('xmlrpc');
  2.  var apikey = '____YOUR____API___KEY___';
  3.  var words  = ['cut', 'daily', 'dance', 'danger', 'dark', 'date', 'day', 'dead', 'deal', 'death', 'decide', 'decision', 'declare', 'deep', 'defense', 'degree', 'demand', 'department', 'depend', 'dependent', 'describe', 'desire', 'destroy', 'detail', 'determine', 'develop', 'die', 'difference', 'different', 'difficult', 'difficulty', 'dinner', 'direct', 'direction', 'director', 'discover', 'discuss', 'discussion', '___YOUR___WORDS___ETC___'];
  4.  
  5.  var api = xmlrpc.createSecureClient({
  6.      host: 'rpc.ote.gandi.net', // 'rpc.gandi.net' for production
  7.      port: 443,
  8.      path: '/xmlrpc/'
  9.  });
  10.  
  11.  api.methodCall('version.info', [apikey], function (error, value) {
  12.      console.dir(value);
  13.  });
  14.  
  15.  function run(domain) {
  16.      var callback = function(error, value) {
  17.          console.log(new Date().toLocaleString());
  18.  
  19.          if (value[domain] == 'pending') {
  20.              setTimeout(function() {
  21.                  api.methodCall('domain.available', [apikey, [domain]], callback);
  22.              }, 700);
  23.          }else if (value[domain] == 'error_invalid') {
  24.              console.dir("Err - " + domain);
  25.          }else{
  26.              console.dir(value)
  27.          }
  28.      }
  29.  
  30.      api.methodCall('domain.available', [apikey, [domain]], callback)
  31.  }
  32.  
  33.  // Make sure the word length bigger than 2
  34.  // words = words.filter(function(word) {
  35.  //     return word.length > 2;
  36.  // });
  37.  
  38.  words.some(function(word) {
  39.      run(word + ".xyz");
  40.  });

Golang 創解文件和追加內容

朋友的問題.雖然這玩意只玩過一次.
但還是為這問題再去玩了一下.順道筆記一下

  1.  package main
  2.  
  3.  import (
  4.      "os"
  5.      "io/ioutil"
  6.  )
  7.  
  8.  const (
  9.      FILENAME = "test.txt"
  10.  )
  11.  
  12.  func createFile() {
  13.      file, err := os.Create(FILENAME)
  14.  
  15.      if err != nil {
  16.          panic(err)
  17.      }
  18.  
  19.      defer file.Close()
  20.  }
  21.  
  22.  func appendContent() {
  23.      file, openErr := os.OpenFile(FILENAME, os.O_APPEND | os.O_WRONLY, 0666)
  24.  
  25.      if openErr != nil {
  26.          panic(openErr)
  27.      }
  28.  
  29.      defer file.Close()
  30.  
  31.      _, writeErr := file.WriteString("This is a test content 1\n")
  32.  
  33.      if writeErr != nil {
  34.          panic(writeErr)
  35.      }
  36.  }
  37.  
  38.  func exampleForIOUtilWriteFile() {
  39.      ioutil.WriteFile(FILENAME, []byte("This is a test content 2\n"), os.ModeAppend)
  40.  }
  41.  
  42.  func main() {
  43.  
  44.      _, err := os.Stat(FILENAME)
  45.  
  46.      if os.IsNotExist(err) {
  47.          createFile()
  48.      }
  49.  
  50.      appendContent()
  51.      // exampleForIOUtilWriteFile()
  52.  }

Python PIL 1.5 小記

安裝一個舊的程式.
在安裝套件時發現 PIL 出錯.
找大神問了一下.發現是 PIL 1.5 版本問題.
因為 PIL 引用了外部的源.所以下載不了.
解決方法有幾個記錄一下

執行

  1. pip install -r requirements.txt

得到

  1.  Downloading/unpacking PIL
  2.    Could not find any downloads that satisfy the requirement PIL
  3.    Some externally hosted files were ignored (use --allow-external PIL to allow).
  4.  Cleaning up...
  5.  No distributions at all found for PIL

解決 1

  1. pip install PIL --allow-external PIL --allow-unverified PIL

解決 2

  1. pip install Pillow

將對應的

  1.  import Image

換成

  1.  from PIL import Image

用 Exim4 來發送郵件

因為某些奇怪的原因.所以沒帶 sendmail 這東西.
再者不想加入這麼大型的玩意到目前的機械上.
所以直接裝上 Exim4 為機械發送郵件.
而別的東西還是留在 Mailgun 上.
筆記一下 (機械為 Debian 7 i386)

先確認移除 sendmail (如本身沒有可不用)

  1. invoke-rc.d sendmail stop
  2. apt-get -q -y remove --purge "sendmail*"
  3. apt-get clean

裝上 Exim4 (同時設為可以對外)

  1. which mail
  2. apt-get -q -y install "exim4"
  3. apt-get clean
  4. ls /etc/exim4/update-exim4.conf.conf
  5. sed -i "s/dc_eximconfig_configtype='local'/dc_eximconfig_configtype='internet'/" /etc/exim4/update-exim4.conf.conf
  6. cat /etc/exim4/update-exim4.conf.conf | grep dc_eximconfig_configtype
  7. invoke-rc.d exim4 restart

如果發送郵件後發現沒收到郵件.可以查看 log

  1. tail -n 10 /var/log/exim4/mainlog

在 Laravel 查詢中 setTablePrefix

目前遇到的情況是.有一個表.但需要在裡面存不同語系的資料.
如 en_us_message, zh_tw_message, zh_cn_message.
除了建立新的 ORM Model 外.好像就沒方法在 ORM 查詢時更改表名.
當然可以用 DB::table Query 來查詢.但寫法比較長.
最後只好找了一下和改了一下找回來的方法

1. 建立一個 Factory 來生成 Model 並在生成時設置他的對應表名
2. 在查詢時使用 ModelFactory::fromTable(ModelName, TableName) 解決

但問題是.這種生成會導致 create 和 all 這類方法失效.
失效指的是他不能夠使用指的 TableName.
原因是這些方法會自已生成 Model (new static) 而不用現有的 instance.

當然.除了這種方法還可以考慮用 laravel-translatable 這玩意

筆記一下

工廠類

  1.  <?php
  2.  class ModelFactory extends Eloquent {
  3.  
  4.      protected static $_table;
  5.  
  6.      public static function fromTable($model, $table, $attributes = Array()) {
  7.          $instance = null;
  8.  
  9.          if (class_exists($model) === true) {
  10.              $instance = new $model($attributes);
  11.              $instance->setTable($table);
  12.          } else {
  13.              $instance = new static($attributes);
  14.              $instance->setTable($table);
  15.          }
  16.  
  17.          return $instance;
  18.      }
  19.  
  20.      public function setTable($table) {
  21.          static::$_table = $table;
  22.      }
  23.  
  24.      public function getTable() {
  25.          return static::$_table;
  26.      }
  27.  
  28.  }

使用方法

  1.  <?php
  2.  Route::get('/', function() {
  3.      // Do not use create, all method (it will new object can not overwrite prefix)
  4.  
  5.      $langs = ['en_us', 'zh_tw', 'zh_cn'];
  6.  
  7.      foreach($langs as $lang) {
  8.          $table = $lang.'_message';
  9.  
  10.          ModelFactory::fromTable('message', $table)->fill([
  11.              'content' => 'content_'.$lang
  12.          ])->save();
  13.      }
  14.  
  15.      foreach($langs as $lang) {
  16.          $table = $lang.'_message';
  17.  
  18.          $messages = ModelFactory::fromTable('message', $table)->get();
  19.  
  20.          echo "<h3>".$lang."</h3>";
  21.          foreach($messages as $message) {
  22.              echo "<p>".$message->content."</p>";
  23.          }
  24.      }
  25.  
  26.  });

資料庫結構

  1.  <?php
  2.  
  3.  use Illuminate\Database\Schema\Blueprint;
  4.  use Illuminate\Database\Migrations\Migration;
  5.  
  6.  class CreateMessageTable extends Migration {
  7.  
  8.      /**
  9.       * Run the migrations.
  10.       *
  11.       * @return void
  12.       */
  13.      public function up()
  14.      {
  15.          Schema::create('en_us_message', function($table) {
  16.              $table->increments('id');
  17.              $table->string('content', 100);
  18.              $table->timestamps();
  19.          });
  20.  
  21.          Schema::create('zh_tw_message', function($table) {
  22.              $table->increments('id');
  23.              $table->string('content', 100);
  24.              $table->timestamps();
  25.          });
  26.  
  27.          Schema::create('zh_cn_message', function($table) {
  28.              $table->increments('id');
  29.              $table->string('content', 100);
  30.              $table->timestamps();
  31.          });
  32.      }
  33.  
  34.      /**
  35.       * Reverse the migrations.
  36.       *
  37.       * @return void
  38.       */
  39.      public function down()
  40.      {
  41.          Schema::dropIfExists('en_us_message');
  42.          Schema::dropIfExists('zh_tw_message');
  43.          Schema::dropIfExists('zh_cn_message');
  44.      }
  45.  
  46.  }

在推裡取得某個列表的最新推文

由於某種特別的取求.所以必需在用戶的 Twitter 帳戶裡面.
取得這個用戶中被指定的列表內容.而這內容則為最新推文
記錄一下用 Tweepy 實測的代碼

  1.  #!/usr/bin/python
  2.  # -*- coding: utf-8 -*-
  3.  
  4.  import tweepy
  5.  
  6.  class Taut(object):
  7.     
  8.      def __init__(self, consumer_key=None, consumer_secret=None, access_token_key=None, access_token_secret=None):
  9.          auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
  10.          auth.set_access_token(access_token_key, access_token_secret)
  11.         
  12.          self.api = tweepy.API(auth)
  13.         
  14.      def show_list(self):
  15.          r = self.api.lists_all()
  16.         
  17.          for item in r:
  18.              print("{0}, {1}, {2}".format(item.name, item.slug, item.id_str))
  19.  
  20.      def show_target_list(self, list_id, slug):
  21.          r = self.api.list_timeline(list_id=list_id, slug=slug)
  22.         
  23.          for item in r:                           
  24.              print "> ID        : {0}".format(item.id)
  25.              print "> Name      : {0}".format(item.user.name.encode("UTF-8"))
  26.              print "> ScreenName: {0}".format(item.user.screen_name.encode("UTF-8"))
  27.              print "> Text:\n{0}".format(item.text.encode("UTF-8"))
  28.             
  29.              if hasattr(item, 'extended_entities'):
  30.                  extended_entities = item.extended_entities
  31.                 
  32.                  if 'media' in extended_entities:
  33.                      print "> Media:"
  34.                      for media in extended_entities['media']:
  35.                          print "--- {0}".format(media['media_url'])
  36.                         
  37.              print "======"
  38.  
  39.      def single_entities(self, item):
  40.          entities = item.entities
  41.             
  42.          print entities
  43.         
  44.          if 'urls' in entities:
  45.              print "------urls"
  46.              print len(entities['urls'])
  47.             
  48.              for url in entities['urls']:
  49.                  print "- {0}".format(url['url'])
  50.         
  51.          if 'media' in entities:
  52.              print "------media"
  53.              print len(entities['media'])
  54.             
  55.              for media in entities['media']:
  56.                  print "- {0}".format(media['media_url'])
  57.         
  58.                  print "++++++++++++++++++++++++++"
  59.             
  60.  if __name__ == "__main__":
  61.      taut = Taut(
  62.          consumer_key="YOU_KEY",
  63.          consumer_secret="YOU_KEY",
  64.          access_token_key="YOU_KEY",
  65.          access_token_secret="YOU_KEY"
  66.      )
  67.     
  68.      taut.show_list()
  69.      taut.show_target_list(LIST_ID, SLUG)
  70.      taut.show_target_list(LIST_ID, SLUG)

Note for volley and action process button

筆記一下最主要部份

  1.  package im.chair.app.ui;
  2.  
  3.  import android.os.Bundle;
  4.  import android.util.Log;
  5.  import android.view.View;
  6.  import android.widget.EditText;
  7.  
  8.  import com.android.volley.Request;
  9.  import com.android.volley.RequestQueue;
  10.  import com.android.volley.Response;
  11.  import com.android.volley.VolleyError;
  12.  import com.android.volley.toolbox.JsonObjectRequest;
  13.  import com.android.volley.toolbox.Volley;
  14.  import com.dd.processbutton.iml.ActionProcessButton;
  15.  
  16.  import org.json.JSONException;
  17.  import org.json.JSONObject;
  18.  
  19.  import im.chair.app.R;
  20.  
  21.  public class UserProfileActivity extends BaseActivity {
  22.  
  23.      private static final String TAG  = "UserProfileActivity";
  24.  
  25.      EditText editTextAPIKey;
  26.      ActionProcessButton buttonFetch;
  27.      RequestQueue requestQueue;
  28.  
  29.      @Override
  30.      protected void onCreate(Bundle savedInstanceState) {
  31.          super.onCreate(savedInstanceState);
  32.  
  33.          this.getActionBar().hide();
  34.          this.getActionBar().setDisplayUseLogoEnabled(true);
  35.          this.getActionBar().setDisplayShowTitleEnabled(false);
  36.  
  37.          this.setContentView(R.layout.activity_profile);
  38.  
  39.          this.requestQueue = Volley.newRequestQueue(this);
  40.  
  41.          this.editTextAPIKey = (EditText) this.findViewById(R.id.editTextAPIKey);
  42.  
  43.          this.buttonFetch = (ActionProcessButton) this.findViewById(R.id.buttonFetch);
  44.          this.buttonFetch.setMode(ActionProcessButton.Mode.ENDLESS);
  45.          this.buttonFetch.setOnClickListener(new View.OnClickListener() {
  46.              @Override
  47.              public void onClick(View v) {
  48.                  buttonFetch.setEnabled(false);
  49.                  editTextAPIKey.setEnabled(false);
  50.                  editTextPassword.setEnabled(false);
  51.  
  52.                  // Start progress animation (Start at 0 will not show animation)
  53.                  Log.d(TAG, "---> Button set to progress");
  54.                  buttonFetch.setProgress(1);
  55.  
  56.                  // Start request
  57.                  Log.d(TAG, "---> Start connect api");
  58.                  try {
  59.                      JSONObject jsonObject = new JSONObject();
  60.                      jsonObject.put("api_key", editTextAPIKey.getText());
  61.  
  62.                      JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
  63.                          Request.Method.POST,
  64.                          "http://10.0.1.10:5000/api/user/1",
  65.                          jsonObject,
  66.                          new Response.Listener<JSONObject>() {
  67.                              @Override
  68.                              public void onResponse(JSONObject response) {
  69.                                  try {
  70.                                      Log.d(TAG, response.getString("username"));
  71.                                      buttonFetch.setProgress(100);
  72.                                  }catch(JSONException e) {
  73.                                      Log.d(TAG, "---> Response Listener");
  74.                                      Log.d(TAG, e.toString());
  75.                                  }
  76.                              }
  77.                          },
  78.                          new Response.ErrorListener() {
  79.                              @Override
  80.                              public void onErrorResponse(VolleyError error) {
  81.                                  Log.d(TAG, "---> Fetch Profile Error");
  82.                                  Log.d(TAG, error.toString());
  83.                                  buttonFetch.setProgress(0);
  84.                              }
  85.                          }
  86.                      );
  87.  
  88.                      requestQueue.add(jsonObjectRequest);
  89.                  }catch(JSONException e) {
  90.                      Log.d(TAG, "---> JSON Object");
  91.                      Log.d(TAG, e.toString());
  92.                  }
  93.              }
  94.          });
  95.      }
  96.  
  97.  }

Polipo 的小筆記

Install application

  1. sudo apt-get install polipo
  2. sudo apt-get install screen

Stop the polipo first

  1. service polipo stop

Start the polipo for testing with public ip and port

  1. polipo proxyAddress=119.180.188.18 proxyPort=8124

Make the polipo run in the screen command

  1. screen -dmS polipo-name polipo proxyAddress=119.180.188.18 proxyPort=8124

Check the screen list

  1. screen -ls

Enter to the target screen

  1. screen -r polipo-name

Exit from the screen

  1. ctrl+a ctrl+d

Change shadowsocks to HTTP in server side

  1. sslocal -c /path/to/shadowsocks.conf
  2. polipo socksParentProxy=127.0.0.1:1080 socksProxyType=socks5 proxyAddress=119.180.188.18 proxyPort=8124

Support the multiple ip address for outgoing

  1. # Clone the repo first
  2. git clone https://github.com/jech/polipo.git
  3. cd polipo/
  4.  
  5. # Path the repo
  6. wget https://github.com/nochkin/polipo/commit/853ed5420c992ff28932471c2132c17e31c308ec.patch
  7. patch -p0 < 853ed5420c992ff28932471c2132c17e31c308ec.patch
  8.  
  9. # If can not perfect path, follow the PR to modify file maunlly
  10. https://github.com/nochkin/polipo/commit/853ed5420c992ff28932471c2132c17e31c308ec
  11.  
  12. # Install the tools
  13. sudo apt-get install texinfo
  14. sudo apt-get install info
  15.  
  16. # Make script
  17. make all
  18.  
  19. # Install script without man file
  20. su -c "make install.binary"
  21.  
  22. # Test the polipo
  23. /usr/local/bin/polipo -v
  24.  
  25. # Try to start the proxy server with specified out going ip
  26. /usr/local/bin/polipo proxyAddress=119.180.188.18 proxyPort=8124 proxyOutgoingAddress=119.180.188.18
  27.  
  28. # Test the proxy server in local machine
  29. http_proxy=http://119.180.188.18:8124 curl http://ifconfig.co/

© 2015 不記程式

Theme by Anders NorenUp ↑

Fork me on GitHub