2009-05-08

桑梓贴吧视频数据的解决方案

  由于种种问题以及磁盘阵列空间有限,桑梓贴吧的阵列趋近饱和,为了解决这个问题最近稍微研究了一下,根据实际的发现,桑梓贴吧的视频文件有一些在网站后台已经被删除,但是在服务器上的文件却没有被删除。这样一来,我就在猜想这种情况恐怕不少。于是,经过一番考虑,想到了一个方法。



这个方法的要点如下:


  1. 从数据库中查出所有桑梓贴吧的视频文件名记录,导出到一个新的表。
  2. 从视频文件目录下导出所有视频文件名列表,再倒入到一个新的数据库表中。
  3. 对比两个数据库的文件名字段,筛选出不是同时存在于两个数据库之中的数据
  4. 导出多出的文件列表,删除文件。

那么一步一步看。

  第一步:导出桑梓贴吧的视频文件名记录。假设表是address 字段是link那么。我们直接复制整个表到别的数据库。

  第二步:从视频目录下导出所有视频文件名的列表,只需要cd到视频目录然后:
find ./ -exec ls {} \; &;gt /home/temp/filelist.txt

  这样就成功的吧文件列表导出来了。之后再想办法把这个列表导入到一个数据库表中。

  第三步:假设我们导入的数据表是exist那么现在对比找出在两个表中不同时存在的数据:

insert into temp(link)
select link from fileexist
where not exists ( select link from addresswhere address.link = fileexist.link) ;

  这一步会在一个临时表temp中的link字段中插入在两个表中不同时存在的数据,因此再把temp表的字段导出就成为了我们要挑选出的文件了。

  第四步:要删除文件,由于数量众多需要使用xargs命令:为免意外我先移动到其他目录,再行删除:

xargs -i mv {}&;lt /home/ftp/temp.txt ../tempuse

这个命令就是用xargs把文件名传递到{}的位置,移动过去而已。而且不怕列表里有文件不存在。

好了,一下子删了200多G的东西,世界清静了。。。。

2009-05-05

php扩展的动态编译

有时候需要安装php的模块,这个时候重新编译php就相当不合适了。因此使用类似于apache的动态编译的特性就不错了。对于php来说,我们有很棒的工具,以pdo_mysql为例。
一下假设我的php已经安装在/opt/php
php的源代码在/home/test/php里。
cd /home/test/php/ext/pdo_mysql
/opt/php/bin/phpize
./configure --with-php-config=/opt/php/bin/php-config --with-pdo-mysql=/opt/mysql/

这样这个模块就编译好了。吧php.ini里面对应的模块打开即可。

另外,注意安装pdo需要aclocal这个在autoconf包里的程序。

2009-05-01

JavaFX GUI Learning: Task Learning

Learning from practice!




This article is the note of my learning of JavaFX under the offical javaFX website tutorial:
http://www.javafx.com/docs/tutorials/mediabrowser/index.jsp

Task 1: Loading and Displaying an Image


Graph Programming Model :

  • Stage is the top level container for JavaFX program.
  • Scene is a drawing surface for graphical content and a container that holds the scene graph nodes. It can be added to Stage, and JavaFX renders everything on a scene.
  • CustomNode is a subclass of javafx.scene.Node and created by overriding the create function. It can have one child node.
  • Group is a sequence of child nodes.

  • Node is an element in a scene graph, and javafx.scene.Node is an abstract class. The following visual objects are examples of javafx.scene.Node implementation: javafx.scene.image.ImageView, javafx.scene.media.Mediaview, javafx.ext.swing.*, javafx.scene.shape.*, and javafx.scene.text.Text. These are leaf nodes, which cannot have a child element.

By the tutorials of SUN, it supply a architecture of this program:




In our program, main.fx is the main class file and the first class to be built, we build a stage and add a scene into it.

You can download the netbeans project file to have a detail looking of this project

http://www.javafx.com/docs/tutorials/mediabrowser/dist/module01-task01_nb.zip

The code of offical demo of task 1 is a little confusing to beginner, So I have change some code and comment so that it is easy for my self to understand, if you need, you can download it from http://ulysess.ys168.com/


After the task 1, we have a simply program that can scale-up a image by user's click.


Task 2 :will create a image wall.


So it is a good habbit to define a action by code like this:

package var fullView : function(metaData : MetaData, placeholder: Image) : Void;

object does not need to know how to do fullView, it let other object which will arrange its to do it.

Task 3: Adding a Expansion effect

Expansion effect will scale up you thumbnail 25% bigger while find your cursor is above it

In order to implementation that, we should make the program know how to center the thumbnail after scaled, and handing the expansion such that it does not make the wall resize.

We just need change thumbnail.fx class, put image into a boundingRect and use imageView to painting the thumbnail, and finally some mouse event, that is what we need.

Offical project can be download in http://www.javafx.com/docs/tutorials/mediabrowser/dist/module01-task03_nb.zip



Task 4:Building a Animation Effect

A program provide scale the image must have the basic function of zoom in and zoom out. We need timeline, key frame and interpolators to implement that functions.

  • Timeline is an object that contains a list of key frames, together with a function to control the animation, which might be to start it, stop it, and repeat it.

  • KeyFrame describes a set of end states of various properties (values) of objects at a certain time instant relative to the start of the animation, together with interpolation specifications to calculate the in-between values relative to the previous frame.
  • KeyValue class defines a target, which is a reference to an object to animate, a value for the object to take on at the KeyFrame time, and an Interpolator.
  • The type of interpolation is defined with a KeyValue so that different interpolation types can be used for each KeyValue in a KeyFrame and at different KeyFrame times. Custom interpolators can be written, but the following simple interpolators are provided for animating numeric values:

  • Interpolator.LINEAR - (The default) uses simple linear interpolation.

  • Interpolator.EASEOUT - Start changing the value slowly after the KeyFrame.

  • Interpolator.EASIN - Slow the rate of change as the KeyFrame is reached.
  • Interpolator.EASEBOTH - Smooth the rate of change through the KeyFrame.

  • A shorthand syntax is provided for defining simple KeyFrames.
    at ( &;lttime&;gt ) {
    &;lttarget&;gt =&;gt &;ltvalue&;gt tween &;ltinterpolator&;gt;
    }

    Well, does it looks a little familar? Yes, if you have a basic knowledge about FLASH, It just about the same concept. After you know the knowledge It's a easy task to do this.

    Let us look at the architecture:

    There are two new operator in the code, the => operator provides a literal constructor for a list of key values. The tween operator is a literal constructor for an interpolated value.

    One thing should note in this section is that the interpolator can't be used at will other than it can result your animation play in unwanted way!

    Task 5: Scroll Controller Feature

    We have lots of photos and obviously it can not displayed in one screen, so we need scroll contorller to navigate to others thumbnails.


    In this task we need a new class ScrollControl and add two function in wall.fx

    JavaFX Script Learning: Basic Knowledge

    Declaring Variables:
    There are two type variables in JavaFX, var or def, we can use 'var' and 'def' keyword to declare varibles. the difference between the two is that var may be assigned new value while def not, so def is a little like final variables in Java.
    In JavaFX we can do not explicitly specify variables as its date type, compiler can figure out what is the data types you need, this called type inference.

    Defining and Invoking Functions:
    a basic format of function define:
    function add() { }
    a function with arguments:
    function add(argOne: Integer, argTwo: Integer) {}
    a function with returnvalue of Integer:
    function add() : Integer { var resule = 11; return resule;}
    Note that if no return value is specified, a function returns Void by default.
    Accessing Command-Line Arguments:
    function run(args : String[]) {}
    Note that run function is special that serves as the script's main entry point.
    Invoke a function just like invoke a method in Java.

    Using Object:
    def myAddress = Address { street: "I don't know"; }
    this line code create a Object of Address and assign the value of street instance variable of Address.

    Data Types:
    In JavaFX there are 6 build-in data types: String, Number and Integer, Boolean, Duration, Void, Null.
    String can be declared by single or double quotes.
    Number is floating-point number while Integer is integer number.
    Duriation type represents a fixed unit of time, it should be notated with time literals for example:
    5ms //5 milliseconds
    5s //5 seconds
    5m //5 minutes
    5h //5 hour


    Void is used toe indicate that a function does not return any value.
    null i a special value used to indicate a missing normal value, null is not the same as zero or empty string. you can use 'null' keyword to comparing if its null, in a word, its like null in java.


    Sequences in JavaFX:
    Sequences should be declared in square brackets[] ,such as


    def weekDays: String[] = ["mon","tue","wed","thu","fri"];
    def days : [weekDays, ["sat","sun"]];
    def nums= [1..10];
    //this declared a sequence contains numbers from 1 to 10 with step 1
    def numg= [10..1 step -1];
    //this declared a sequence contains number from 10 to 1 with step -1
    //Note that if create a descending range the second value should less
    // than first
    def nums2 = nums[ n | n &;lt 5]
    //this will create a sequence with the items from mums where value
    //less than 5
    def size =sizeof numg;
    // this will get the size of numg
    def weekend = days[5..6];
    //this will create a sequence with the items of days 6 to 7
    def weekend2 = days[5..];
    //this will create a sequence with the items of days 6 to the end
    //of days
    def weekdays2 = days[0..&;gt5];
    //this will create a sequence with the items of days 1 to 5
    def days2 = days[0..&;gt];
    //this will create a sequence with all items from days,
    //but the last item of days will be excluded


    Operators in JavaFX:
    +-*/is same to Java
    mod get remainder
    not is inverts the balue of boolean
    and or is same to Java
    instanceof is same to Java


    Expressions in JavaFX:
    A block expressions surrounded by curly braces and must be sparated by semicolons. The VALUE of block expression is the value of the last expression. var and def are expressions.
    Look for expression:
    var nums= [1..10] ;
    for(num in nums) { println(nums); }

    2009-04-27

    JavaFX Script Learning: Data Binding and Triggers

    One of the most useful feature in JavaFX is its Data Binding and Triggers functions. According to the official tutorial, Data binding is the ability to create an immediate and direct relationship between tow variables, This allow two or more variables can automatically change when the other or others change. At the same time, A Replace Trigger is a block of code that is attached to a variable, which when the variable changes, the code is automatically executed. So let's begin here.
    Here is an example :


    var x = 0;
    def y = bind x;
    x=1;
    println(y); //y now equals 1
    x = 333;
    println(y); // y now is 333;

    That is a extreme sample example to show the use of 'bind' keyword, You can know in that example, y is binded to x, and its value is changed with x, that's the basic use of bind. Note that y is declared as a def because we don't want any thing change y by assigning a value to it.
    An other example:

    var myStreet= " No.2 Phoenix Garden"
    var myCity = "Xiamen"

    def address = bind Address {
    street : myStreet;
    city : myCity;
    };

    println({address.street});
    myStreet = "No.33 NoWhere"
    println({address.street});


    In this example the result of execute is :
    No.2 Phoenix Garden
    No.33 NoWhere

    So, the conclusion is we can bind a variable with the value of a bound expression, which can be a basic type, an object, the outcome of a function, or the outcome of an expression. But in this example we must note that the changing of myStreet actually causes a new Address object to be created and then re-assigned to the address variable. If you don't want this happen, you can change the definition like this:

    def address = bind Address{
    street: bind myStreet;
    city : myCity;
    }

    By this, you can change street without create a new object, and the bind in def line can be omited.

    In next step, let us look at Binding and Functions.

    Here is an example :

    var scale = 1.0;

    bound function makePoint(xPos : Number, yPos : Nubmer) : Point {
    Point {
    x: xPos * scale;
    y: yPos * scale;
    }
    }

    class Point {
    var x : Number;
    var y : Number;
    }

    var myX = 5.0;
    var myY = 9.0;
    def pt = bind makePoint(myX, myY);
    println(pt.x);

    myX *=2;
    println(pt.x);

    scale = 2.0;
    println(pt.x);

    At the head of this code, we announce a bound function by 'bound' keyword, and then we use our own myX and myY number to create a Point by that bound function, note we use bind keyword before the invocation of makePoint function, so pt binded to the outcome of makePoint function.
    The result of executing is :
     
    5.0
    10.0
    20.0

    But if we remove the bound keyword from makePoint function(it became a non-bound function), the result would be:

    5.0
    10.0
    10.0

    The different between these two situation is a bound function will get re-invoked when every variable related to the function changed while the non-bound function only do that when one of their arguments change. And we MUST NOTE that bound function and bind keyword is work together.


    In next step, let us look at Binding with Sequences:

    Here is an example:

    var q1 = [1..10];
    def q2 = bind for (item in q1) item *8;
    printSeqs();
    insert 11 into q1;

    function printSeqs() {
    println("First Sequence:");
    for( i in q1) { println(i) ; }
    println("Second Sequence:");
    for( i in q2) { println(i) ; }
    }

    You can guessed the result is first sequence is 1 to 10 with step of 1 and the second sequence is 8 to 80 with step of 8.
    In this example, we bind two sequence by placing the bind before the for. For more understanding, we can try to change one or some items of q1, you can find the corresponding items q2 will automatically changed and others will not be affect, like we do in the example we insert a item 11 into the end of q1 and q2 automatically generated a item 88 at the end of itself.

    Finally, let us look at the Replace Triggers.
    It is arbitrary blocks of code that attach to variables and execute whenever the variable's value changes. Here is an example:

    var test = "test" on replace oldValue {
    println(" value has changed, old value is { oldValue}");
    }

    test = "no";

    The trigger will fires two times, first is the initialized to "test" and the next is fires When the code "test= "no"; " executed, the program will report value has changed. NOTE that the oldValue store the value of test before the trigger was invoked.