小子 发布的文章

[Laravel4] Eloquent with的错觉

$categories = \Category::with(array('posts' => function ($query) {
    return $query->orderBy('created_at', 'desc')->take(10);
}))->get();

这样的相对语义化的写法很容易让人错误的以为会对每个分类下取10篇文章,而事实上是总共取10篇文章

QQ20140601-1.png

[Laravel4] 创建一个 占位图片 服务

演示图片地址:http://usr.im/100x100

使用Composer安装intervention/image库

composer require intervention/image:dev-master

编码

这里并未对生成的图片进程缓存处理,需要的可以自行加上。

// vim app/routes.php
<?php
Route::pattern('width', '\d+');
Route::pattern('height', '\d+');
Route::get('{width}x{height}', 'ImageHolderController@getIndex');
// vim app/controllers/ImageHolderController.php
<?php

class ImageHolderController extends BaseController {
    public function getIndex($width, $height)
    {
        $width = intval($width);
        $height = intval($height);
        if ($width > 1900 || $height > 900)
            App::abort(404);
        $fontSize = min(max(intval($width / 5), 12), 38);
        $image = Image::canvas($width, $height, '#CCCCCC')
                ->line('#B5B5B5', 0, 0, $width, $height)
                ->line('#B5B5B5', $width, 0, 0, $height)
                ->text($width . 'x' . $height, $width / 2, $height / 2, function ($font) use ($fontSize) {
                    $font->file(public_path('font/Georgia.ttf'));
                    $font->align('center');
                    $font->valign('middle');
                    $font->size($fontSize);
                    $font->color('#666666');
                });
        // 2014-07-19 17:46 修复图片格式不正确的问题,->encode('png')
        return Response::make($image->encode('png'), 200, array('Content-Type' => 'image/png'));
    }
}

使用命令行创建dmg

自动获取软件版本号

APP_NAME="Soulver"
VERSION=$(/usr/libexec/plistbuddy -c Print:CFBundleShortVersionString: "${APP_NAME}.app/Contents/Info.plist")
DMG_BACKGROUND_IMG="Background.png"

VOL_NAME="${APP_NAME} ${VERSION}"
DMG_TMP="${VOL_NAME}-temp.dmg"
DMG_FINAL="${VOL_NAME}.dmg"
STAGING_DIR="./Install"

创建dmg

# 清理文件夹
rm -rf "${STAGING_DIR}" "${DMG_TMP}" "${DMG_FINAL}"
# 创建文件夹,拷贝,计算
mkdir -p "${STAGING_DIR}"
cp -rpf "${APP_NAME}.app" "${STAGING_DIR}"
SIZE=`du -sh "${STAGING_DIR}" | sed 's/\([0-9\.]*\)M\(.*\)/\1/'` 
SIZE=`echo "${SIZE} + 1.0" | bc | awk '{print int($1+0.5)}'`
# 容错处理
if [ $? -ne 0 ]; then
   echo "Error: Cannot compute size of staging dir"
   exit
fi
# 创建临时dmg文件
hdiutil create -srcfolder "${STAGING_DIR}" -volname "${VOL_NAME}" -fs HFS+ \
      -fsargs "-c c=64,a=16,e=16" -format UDRW -size ${SIZE}M "${DMG_TMP}"
echo "Created DMG: ${DMG_TMP}"

设置dmg

DEVICE=$(hdiutil attach -readwrite -noverify "${DMG_TMP}" | \
         egrep '^/dev/' | sed 1q | awk '{print $1}')
sleep 2
# 增加Applications目录的软链接
echo "Add link to /Applications"
pushd /Volumes/"${VOL_NAME}"
ln -s /Applications
popd
# 拷贝背景图片
mkdir /Volumes/"${VOL_NAME}"/.background
cp "${DMG_BACKGROUND_IMG}" /Volumes/"${VOL_NAME}"/.background/

# 使用applescript设置一系列的窗口属性
echo '
   tell application "Finder"
     tell disk "'${VOL_NAME}'"
           open
           set current view of container window to icon view
           set toolbar visible of container window to false
           set statusbar visible of container window to false
           set the bounds of container window to {400, 100, 938, 432}
           set viewOptions to the icon view options of container window
           set arrangement of viewOptions to not arranged
           set icon size of viewOptions to 72
           set background picture of viewOptions to file ".background:'${DMG_BACKGROUND_IMG}'"
           set position of item "'${APP_NAME}'.app" of container window to {160, 195}
           set position of item "Applications" of container window to {360, 195}
           close
           open
           update without registering applications
           delay 2
     end tell
   end tell
' | osascript

sync
# 卸载
hdiutil detach "${DEVICE}"

压缩dmg

echo "Creating compressed image"
hdiutil convert "${DMG_TMP}" -format UDZO -imagekey zlib-level=9 -o "${DMG_FINAL}"

# 清理文件夹
rm -rf "${DMG_TMP}"
rm -rf "${STAGING_DIR}"

echo 'Done.'
exit

PHP unpack VS Python unpack

unpack 对二进制数据解包。

php unpack的结果 数组的索引是从 1 开始的
python unpack的结果是 元祖,索引从 0 开始

php unpack可以传大于需要解包长度的二进制串
python unpack只能传入需要的长度的二进制串

php unpack 和 python unpack 的解包格式不一样,例如:

这是纯真数据库自动更新的例子: QQWryUpdate

// php
unpack('V6', $bin);

# python
import struct
struct.unpack('<6L', bin[0:24])

2017-07-25更新

echo pack('H*', $hash);
import codecs
from base64 import b32encode

print(b32encode(codecs.decode(hash, 'hex')).decode())

svg图片蒙板

预览

2014-04-13 11_59_17.gif

代码

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <filter id="maskfilter">
    <feColorMatrix in="SourceAlpha"
                   type="matrix"
                   values="0 0 0 1 0
                           0 0 0 1 0
                           0 0 0 1 0
                           0 0 0 1 0" />
  </filter>
  <mask id="svgmask">
    <image xlink:href="mask.png" x="0" y="0" width="130" height="130" filter="url(#maskfilter)"></image>
  </mask>
  <g transform="translate(100, 100)">
    <image id="handler" xlink:href="default.jpg" x="0" y="0" width="260" height="130" mask="url(#svgmask)"></image>
  </g>
</svg>
// https://code.jquery.com/jquery-2.1.0.min.js
(function ($) {
    var x, y, startX, startY, isDragging;
    x = y = startX = startY = 0;
    isDragging = false;
    var handler = $('#handler');
    handler.on('mousedown', function (e) {
      x = parseInt(handler.attr('x'));
      y = parseInt(handler.attr('y'));
      startX = e.pageX;
      startY = e.pageY;
      isDragging = true;
    });
    $(document).on('mousemove', function (e) {
      if (!isDragging) return;
      handler.attr('x', x + e.pageX - startX);
      handler.attr('y', y + e.pageY - startY);
    }).on('mouseup', function (e) {
      isDragging = false;
    });
  })(jQuery);

Photoshop不能初始化的问题

不能初始化 Photoshop,因为文件被锁定、您没有必需的访问权限,或者其他程序正在使用该文件。 在 Finder 中使用“简介”命令可解锁文件,让您有权访问该文件。如果问题仍然存在,请将文档存储到其他文件,或将其复制到 Finder 中

打开Photoshop的时候按option+command+shift,删除Adobe Photoshop设置文件后,正常启动。

MacBook Pro换SSD

MacBook型号:13-inch, Mid 2012
SSD型号:Intel SSD 530 180G

工具:

 釰 > 多功能组合螺丝刀套装

软件:

Trim Enabler
Carbon Copy Cloner

实践结果:

1. SSD只能放在主硬盘位,于是原来的机械硬盘就放在光驱位
2. 程序从机械硬盘上转移到SSD上之后,Chrome打开某些网页的时候存在问题,重新下载Chrome安装就可以了。
3. 貌似`Carbon Copy Cloner`不会copy空文件,所以,某些目录会显示成英文名字;直接执行
touch "/Users/$(whoami)/Desktop/.localized"

Vox中文乱码的问题

使用iTunes转换歌曲的ID3版本,首先确保下面的设置,否则iTunes的修改不会作用到原文件上面。
Screenshot_2014-04-07_22_41_58.png

在iTunes的音乐列表里面+a全选,右键:
Screenshot 2014-04-07 22.45.12.png

接着选择v2.4,然后在Vox中就不会乱码了
Screenshot_2014-04-07_22_45_02.png

Nginx图片处理

server {
  # ...此处省略N行配置
  # example: /thumb/[md5].png_300x187.png
  location ~ "/thumb/([0-9a-f]{32}\.(png|jpg|gif))_(\d+|-)x(\d+|-)\.(png|jpg|gif)$" {
    access_log off;
    set $image $1;
    set $width $3;
    set $height $4;
    # 建议使用try_files代替if
    try_files /thumb/$image =404;
    image_filter resize $width $height;
    image_filter_buffer 10M;
    # 只会在浏览器端缓存,若要在服务器端缓存,可采用proxy的方案(此处没有给出,可自行google)
    expires 7d;
  }
}

object-c调用网址缩短api

短网址文档地址: usr.im

NSString *requestUrl = [NSString stringWithFormat:
                                 @"http://api.usr.im/short.txt?url=%@", @"http://tool.lu/"];
NSString *shortUrl = [NSString stringWithContentsOfURL:[NSURL URLWithString:requestUrl]
                                                   encoding:NSUTF8StringEncoding error:nil];
// NSLog(@"%@", url);

Sequel Pro Bundle修复

Copy as Text Table

这个第三方的bundle,可以将查询到的数据复制为ascii table。但是遇到字段中存在中文的时候,field的宽度就不对了。

// $lenfunc = 'mb_strlen';
$lenfunc = 'mb_strwidth';

将24行的mb_strlen修改为mb_strwidth就可以了。

+----+------+--------------+-------------+
| id | name | displayorder | discription |
+----+------+--------------+-------------+
| 1  | 程序 | 1            | 代码工具    |
| 2  | 生活 | 2            | 生活娱乐    |
+----+------+--------------+-------------+

Laravel的Nginx配置

server {
    listen 80;
    server_name tool.lu;
    root /data/html/tool.lu/public;
    index index.html index.php;

    location / {
        try_files $uri $uri/ /index.php$is_args$query_string;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

if (!-f $request_filename)貌似并不是一个好的做法

mac上nasm汇编helloworld

osx 10.9上自带的nasm版本比较低,然后不能编译64位的程序。

www.nasm.us直接下载最新的版本;路径加入系统的PATH环境变量里面就好了。

mac上面的gcc编译.o文件的时候默认的入口是_main,而使用ld命令时,默认的是start

SECTION .data

msg: db "hello xiaozi!", 0x0a
len: equ $-msg

SECTION .text
global _main

kernel:
    syscall
    ret

_main:
    mov rax,0x2000004
    mov rdi,1
    mov rsi,msg
    mov rdx,len
    call kernel

    mov rax,0x2000001
    mov rdi,0
    call kernel
nasm -f macho64 -o asm1.o asm1.asm
ld -o asm1 -e _main asm1.o
./asm1

[SysStatus app] 模拟monitorplus状态栏

首先看效果:

screenshot2-1.png
2014-02-24 14_03_06.gif

下面是所用到的颜色:

screenshot1.png

分析:

detail.png

代码

因为是demo,所以很多地方的代码组织不完善。

//
//  StatusItemView.h
//  SysStatus
//
//  Created by xiaozi on 14-2-23.
//  Copyright (c) 2014年 xiaozi. All rights reserved.
//

#import <Cocoa/Cocoa.h>
#import "ProgressView.h"

@interface StatusItemView : NSControl <NSMenuDelegate> {
    NSStatusItem *_statusItem;
    BOOL _isHighlighted;
    NSDictionary *_data;
    SEL _action;
    id __unsafe_unretained _target;
    ProgressView *_cpuView;
    ProgressView *_memView;
}

@property (nonatomic, readonly) NSStatusItem *statusItem;
@property (nonatomic, setter = setHighlighted:) BOOL isHighlighted;
@property (nonatomic) NSDictionary *data;
@property (nonatomic) SEL action;
@property (nonatomic, unsafe_unretained) id target;

- (id) initWithStatusItem: (NSStatusItem *)statusItem;

@end
//
//  StatusItemView.m
//  SysStatus
//
//  Created by xiaozi on 14-2-23.
//  Copyright (c) 2014年 xiaozi. All rights reserved.
//

#import "StatusItemView.h"
#import "ProgressView.h"

@implementation StatusItemView

- (id) initWithStatusItem: (NSStatusItem *)statusItem
{
    self = [super init];
    if (self) {
        // Initialization code here.
        _statusItem = statusItem;
        _cpuView = [[ProgressView alloc] initWithFrame: NSMakeRect(0, 10, 82, 11)];
        [_cpuView setBarColor:[NSColor colorWithCalibratedRed:0.91 green:0.3 blue:0.24 alpha:1]];
        [_cpuView setData:[NSDictionary dictionaryWithObjectsAndKeys:@"CPU %3d%%", @"label", [NSNumber numberWithInt: 0], @"value", nil]];
        _memView = [[ProgressView alloc] initWithFrame: NSMakeRect(0, 1, 82, 11)];
        [_memView setBarColor:[NSColor colorWithCalibratedRed:0.29 green:0.64 blue:0.87 alpha:1]];
        [_memView setData:[NSDictionary dictionaryWithObjectsAndKeys:@"MEM %3d%%", @"label", [NSNumber numberWithInt: 0], @"value", nil]];
        [self addSubview:_cpuView];
        [self addSubview:_memView];
    }
    return self;
}

- (void) setData: (NSDictionary *)data
{
    [_cpuView setData:[NSDictionary dictionaryWithObjectsAndKeys:@"CPU %3d%%", @"label", [data objectForKey: @"cpu"], @"value", nil]];
    [_memView setData:[NSDictionary dictionaryWithObjectsAndKeys:@"MEM %3d%%", @"label", [data objectForKey: @"mem"], @"value", nil]];
}

- (void) setHighlighted: (BOOL) highlighted
{
    if (_isHighlighted == highlighted) return;
    _isHighlighted = highlighted;
    [_cpuView setHighlighted: highlighted];
    [_memView setHighlighted: highlighted];
    [self setNeedsDisplay: YES];
}

- (void) setMenu:(NSMenu *)menu
{
    [menu setDelegate: self];
    [super setMenu: menu];
}

- (void)mouseDown:(NSEvent *)theEvent
{
    [_statusItem popUpStatusItemMenu: [super menu]];
    [NSApp sendAction:_action to:_target from:self];
}

- (void)menuWillOpen:(NSMenu *)menu {
    [self setHighlighted:YES];
    [self setNeedsDisplay:YES];
}

- (void)menuDidClose:(NSMenu *)menu {
    [self setHighlighted:NO];
    [self setNeedsDisplay:YES];
}

- (void)drawRect:(NSRect)dirtyRect
{
    [_statusItem drawStatusBarBackgroundInRect:dirtyRect withHighlight: _isHighlighted];

}

@end
//
//  ProgressView.m
//  SysStatus
//
//  Created by xiaozi on 14-2-24.
//  Copyright (c) 2014年 xiaozi. All rights reserved.
//

#import "ProgressView.h"

@implementation ProgressView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
        _data = [NSDictionary dictionaryWithObjectsAndKeys:@"LAB %3d%%", @"label", [NSNumber numberWithInt: 50], @"value", nil];
        _barColor = [NSColor colorWithCalibratedRed:0.91 green:0.3 blue:0.24 alpha:1];
    }
    return self;
}

- (void) setHighlighted:(BOOL)highlighted
{
    if (_highlighted == highlighted) return;
    _highlighted = highlighted;
    [self setNeedsDisplay: YES];
}

-(void) setData:(NSDictionary *)data
{
    _data = data;
    [self setNeedsDisplay: YES];
}

- (void)drawRect:(NSRect)dirtyRect
{
    NSColor *fontColor,*barBorderColor,*barIndicatorColor,*barBgColor;
    if (_highlighted) {
        fontColor = [NSColor whiteColor];
        barBorderColor = [NSColor whiteColor];
        barIndicatorColor = [NSColor whiteColor];
        barBgColor = [NSColor clearColor];
    } else {
        fontColor = [NSColor blackColor];
        barBorderColor = [NSColor colorWithCalibratedRed:0.17 green:0.24 blue:0.3 alpha:1];
        barIndicatorColor = _barColor;
        barBgColor = [NSColor colorWithCalibratedRed:0.95 green:0.96 blue:0.96 alpha:1];
    }
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:@"Menlo" size: 8], NSFontAttributeName, fontColor, NSForegroundColorAttributeName, nil];
    NSAttributedString * text=[[NSAttributedString alloc] initWithString:[NSString stringWithFormat: [_data valueForKey:@"label"], [[_data objectForKey: @"value"] integerValue]] attributes: attributes];
    [text drawAtPoint:NSMakePoint(6, 1)];
    
    NSRect bar = NSMakeRect(50.0f, 3, 27.0f, 6.0f);
    bar = NSInsetRect(bar, .5f, .5f);
    NSBezierPath *barView = [NSBezierPath bezierPathWithRect: bar];
    [barBgColor set];
    [barView fill];
    [barBorderColor set];
    [barView stroke];
    NSRect barIndicator = NSMakeRect(50.0f, 3, roundf(.27f * [[_data objectForKey: @"value"] integerValue]), 6.0f);
    barIndicator = NSInsetRect(barIndicator, 1, 1);
    [barIndicatorColor set];
    [NSBezierPath fillRect:barIndicator];
}

@end

使用方法

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    NSStatusItem *statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:82];
    statusItemView = [[StatusItemView alloc] initWithStatusItem: statusItem];
    [statusItem setHighlightMode: YES];
    [statusItem setView: statusItemView];
    [statusItemView setMenu: _statusMenu];
    
    [NSTimer scheduledTimerWithTimeInterval:2
                                      target:self
                                    selector:@selector(updateInfo:)
                                    userInfo:nil
                                     repeats:YES];
}

- (void)updateInfo:(NSTimer *)timer
{
    int cpuUsage = (arc4random() % 20) + 2;
    int memUsage = (arc4random() % 10) + 50;
//    NSLog(@"%d, %d", cpuUsage, memUsage);
    NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt: cpuUsage], @"cpu", [NSNumber numberWithInt: memUsage], @"mem", nil];
    [statusItemView setData: data];
}