16 Impressive CSS3, HTML5 and Javascript Experiments From Hakim

If you’re a fan of Canvas, WebGL and interactive CSS3, HTML5 and Javascript, you most probably have heard of the name Hakim. Hakim is a web developer and creative programmer from Sweden who passionate about working with animation and interactivity. He has many personal projects and experiments with HTML5, CSS and Javascript showcased in Chrome Experiments and other places. We are really impressed but his creativity and cool stuff that he managed to create, and the following is some of the coolest things on the web.

  • CSS3 Scroll EffectCool list scrolling effect. Not intended for any practical use but the visuals are surprisingly impactful.

    CSS3 Scroll Effect

  • DOM TreeChristmas Pine Tree wit form elements.

    DOM Tree

  • OrigamiSimply a colorful folding doodle on. Click anywhere on the drawing — or use your keyboard — to activate different layouts.

    Origami

  • .net 404A creepy 404 page for .net magazine.

    .net 404

  • SphereThe sphere — actually more of a spiral — is built out of 10,000 particles and the structure changes over time.

    Sphere

  • Textify.itBrowser for or drag an image onto the page and watch it be reconstructed purely out of text. The markup for the resulting textual image can be copied and used elsewhere.

    Textify.it

  • WebGL ParticlesAn experiment created to test the efficiency of particles rendering with WebGL.

    WebGL Particles

  • BreakDOMThis is a remix of the classic Breakout game except all game elements have been replaced with HTML user interface elements.

    BreakDOM

  • SinuousA game built on the HTMLCanvas element which will test your mouse pointer reflexes. The objective is to stay clear of the evil red dots and stay alive as long as possible.

    Sinuous

  • MagneticControl and create currents of particles which react to magnetic nodes.

    Magnetic

  • WaveA wave with bubbles floating on the surface, the bubbles each represent a tweet with the word “water” in it.

    Wave

  • TrailParticle movement patterns that generate smooth trails.

    Trail

  • BlobSoft blobby physics. It’s like, you know… jelly?

    Blob

  • BacteriumAn interactive experiment with bacteria in a playful and dynamic physics world.

    Bacterium

  • Particle DepthParticle positioning patterns using depth.

    Particle Depth

  • KeylightA playhead travels between keys which resonate in sound depending on where they are placed in the room.

    Keylight

Posted in Uncategorized

Markdown语法

概述

哲学

Markdown 的目标是易读易写。

Markdown强调可读性高于一切。一份Markdown格式的文档应该能直接以纯文本方式发布,而不致一眼看过去满眼都是标签和格式化指令。Markdown的语法确实受了几种现有的text转HTML过滤器影响--包括 Setext, atx, Textile, reStructuredText,Grutatext, 和 EtText — 其中对Markdown语法影响最大的单一来源是纯文本的Email格式。

为实现这一目标,Markdown的语法几乎全部由标点符号构成,这些标点符号都是精心挑选而来,尽量做到能望文生义。如星号括着一个单词(Markdown中表示强调)看上去就像 *强调*。Markdown的列表看上去就像列表;Markdown的引文就象引文,和你使用email时的感觉一样。

内嵌HTML

Markdown的语法为“方便地在网上写作”这一目标而生。

Markdown不是HTML替代品,也不是为了终接HTML。它的语法非常简单,只相当于HTML标签的一个非常非常小的子集。它并非是为了更容易输入HTML标签而创造一种新语法。在我看来,HTML标签已经够容易书写的了。Markdown的目标是让(在网上)让读文章、写文章、修改文章更容易。HTML是一种适合发表的格式;而Markdown是一种书写格式。正因如此,Markdown的格式化语法仅需解决用纯文本表达的问题。

对Markdown语法无法支持的格式,你可以直接用HTML。你不需要事先声明或者使用什么定界符来告诉Markdown要写HTML了,你直接写就是了。

唯一的限制是那些块级HTML元素 — 如 <div>,<table>, <pre>, <p>等等 — 必须使用空行与相邻内容分开,并且块元素的开始和结束标签之前不要留有空格或TAB。Markdown足够聪明不会添加额外的(也是不必要的)<p>标签包住这些块元素标签。

下面这个例子,在一篇Markdown文章中添加了一个HTML表格:

这是一个普通的段落。 <table> <tr> <td>Foo</td> </tr> </table> 这是另一个普通的段落。

注意一点,不要在块级HTML元素内使用Markdown格式化命令,Markdown不会处理它们。比如你不要在一个HTML块中使用 *emphasis* 这样的Markdown格式化命令。

行内HTML标签 — 如 <span>, <cite>, 或 <del> — 在一个Markdown段落里、列表中、或者标题中--随便用。 如果需要,你甚至可以用HTML标签代替Markdown格式化命令。比方你可以直接用HTML标签 <a><img> 而不使用Markdown的链接和图片语法,随你的便。

不同于这些块级HTML元素,在HTML行内元素内的Markdown语法标记会被正确处理。

自动转换特殊字符

在HTML中,有两个字符需要特殊对待:<&<用于标签开始,&用于标识HTML实体。如果打算把它们当成普通字符,你必须使用反引号转义它们,如<&

对一些互联网作家来说,&符号特别使人烦恼。如果你打算写’AT&T’,你就得写 ‘AT&amp;T‘。甚至在URL中也得想着转义&符号。比方你打算写:

http://images.google.com/images?num=30&q=larry+bird

你就得在A标签中把href属性中的URL编码成:

http://images.google.com/images?num=30&amp;q=larry+bird

不用说,这很容易忘。这往往是那些良构HTML站点中最容易出错的地方。

在Markdown中,你尽管自然的使用这些字符,只需要关心那些必要的转义。如果使用在HTML实体中使用&符号,它会保持不变;而在其它场合,它会转换成&

所以,如果你打算在文章中书写版权符号,你可以这样写:

&copy;

Markdown不会碰它。然而如果你书写

AT&T

Markdown就会把它翻译成:

AT&amp;T

类似的,既然Markdown支持内嵌HTML,如果你使用<作为HTML标签定界符,Markdown就会把它们当成HTML标签定界符。可是如果你书写:

4 < 5

Markdown就会把它翻译成:

4 &lt; 5

然而,在Mardown代码行内标记和块级标记之中,<&始终会被自动编码。这使得在Markdown文件中书写HTML代码更容易.(相对于纯HTML。如果想在纯在纯HTML里贴一段HTML代码,那才是糟糕透顶,必须对代码中的每一个<&都转义才成。)


块级元素

段落和换行

一个段落由一行或多个相关文本行构成。段落之间用一个或多个空行分隔。(一个空行就是一个看上去什么也没有的行--如果一行什么也没有或者只有空格和TAB都会被视为空行)正常的段落不要以空白或TAB字符开始。

一行或多个相关文本行意味着Markdown支持“硬折行”。这一点与其它text转HTML的程序完全不同(包括Moveable Type的“Convert Line Breaks”选项),它们会将段落中的每一个换行符转换成<br />标签。

如果你确实需要使用Markdown插入一个<br />换行符,只需要在每一行的末尾以两个或更多个空格符号结束,然后再打回车键。

没错,在Markdown里生成一个<br />稍稍有一点麻烦,但那种简单的“把每一个换行符都转换成<br />规则”并不适用于Markdown。Markdown Email风格的 blockquoting 和 multi-paragraph list items更好用 — 并且更美观 — 在你用换行符对其格式化时。

Markdown 支持两种风格的标题,Setextatx.

Setext-风格的一级标题下面一行使用等号符号,二级标题下面使用连字符符号,例如:

这是一个一级标题 ============= 这是一个二级标题 -------------

至少有一个=-就能正常工作。

Atx-风格的标题在每行的开头使用1-6个井号字符,分别对应标题级别1-6。例如:

# 这是一级标题 ## 这是二级标题 ###### 这是六级标题

如果愿意, 你也可以 “结束” atx-风格的标题。这纯粹是美观考虑–如果你觉得这样会看上更舒服些的话。结束用的井号个数随便,不必与起始井号数量相同 (起始井号的数量决定标题级别):

# 这是一级标题 # ## 这是二级标题 ## ### 这是三级标题 ######

引用块

Markdown使用Email风格的 > 字符引用块。如果你熟悉Email中的引用块,你就知道在Markdown中如何使用引用块。如果每一行你都使用硬换行并在行首放一个>符号,看上去会很美观:

> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse > id sem consectetuer libero luctus adipiscing.

(如果觉得每行写一个>太累,)Markdown允许你偷懒,你只需在硬换行段落的第一行之前放一个>号:

> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.

只需要多加一个>,就得到嵌套的引用块(即引用块中的引用块):

> This is the first level of quoting. > > > This is nested blockquote. > > Back to the first level.

引用块中可包含其它Markdown元素,如标题、列表和代码块:

> ## This is a header. > > 1. This is the first list item. > 2. This is the second list item. > > Here's some example code: > > return shell_exec("echo $input | $markdown_script");

是个象样的文本编辑器都能实现Email风格的引用。比如在BBEdit里,你就可以选中一些文字之后从Text菜单里选择引用级别。

列表

Markdown 支持有序列表和无序列表

无序列表可使用星号、加号和连字符(这几个符号是等价的,你喜欢哪个就用哪个)作为列表标记:

* Red * Green * Blue

等同于:

+ Red + Green + Blue

也等同于:

- Red - Green - Blue

有序列表则使用数字加英文句点:

1. Bird 2. McHale 3. Parish

有一点需要注意,你在列表中输入的标记数字并不会反映到Markdown输出的HTML之中。上面这个列表Markdown会输出为:

<ol> <li>Bird</li> <li>McHale</li> <li>Parish</li> </ol>

即使你写成下面这样:

1. Bird 1. McHale 1. Parish

甚至这样:

3. Bird 1. McHale 8. Parish

都会得到一模一样(但正确的)输出。要点在于,如果你愿意,就在你的Markdown有序列表里顺序使用数字(这样源代码里的顺序和生成的顺序会一致),如果你希望省点儿事,你就不用费心(去手工编号)。

如果你打算偷懒,记住列表的第一行使用数字 1。以后Markdown或许会支持有序列表从任意数字开始(译者注:这儿和前面的例子有点矛盾,原文如此)。

列表标记通常从左边界开始,至多可以有三个空格的缩进。列表标记之后至少要跟一个空格或TAB。

为了让列表看起来美观,你可以使用TAB缩进列表项内容,使其整齐:

* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.

不过如果你很懒,下面这样也行:

* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.

如果列表项之间用空行分隔,Markdown就会在HTML输出中使用<p>标签包裹列表项。比如:

* Bird * Magic

生成的HTML如下:

<ul> <li>Bird</li> <li>Magic</li> </ul>

而这个:

* Bird * Magic

生成的HTML是这样:

<ul> <li><p>Bird</p></li> <li><p>Magic</p></li> </ul>

列表项有可能由多个段落组成,列表项的每个后续段落必须缩进至少4个空格或者一个TAB:

1. This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. 2. Suspendisse id sem consectetuer libero luctus adipiscing.

像上面这样缩进后续段落的每一行看起来很美观(但稍有些麻烦),如果你比较懒(和我一样),没问题,Markdown支持你:

* This is a list item with two paragraphs. This is the second paragraph in the list item. You're only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. * Another item in the same list.

要在列表项中使用引用,引用定界符 > 需要缩进:

* A list item with a blockquote: > This is a blockquote > inside a list item.

要在列表项中使用代码块,代码块需要缩进两次 — 8个空格或者两个TAB:

* A list item with a code block: <code goes here>

有时候不小心会触发一个有序列表,比方在写类似下面这样的东西时:

1986. What a great season.

换言之, 以数字+句点+空格 序列起始的行会触发有序列表。为避免此情况,要对句点符号进行转义:

1986. What a great season.

代码块

我们经常在写有关编程或标记语言源代码时用到预格式化的代码块。不像格式化普通段落,代码块中的行会按字面进行解释。Markdown对代码块同时使用<pre><code>标签包裹:

在Markdown中要生成一个代码块,只需要在代码块内容的每一行缩进至少四个空格或者一个TAB。比如:

This is a normal paragraph: This is a code block.

Markdown会生成:

<p>This is a normal paragraph:</p> <pre><code>This is a code block. </code></pre>

Markdown会从生成的代码块中删除一级缩进 — 4个空格或者1个TAB。看下面这个例子:

Here is an example of AppleScript: tell application "Foo" beep end tell

会得到:

<p>Here is an example of AppleScript:</p> <pre><code>tell application "Foo" beep end tell </code></pre>

代码块在遇到没有缩进的一行,或者文件末尾时自动结束。

在代码块中,&符号和<>会自动转换成HTML实体。因此在Markdown中包含HTML源代码只是小菜一碟--粘贴进去,缩进一下。剩下的脏活累活Markdown自会处理。看下面这个例子:

 <div class="sample_footer"> &copy; 2004 Foo Corporation </div>

Markdown会生成:

© 2004 Foo Corporation
 

 

Markdown不会解析代码块中的Markdown标记。如代码块中的星号就是星号,失去了它原来的Markdown含义。这意味着你能够使用Markdown编写Markdown自己的语法教程。(就象这篇文章一样)。

水平线

如果在一行里只放三个或更多个连字符,或星号或下划线,你就会得到一个水平线标记(<hr />)。下面每一行都会得到一个水平线:

* * * *** ***** - - - ---------------------------------------

行内元素

Markdown 支持两种风格的链接: 行内链接引用链接.

两种风格的链接,链接文本都放在中括号之内[square brackets]。

要生成一个行内链接,在链接文本之后紧跟用一对小括号。小括号里放链接地址和可选的的链接title。如果提供链接title的话,链接title要用引号包起来。例如:

这是一个 [an example](http://example.com/ "Title") 行内链接。 [这个链接](http://example.net/) 没有title属性。

Markdown会生成:

<p>This is <a href="http://example.com/" title="Title"> an example</a> inline link.</p> <p><a href="http://example.net/">This link</a> has no title attribute.</p>

如果你打算引用一个本地资源或者同一站点的资源,可以使用相对路径:

如果想进一步了解我,请参阅我的 [关于我](/about/) 页。

引用风格的链接,在链接文本之后紧跟又一对中括号。这对中括号里放的是该链接的标识符(可以理解为别名):

这是一个引用型链接 [示例][id]。

如果你嫌弃两对中括号过于亲密,Markdown允许你在两对中括号之间放一个空格:

这是一个引用型链接 [示例] [id]。

然后,我们可以在文档的任意位置,像下面这样定义链接标识与链接的对应关系(一行一个链接):

[id]: http://example.com/ "Optional Title Here"

即:

  • 中括号内放链接标识符(行前可选缩进,至多不超过三个空格);
  • 之后紧跟一个冒号;
  • 再后面是一个或多个空格(TAB也行);
  • 接下来是链接URL;
  • 最后面是可选的用双引号或单引号或小括号括起来的链接title。

下面三种链接定义方式是等价的:

[foo]: http://example.com/ "Optional Title Here" [foo]: http://example.com/ 'Optional Title Here' [foo]: http://example.com/ (Optional Title Here)

注意: Markdown.pl 1.0.1 版本有一个已知的bug,用单引号作为链接title的定界符会出问题。

至于链接URL,还支持使用一对可选的尖括号包裹起来:

[id]: <http://example.com/> "Optional Title Here"

你也可以将链接的title属性放在下一行并使用额外的空格或TAB填充,这样较长的URL会比较美观:

[id]: http://example.com/longish/path/to/resource/here "Optional Title Here"

链妆定义仅供Markdown解析器使用。最终输出的HTML当中不会包含链接定义。

链接标识符可以由字母、数字、空格和标点符号组成--不区分大小写。下面这两个链接:

[link text][a] [link text][A]

是等价的。

隐式链接标识 允许我们省略链接标识,这时链接文本本身就是链接标识。在链接文本之后加一对空的中括号--例如,使用”Google”文本链接到google.com站点,可以这样写:

[Google][]

然后这样定义它的链接:

[Google]: http://google.com/

链接名字有可能包含空格,不过没问题,这种情况照样正常工作:

Visit [Daring Fireball][] for more information.

然后这样定义这个链接:

[Daring Fireball]: http://daringfireball.net/

链接定义可放于Markdown文档的任意位置。我建议把它们就近放到最先使用它的段落之后。不过如果你更喜欢放到文档末尾,当成某种形式的尾注,随你的便。

下面是一些引用链接的例子:

I get 10 times more traffic from [Google] [11] than from [Yahoo] [12] or [MSN] [13]. [1]: http://google.com/ "Google" [2]: http://search.yahoo.com/ "Yahoo Search" [3]: http://search.msn.com/ "MSN Search"

换成隐式链接标识,也可以这么写:

I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][]. [google]: http://google.com/ "Google" [yahoo]: http://search.yahoo.com/ "Yahoo Search" [msn]: http://search.msn.com/ "MSN Search"

上面两种写法最终得到HTML输出是一样的:

<p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>

作为比较,下面这个段落使用Markdown的行内链接风格编写:

I get 10 times more traffic from [Google](http://google.com/ "Google") than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or [MSN](http://search.msn.com/ "MSN Search").

引用型链接的亮点并不在于它更容易书写,而在于引用型链接让你的文档可读性更好。看看上面的例子:使用引用型链接,段落本身仅81个字符;而使用行内链接的例子,是176个字符。最终输出的HTML则有234个字符。纯HTML中标记字符甚至超过了文本本身。

使用Markdown的引用型链接,源文档更接近于最终的浏览器输出效果。再加上Markdown允许将标记有关的元数据移到段落之外,你尽管添加链接,而不必担心打断文件的故事情节。

强调

Markdown使用星号(*)和下划线(_)作为表示强调。用一个 *_ 包裹的文本会使用 HTML <em> 标签包裹; 用两个 *_包裹的文本会使用HTML<strong> 标签包裹。如:

*single asterisks* _single underscores_ **double asterisks** __double underscores__

将会输出为:

<em>single asterisks</em> <em>single underscores</em> <strong>double asterisks</strong> <strong>double underscores</strong>

你喜欢哪一种风格就用哪一种,唯一的限制就是起始字符与关闭字符必须一致。

强调符号可用于一个单词的一部分:

un*frigging*believable

不过如果你用空格包裹单独的 *_,它们就失去了强调的含义,而成为字面上的星号或下划线。

如果不想让Markdown解释这两个元字符,就转义它:

*this text is surrounded by literal asterisks*

代码

要在行内表示部分代码,用反引号(`)包住它。与预格式代码块不同和,行内代码用于段落之内。例如:

Use the `printf()` function.

会生成:

<p>Use the <code>printf()</code> function.</p>

要在一个行内代码中使用反引号(`)本身,用多个反引号作为定界符包住它:

``There is a literal backtick (`) here.``

这样就会得到:

<p><code>There is a literal backtick (`) here.</code></p>

包住行内代码的反引号定界符可以包括空格--即在起始反引号之后,结束反引号之前可以有一个空格。这使得我们能够在行内代码的开始或结束处使用反引号:

A single backtick in a code span: `` ` `` A backtick-delimited string in a code span: `` `foo` ``

会生成:

<p>A single backtick in a code span: <code>`</code></p> <p>A backtick-delimited string in a code span: <code>`foo`</code></p>

在行内代码中,&<>会自动编码为HTML实体,以方便包含HTML标签。Markdown会把下面这行:

Please don't use any `<blink>` tags.

转换为:

<p>Please don't use any <code><blink></code> tags.</p>

你也可以这样写:

`&#8212;` is the decimal-encoded equivalent of `&mdash;`.

会得到:

<p><code>&#8212;</code> is the decimal-encoded equivalent of <code>&mdash;</code>.</p>

图片

必须承认,要以“自然的”语法把一个图片放到一个纯文本文档之中,确实是一个挑战。

Markdown使用了类似链接语法来表示图片,同样有两种风格:行内图片引用图片

行内图片语法示例:

![Alt text](/path/to/img.jpg) ![Alt text](/path/to/img.jpg "Optional title")

即:

  • 一个感叹号!开头;
  • 其后紧跟一对中括号,中括号内存放图片的alt`属性;
  • 其后紧跟一对小括号,小括号内存放图片的URL或路径,及可选的用双引号或单引号或小括号括起来的图片title

引用图片语法如下:

![Alt text][id]

这里 “id” 是图片引用标识。图片引用定义的语法与链接定义完全相同:

[id]: url/to/image "Optional title attribute"

在写这篇文章时,Markdown还没有语法指定图片的大小,如果这一点对你特别重要,你可以直接使用<img>标签。


杂七杂八

Markdown提供了一种快捷方式”自动地”定义链接和Email地址:直接用一对尖括号把URL或Email地址包住。这表示链接文本就是URL本身,Email文本就是Email本身。这样你就得到了一个可点击的链接,如:

<http://example.com/>

Markdown会将它转换为:

<a href="http://example.com/">http://example.com/</a>

自动Email地址工作方式相似,只有一点不同。Markdown自动的用一些十进制和十六进制数字表示你的Email,以防止遭遇垃圾邮件袭击。 例如:

<address@example.com>

会被转换为:

<a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65; &#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111; &#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61; &#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>

浏览器会将它渲染为一个可点击的链接,并正确显示 “address@example.com”。

(这种实体编码的小方法可以骗过一些收集邮件地址的机器人,不过它确实无法骗过所有的机器人。有总比没有强,聊胜于无。能阻止一点就阻止一点好了。)

反斜线转义

Markdown允许你使用反斜线转义那些Markdown元字符,让它们失去原有的“魔力”。举个例子,如果你确实想用星号包住一个词组(而不是想得到<em>标签),就可以在星号之前使用反斜线将其转义。即:

*literal asterisks*

Markdown中,以下字符支持使用反斜线转义:

 反斜线 ` 反引号 * 星号 _ 下划线 {} 大括号 [] 中括号 () 小括号 # 井号 + 加号 - 减号(连字符) . 句点 ! 感叹号
Posted in Uncategorized

你不必这么着急 –by Rei

现在这个世界,似乎一切都在快速演进:各种年少暴富的新闻充斥着我们的眼球,软件开发世界到处是敏捷方法,甚至你最亲近的人都在催促你更快——谁谁谁都已经XX了,你将来怎么打算?所以,现在的学生找实习的时间越来越早,想速成的心态越来越重。

但是,你不必这么着急。慢有慢的好处,最重要的是,急也急不来。我想和未走出社会的人分享一下,为什么是我们不用那么着急,并且应该把精力放去哪里。如果你已经工作数年了,但是对着未来感到恐惧,却从来没有试着让自己慢一点,也可以看一看接下来的内容。

在继续阅读之前,先看几个问题,判断这篇文章是否适合你。

1. 并不是所有人都那么聪明的,有些人只需要过普通的生活就够了。

对的,但我只想跟觉得自己足够聪明的人讨论后面的内容。实际上,我觉得没有什么聪不聪明之分,只是投入时间的问题。

2. 不是所有人都有那么崇高的理想的,这些内容太理想主义了。

对的,但我也是只想跟心怀理想的人交流。

3. 我负有助学贷款压力/出身贫寒/其他急需资金的原因,没空让我停下来好好考虑。

很遗憾,这部分人可能需要先解决温饱问题,待将来走出了困境,再仔细考虑一下前面的内容。

你没有对上面的内容嗤之以鼻,那么,可以进入正题了。

为什么你不用这么着急

这里有着确切的理由,你不用这么着急

1. 工作岗位比你想象中多

对于真正的人才,工作机会是源源不断的。他们困扰的不是找工作,而是找有趣的工作。这听起来很气人,大学毕业有很多人找不到工作呢,很多人工作几年还在用“码农”调侃自己呢。

但现实就是这样,企业缺人、缺人才,但是不缺平凡的人。企业发出一个招聘岗位,会收到数十上百封简历,但十有八九在第一轮人事MM筛选中就会去掉,真正到达缺人部门的领导手中时,又是十有八九看一眼就被淘汰掉了……等等,这是不是说找工作很难呢?正好相反,看问题得反过来看。

试想你是一个部门领导,你的部门急需补充成员,否则会拖慢年度的计划安排。一个月两个月过去了,总看不到可塑之才出现。所以你得不断地到人事部催促,多发些招聘信息;人事MM每天被催促,恨不得天上掉下个技术大牛,活好收费少,赶紧把招聘任务了结了。这样的部门、这样的公司都处都是,他们都在焦急的等着那些合适的人。如果你恰好是那类人,入职就是一张机票的事。

记住,关键是你是否能成为合适的人。“找”工作是没用的,只会成为那 (9/10 + 1/10 × 9/10) × 100%。最理想的是,让工作来找你,这放在后面说。

2. 现实工作不一定有趣

假设你已经足够成为那类公司热烈欢迎的人了,是不是得赶紧走出社会“积累积累”经验了呢?

我给建议依然是:别急。现实工作不一定有趣,无趣的工作意味着工作效率低下,工作效率低下意味着经验增长缓慢,经验增长缓慢的工作,还不知蹲在家里每天写8个小时代码呢。

一般说来,越大的公司越无趣,因为大公司有复杂的流程。如果你的工作环境被切割成了设计-UI-编码的团队界限分明的结构,那么你的发挥空间就很小了。你的最大目标是实现别人的需求,你需要实现很繁琐的注册表单和根本没人会用的后台控制;你需要在每个a标签里面放一些不必要的span;你需要学会写 ugly 的代码,因为时间紧/反正用得很好/要跟周围风格一致。另一方面,小公司也会让你很无趣,你需要做运维/产品/设计/编码/维护,半夜收到异常Email要起床,还要吃着老板画给你的“等公司上了轨道一定不会亏待你的”的大饼。

天阿,让不让人活了!

其实分辨工作是否有趣很简单:招人最靠谱的是看作品,找工作最靠谱的当然就是看产品了。看公司的产品,你觉得有不有趣,你自己会不会用,细节做得好吗,是又一个 C2C(Copy to China) 吗?从公司的产品,就可以看出公司的内部架构和流程,员工工作得愉不愉快,创意有没有施展的空间。我觉得,Twitter,Github 那样的公司就挺好。

要去,就要去有趣的公司,世界上缺工作的人那么多,为什么要跟他们争抢一份平凡的工作呢?

把精力花到刀刃上

如果你接受了我上面说的理由,那么可以淡定的看待身边一个又一个找到实习或者工作的同学了,因为你需要认真地挖掘什么才是你需要持久钻研的东西。

1. 多参与开源项目

github.com 不用多说了,现在已经成为技术人员最好的简历。

有了 github,参与开源项目成为一件很简单的事情:使用 -> 发现 bug -> 查找/提交 issues -> 提交 pull-request。

不过,要一开始就参加一个热门的项目是很困难的,因为有很多比你聪明(本质只是编程时间比你长)的人都在上面折腾,根本没有让你“接球”的机会。

这时候最好自己发展一个开源项目。

可以练手的项目类型多着呢:你的博客/Todo-list好用吗?你觉得某个现有的服务/项目很搓吗?你需要帮你随机决定中午午餐吃什么而且自动发送邀请给好友的机器人程序吗?

发挥你的想象力,做一个实际能用的项目,比到公司打杂有用多了。

2. 多参与社区讨论

你得了解你学习的技术方向的牛人在哪里混,多跟他们交流,也多回答新手的提问,在网络社区里很有可能你会遇到你将来的同事或者合伙人。

编程是一项社会活动,即使你的程序完全是交给机器执行,但是最终的使用者和受益者是人类,所以你需要认识各种各样的人,了解你是为了什么去编程。

如果你学习 Ruby,我推荐 ruby-china.org,这是当前国内人气最旺的 Ruby 社区了。当然,还有 CodeCampo,你可以看到 Rei 分享的各类奇怪资源。

3. 多进行户外活动

多进行户外活动,即可以强健体魄,也可以让你的性格更开朗。性格开朗的人,创造力会比整天闷闷不乐的人高。这里就有一个乐天向上好榜样:辞职旅行一周年

勇敢的编程 10000 小时

程序世界是非常公平的,随着你编程经验的积累,你的项目用户会开始增多,你的交友圈会更广泛,你的工作机会会找上门——或者该你给别人工作机会了。

无论怎么样,要成为技术牛人,编程 10000 小时是少不了的。无论你愿不愿意,你的经验都在增加,所以你完全不用心急。

看清自己的目标,一步一步的走,有一天它就会在你脚下。

Posted in Uncategorized

Git Submodule 的認識與正確使用!

已經用了 git submodule 好一陣子了,今天看到了 Git submodules in N easy steps 才覺得比較搞懂一些之前碰到的問題。趁機來整理、釐清之前常碰到的小問題吧~~

什麼是 Git Submodule

剛剛從 SVN 或 CVS 等 Client-Server 架構的版本控制系統切換到 Git 時,可能會有這個想法:「能不能只取得一部分的程式碼、而非整個 Repository?」因為在 SVN/CVS 可以針對 Repository 中的某個目錄 checkout,不需要是整個 Repository、甚至還可以用 SVN Externals 達到不同角色 (視覺、前端、後端)checkout 不同 File Layout(之前在無名小站時,超喜歡 svn:externals 的概念)。

但 Git 是分散式的版本控制系統,每個人都是一個完整的 Repository,沒辦法像 SVN/CVS 指定到某個資料夾。例如你要取得 YUI 3 的 Git,只能 git clone https://github.com/yui/yui3.git、而不能指定到底下的目錄。

SVN/CVS 你可以用目錄區隔大小專案、都在同一個大的 Repository。而 Git 的想法必須修正為每個小專案就是一個 Repository、或不同團隊開發是一個 Repository、甚至功能獨立也可以是一個 Repository。若說 SVN 是包容百川、Git 就是各自獨立的小河流

軟體開發團隊不太容易如此單純,有時需要給外包開發、有時需要分工、有時需要用 Open Source,光用以上的切分方式是沒辦法達成所有需求的、還是得將各自獨立的小河流連接起來。例如我先前在 WebRebuild 與 COSCUP 分享的 JavaScript Platform,為了分享把原始碼放了一份到 Github : http://github.com/josephj/javascript-platform-yui,但我的工作及部落格都有使用的需求,該怎麼做呢?如果每次都得 git clone 再 copy 檔案到兩個地方、這樣手工做真的是個很遜的解決方案。好在有 Git Submodule 可以幫忙解決!

簡單來說,Git Submodule 可以輕易地將別人的 git 掛入到你目前 git 的任何位置

新增一個 Git Submodule

例如我有目前本機有一個 josephj.git、在 /home/josephj/www 下,而我需要將 javascript platform 放到 /home/josephj/www/static/ 可以用以下幾行快速達成。

  • 切換到我的 repository 目錄:
    $ cd /home/josephj/www
  • 使用 git submodule add [repository 位置] [欲放置的位置] 增加一個新的 submodule:
    $ git submodule add git@github.com:josephj/javascript-platform-yui.git static/platform需要注意 [欲放置的位置] 不能以 / 結尾(會造成修改不生效)、也不能已經是現有的路徑喔(不能順利 Clone)。
  • 按下去就會看到以下結果:
    $ git submodule add git://github.com/josephj/javascript-platform-yui.git static/platform Initialized empty Git repository in /home/josephj/www/static/platform/.git/ remote: Counting objects: 31, done. remote: Compressing objects: 100% (31/31), done. remote: Total 31 (delta 14), reused 0 (delta 0) Receiving objects: 100% (31/31), 6.06 KiB, done. Resolving deltas: 100% (14/14), done. 

    這時在 /home/josephj/www/ 會產生一個 .gitmodules 記錄你的 Submodule 資訊。該 git 的相關檔案也都會在此時被拉下來

  • 用 git status 看一下:
    $ git status # On branch master # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # new file: .gitmodules # new file: static/platform # 

    會發現它只列出 submodule 目錄而非所有底下檔案,parent git 實際上也只會記錄 submodule 的 commit id 以供未來做比對用。這裡一個很重要的點是大家必須理解的:parent git 與 submodule git 的關連性(被掛入的目錄、repository 位置)記錄在 .gitmodules 中,而版本控制則是靠 parent git 記住 submodule git 的 commit id。

  • 先 commit 一下:
    $ git add .gitmodules static/platform git commit -m "Add submodule into version control";
  • 但是你還必須做 init 的動作,你的 .git/config 才會有對應 submodule 的資訊。
    $ git submodule init 

更新已安裝的 Submodule

當初我第一次新增一個 Submodule 後,以為未來它都會像 SVN External 一樣、在我 git pull 的時候自動更新。但實際情況是你必須手動處理才能更新 Submodule

  1. 進入該目錄 Subomdule 目錄: $ cd static/platform
  2. 向來源的 master branch 做 git pull 的動作(這裡的 git pull 不會更新你 parent git 的檔案) $ git pull origin master
  3. 若 submodule 有更新的檔案,你可以到 parent git 觀看一下情況:
    $ cd ../../ $ git status # Not currently on any branch. # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: static/platform (new commits) # no changes added to commit (use "git add" and/or "git commit -a")

    與第一次 git submodule add 相同,submodule 更新的檔案並不會在 git status 中要求你 commit 喔!

  4. 我們前面提到,submodule 的版本控制在於 submodule git 的 commit id,上面看到 static/platform 有 new commit。表示你既然把新的內容 pull 回來、應該要更新 submodule 的 commit id 到你的 git 中:
    $ git add static/platform $ git commit -m "static/platform submodule updated"

    如此一來,新的 submodule commit id 就被你的 repositiory 給記錄下來囉!

團隊使用 Submodule

在一個多人的軟體開發團隊中,通常還是會有 Centralized Git Repositiory,像我們公司就採用了 gitosis 的解決方案。而像上述更新 Submodule 的情形,通常只有一兩個負責架構的人來做(大多是一開始把東西掛進來的人)、其他人只是單純使用者的角色,並不需要負責更新的工作

  1. 像上面我增加了一個 Submodule,對於團隊其他人來說,他們在下一次的 git pull 會看到以下的狀況:
    $ git status # On branch develop # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: static/platform (new commits) # no changes added to commit (use "git add" and/or "git commit -a")

    這表示其他人也會拿到 .gitmodules 的設定,但他必須使用 git submodule init 將新的 Submodule 註冊到自己的 .git/config、未來才能使用。

    $ git submodule init Submodule 'static/platform' (http://github.com/josephj/javascript-platform-yui.git) registered for path 'static/platform'
  2. 接著其他人使用 git submodule update 把該 Submodule 的內容全部拉下來!
    $ git submodule update Cloning into static/platform... remote: Counting objects: 34, done. remote: Compressing objects: 100% (34/34), done. remote: Total 34 (delta 15), reused 0 (delta 0) Unpacking objects: 100% (34/34), done. Submodule path 'static/platform': checked out '117c5b3c5a195deac2e53aa118b78ef3f01ae371' 

使用時機

簡單整理一下:

  • git submodule init: 在 .gitmodules 第一次被其他人建立或有新增內容的時候,用 git submodule init 更新你的 .git/config、設定目錄與增加 submodule 的 remote URL
  • git submodule update: 在 init 完有新的 submodule commit id 後就可以做了,會把所有相關檔案拉下來。若其他人更新 submodule 造成你拿到新的 commit id 時,你可以直接用 git submodule update 做更新即可、不需要做任何 add 或 commit 的動作!

可以想見,其他成員使用 git submodule update 的情況會遠比 git submodule init 多很多。

修改 Submodule 的內容

有時自己也是 Submodule 的 Owner,碰到要改 Code 時,要我切回原本的此 Git 開發位置有點麻煩… 不如就直接改被當成 Submodule 掛進來的原始碼吧

  1. 到 submodule 目錄去做些修改:
    $ cd static/platform $ vim README # 做些修改 
  2. 接著就是常見的 git add , git commit, git push
    $ git add README $ git commit -m "Add comments" $ git push 
  3. push 完回到根目錄git status 看一下!會看到
    $ git status # On branch master # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: static/platform # no changes added to commit (use "git add" and/or "git commit -a")
  4. 這裡也需要再做一次 Commit 喔!
    $ git add static/platform $ git commit -m 'Submodule updated' $ git push 

這裡有一點非常需要注意,因為 Submodule 的更新只記錄 commit id,所以你必須先在 submodule 內做 commit、push 後、再到 parent git 做 push,不然會出現版本錯亂的問題,別人跟你 submodule 的內容將會不一致。

如何移除 Submodule

這點也非常地不直覺,不是想像中 git submodule remove [欲移除的目錄] 這麼簡單…

  1. 先砍掉目錄:
    $ git rm --cached [欲移除的目錄] $ rm -rf [欲移除的目錄]
  2. 再修改 .gitmodules
    $ vim .gitmodules

    將相關內容移除

  3. 再修改 .git/config
    $ vim .git/config

    將相關內容移除

  4. 最後再 commit,改變整個 Repository。
    $ git add .gitmodules $ git commit -m "Remove a submodule" 
  5. 安全起見再做個 sync:
    $ git submodule sync

結語

我們公司目前主要將 Submodule 運用在與外包公司的合作上,因為彼此 Engineering 團隊負責的專案項目雖不同,但有部分的開發會需要在我們的結構下開目錄,我們也不希望他們改到我們的程式,此時 Git Submodule 提供了非常好的分工效果:把他們開發好的東西掛進來、更新即可。另有一點很重要的是, Git Submodule 內還可以將其他的 Submodule 給掛進來,形成一個巢狀式的結構,彈性非常地大。我們只要抓他們的大 Git 當 Submodule,下面怎麼掛就由外包公司決定。

整篇文章看下來,會發現 git submodule 的操作有許多需要注意的地方,像是更新、修改、刪除都要遵循一定的程序,不然你 PUSH 回 Central Repository 時,別人 PULL 下來的 Submodule 可能並不會更新,就會產生混亂了 Orz…

暇不掩瑜,Git Submodule 還是一個強大且團隊開發上非常重要的功能,就盡量使用前先搞懂、小心使用囉 ;)

Posted in Uncategorized

10 Cool Premium jQuery Countdown Scripts

Today’s post is a collection of 10 cool “premium” jQuery countdown scripts that you’d definitely find useful for your webpages at some point in time. Enjoy.

1. 5sec Maintenance Mode

6 beautiful, funny templates to make your visitors less angry while you’re offline.


5sec Maintenance Mode

Source
Demo

2. Premium Coming Soon – WordPress Plugin

New, modern, user friendly countdown page that lets your visitors know when you will launch your website. It has a custom countdown counter and the possibility to create an endless number of new themes as you please.


Premium Coming Soon

Source
Demo

3. Coming Soon Landing Page

JavaScript under construction website counter!


Coming Soon Landing Page

Source
Demo

4. fresh Parallax Under Construction Countdown

fresh Parallax Under Construction upgrades your “Coming Soon” page with a dynamic 3D cloudy sky with your logo or item of choice in focus.


fresh Parallax Under Construction

Source
Demo

5. FlipTimer

FlipTimer 1.2 with 8 color themes ready-made and a beautiful template with working contact form included.


FlipTimer

Source
Demo

6. Fancy Countdown – jQuery Plugin

It is a highly customizable jQuery plugin that lets you create an outstanding countdown. It´s very easy to use. You can set an own target date with a timezone. The plugin comes with an extensive API.


Fancy Countdown

Source
Demo

7. Countdown / Construction Page

Easy adaptable countdown, under construction – page. Including manual for easy set-up.


Countdown / Construction Page

Source
Demo

8. JavaScript Animated Counter

Simple, animated JavaScript counter, which will allow you to present rapidly increased or decreased values, such as number of registered users, total income etc.


JavaScript Animated Counter

Source
Demo

9. jsCountdown

Included are 14 different skins to choose from and a template file (png format) to make your own.


jsCountdown

Source
Demo

10. Live Broadcast Countdown Module

Nice jQuery based countdown timer. Header text depending on countdown stateus (counting down or finished). A lot of options available.


Live Broadcast Countdown

Source
Demo

Posted in Uncategorized

安装GitLab

一、准备工作
根据GitLab的官方文档要求,安装GitLab需要以下软件:
ruby 1.9.2
sqlite
ubuntu/debian
pygments lib – sudo pip install pygments
gitolite
因此在安装GitLab之前需要做一些准备工作。
1、设置安装环境(安装一些必要软件)
sudo apt-get update
sudo apt-get dist-upgrade -y
sudo apt-get install git-core openssh-server sendmail curl gcc libxml2-dev libxslt-dev sqlite3 libsqlite3-dev libcurl4-openssl-dev libreadline-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev python-setuptools
*安装VMWare Tools(这是在虚拟机环境下需要安装的,如果不是的可忽略)
sudo apt-get update -y
sudo apt-get dist-upgrade -y
sudo apt-get install dkms build-essential gcc linux-headers-$(uname -r) -y
sudo mkdir -p /media/cdrom
sudo mount /dev/cdrom /media/cdrom
cp /media/cdrom/VM* /tmp
sudo umount /media/cdrom
cd /tmp
tar -xzvf VMware*.gz
cd vmware-tools-distrib/
sudo ./vmware-install.pl -d
sudo apt-get autoremove -y
sudo shutdown -r now
上面关于虚拟机的部分是摘抄官网的,因为没环境测试,所以也只是原样照搬了。:)
2、设置专门的帐号
接下来我们需要创建一个专门的gitlabhq用户帐号来运行程序,这个帐户需要设置密码,因为需要将它加入到admin组来运行sudo:
sudo useradd -s /bin/bash -m -G admin gitlabhq
sudo passwd gitlabhq
现在使用gitlabhq用户帐号登录机器:
ssh gitlabhq@localhost
3、配置git全局变量并生成SSH密钥
git config –global user.email “admin@local.host”
git config –global user.name “GitLabHQ Admin User”
由于gitlabhq用户稍后要使用SSH密钥访问稍后创建git用户帐号,执行git命令,所以需要生成gitlabhq用户的SSH密钥:
ssh-keygen -t rsa
注意:在出现提示询问文件保存位置时直接回车,在要求输入和确认passphrase时也按回车。
4、安装Ruby 1.9.2、RubyGem和Rails
Ubuntu 11.10中的Ruby包,其版本是1.8的,所以需要安装包ruby1.9.2。由于在Ubuntu 11.10中的Ruby1.9.1包中ruby版本实际上是Ruby1.9.2,之所以包名为Ruby1.9.1是因为该版本为1.9.1的“库兼容版本”,所以可以直接安装包Ruby1.9.1即可,然后更新rubygem并安装rails。
sudo apt-get install ruby1.9.1-full
sudo update-alternatives –config ruby
sudo update-alternatives –config gem
sudo gem install rails
注意两点:1)、02-03行命令是在安装了其他ruby版本包时使用;2)、如果在安装rails时出现“RubyGems will revert to legacy indexes degrading performance.”之类的错误时,修改~/.gemrc文件后重试(有时要试多次才进行安装,一般来说都会3-6次之间,下面的bundle命令也是如此,不知道是不是伟大的墙在起作用,看你的运气了!):
vi ~/.gemrc

:backtrace: false
:benchmark: false
:bulk_threshold: 1000
:sources:
– http://gems.rubyforge.org/
– http://gems.github.com/
– http://gems.rubyonrails.org/
:update_sources: true
:verbose: true
5、安装和设置Gitolite
Gitolite 是一款 Perl 语言开发的 Git 服务管理工具,通过公钥对用户进行认证,并能够通过配置文件对写操作进行基于分支和路径的的精细授权,它是采用 SSH 协议并且使用 SSH 公钥认证的。Gitolite开始于 2009年8月,其作者当时是受到了 Gitosis 的启发,开发了这款功能更为强大和易于安装的软件。对于Gitolite的命名,作者原意是 Gitosis 和 lite 的组合,不过因为 Gitolite 的功能越来越强大,已经超越了 Gitosis,因此作者笑称 Gitolite 可以看作是 Github-lite —— 轻量级的 Github。
安装Gitolite也十分简单,首先添加git用户帐号并将其加入git组:
sudo adduser
–system
–shell /bin/sh
–gecos ‘git version control’
–group
–disabled-password
–home /home/git
git
sudo usermod -a -G git `eval whoami`
然后将生成的gitlabhq用户的公钥拷到git用户目录中:
sudo cp ~/.ssh/id_rsa.pub /home/git/rails.pub
接下来以git用户的名义将gitolite源文件下载的git用户家目录中:
sudo -u git -H git clone git://github.com/gitlabhq/gitolite ~git/gitolite
再以git用户的名义安装gitolite
sudo -u git -H /home/git/gitolite/src/gl-system-install
在这里该命令会提示关于目录的警告信息,不用理会。直接运行下列命令:
sudo -u git -H sh -c “PATH=/home/git/bin:$PATH; gl-setup ~/rails.pub”
在这里将会出现vim文本编辑器的编辑界面,请将其中的REPO_UMASK=0077改为REPO_UMASK=0007,然后保存退出(退出编辑状态ESC,然后使用:x)。关于如何在vim中编辑这里就不做说明了,我偷个懒,反正有谷歌和百度。:)
最后设置库目录的权限:
sudo chmod -R g+rwX ~git/repositories/
sudo chown -R git:git ~git/repositories/
OK,设置完了之后,重新进入一次gitlabhq用户,以使gitlabhq用户生效:
exit
ssh gitlabhq@localhost
二、安装和设置GitLab
1、安装GitLab
cd ~
git clone git://github.com/gitlabhq/gitlabhq.git ~/gitlabhq
cd gitlabhq
sudo easy_install pygments
sudo gem install bundler
sudo gem install linecache19 — –with-ruby-include=/usr/include/ruby-1.9.1/ruby/
bundle install –without development test
注意:linecache19的安装是必须要指定with-ruby-include参数的,否则将会在后面的bundle install中出错!
2、设置数据库
bundle exec rake db:setup RAILS_ENV=production
bundle exec rake db:seed_fu RAILS_ENV=production
注意:运行01行的rake db:setup语句时,如果出现“unititialized constant Rake::DSL”,则需要在GitLab根目录中的Rakefile文件中添加以下语句(参见http://stackoverflow.com /questions/6268518/uninitialized-constant-rakedsl-in-ruby-gem)来解决,如未出现上述出错信息,可忽略:
require ‘rake/dsl_definition’
require ‘rake’
3、配置GitLab
编辑GitLab的配置程序:
vi ~gitlabhq/gitlabhq/config/gitlab.yml
将下列内容
git_host:
system: gitolite
admin_uri: git@localhost:gitolite-admin
base_path: /home/git/repositories/
host: gitlab
git_user: git
# port: 22
修改为:
git_host:
system: gitolite
admin_uri: git@localhost:gitolite-admin
base_path: /home/git/repositories/
host: gitlabhq.your.domain
git_user: git
# port: 22
其中03和05行中的gitlabhq.your.domain是服务器的域名。
启动服务
cd ~gitlabhq/gitlabhq
bundle exec rails s -e production
三、测试服务
如果一切OK的话,就可以在浏览器上输入:http://server.ip:3000/ 来测试该服务了,使用以下信息登录:
Email: admin@local.host
Password: 5iveL!fe
接下来您可以在admin中创建一个新的用户,注意该用户在创建时要花费一段时间,请耐心等待。在该用户生成成功后,您需要按照前面的方法在客户机上生成该用户的密钥(Windows下可以使用Git for Windows中的Git Bash来代替):
ssh-keygen -t rsa -C “your_email@youremail.com”
然后用新用户登录,点击GitLab中My profile>Keys>Add new按钮,将生成的SSH公钥贴到弹出对话框的Key中,Title可随便填,我一般是使用用户_机器名这种格式,然后点击Save按钮。
在保存用户公钥之后,就可测试是否可以通过公钥来访问服务器上的git用户,执行git命令:
ssh -T git@gitlabhq.your.domain
其中,gitlabhq.your.domain是服务器的域名。如果出现”Agent admitted failure to sign using the key”错误,并提示输入git用户密码,那么请在客户机上使用以下命令将用户私钥加进来 (根据个人的密匙命名不同更改 id_rsa):
ssh-add ~/.ssh/id_rsa
ssh -T git@gitlabhq.your.domain
hello your_email_youremail_com_1324608633, this is gitolite v2.2-11-g8c4d1aa running on git 1.7.5.4 the gitolite config gives you the following access: @R_ @W_ testing
再次访问git,如出现类似02行信息时,则表明设置成功。
四、安裝和配置 Nginx和Passenger
1、卸载Apache2
sudo apt-get autoremove apache2*
sudo dpkg –purge apache2*
2、安装Nginx和Passenger模块
sudo gem install passenger
sudo passenger-install-ngnix-module
注意:02行语句会检查编译Ngnix和Passenger模块所需要的工具,然后询问你是否有Ngnix的源码,如果没有的话,就选1,会自动下载,如果有的话,就选2,并告之源码所在位置。在这里选择1。
3、创建运行Nginx服务的用户
sudo adduser –system –no-create-home –disabled-login –disabled-password –group nginx
4、将Nginx设置开机启动脚本
wget -O init-deb.sh http://library.linode.com/assets/660-init-deb.sh
sudo mv init-deb.sh /etc/init.d/nginx
sudo chmod +x /etc/init.d/nginx
sudo /usr/sbin/update-rc.d -f nginx defaults
5、将Nginx设置为GitLab的服务器
sudo vi /opt/nginx/conf/nginx.conf

user gitlabhq staff;
# —
server {
listen 80;
server_name gitlabhq.your.domain;
root /home/gitlabhq/gitlabhq/public;
passenger_enabled on;
}
# —
其中,07行的gitlab.yourdomain.com要改为你的域名。
6、启动Nginx
sudo /etc/init.d/nginx start
五、测试服务
在浏览器中输入http://gitlab.yourdomain.com/来测试GitLab能是否正常工作。如果一切正常的话,就可以打完收功了!

Posted in Uncategorized

What are the Options for Storing Hierarchical 分层 Data in a Relational Database?

Generally speaking you’re making a decision between fast read times (e.g. nested set) or fast write times (adjacency list). Usually you end up with a combination of the options below that best fit your needs. The following provides some in depth reading:

Options

Ones I am aware of and general features:

  1. Adjacency List:
    • Columns: ID, ParentID
    • Easy to implement.
    • Cheap node moves, inserts, and deletes.
    • Expensive to find level (can store as a computed column), ancestry & descendants (Bridge Hierarchy combined with level column can solve), path (Lineage Column can solve).
    • Use Common Table Expressions in those databases that support them to traverse.
  2. Nested Set (a.k.a Modified Preorder Tree Traversal)
    • First described by Joe Celko – covered in depth in his book Trees and Hierarchies in SQL for Smarties
    • Columns: Left, Right
    • Cheap level, ancestry, descendants
    • Compared to Adjacency List, moves, inserts, deletes more expensive.
    • Requires a specific sort order (e.g. created). So sorting all descendants in a different order requires additional work.
  3. Nested Intervals
    • Combination of Nested Sets and Materialized Path where left/right columns are floating point decimals instead of integers and encode the path information. In the later development of this idea nested intervals gave rise to matrix encoding.
  4. Bridge Table (a.k.a. Closure Table: some good ideas about how to use triggers for maintaining this approach)
    • Columns: ancestor, descendant
    • Stands apart from table it describes.
    • Can include some nodes in more than one hierarchy.
    • Cheap ancestry and descendants (albeit not in what order)
    • For complete knowledge of a hierarchy needs to be combined with another option.
  5. Flat Table
    • A modification of the Adjacency List that adds a Level and Rank (e.g. ordering) column to each record.
    • Expensive move and delete
    • Cheap ancestry and descendants
    • Good Use: threaded discussion – forums / blog comments
  6. Lineage Column (a.k.a. Materialized Path, Path Enumeration)
    • Column: lineage (e.g. /parent/child/grandchild/etc…)
    • Limit to how deep the hierarchy can be.
    • Descendants cheap (e.g. LEFT(lineage, #) = '/enumerated/path')
    • Ancestry tricky (database specific queries)

Database Specific Notes

MySQL

Oracle

PostgreSQL

SQL Server

  • General summary
  • 2008 offers HierarchyId data type appears to help with Lineage Column approach and expand the depth that can be represented.

Some articles from my blog on the subject:

Posted in Uncategorized

Gedit Keyboard Shortcuts

Shortcut keys enable you to perform tasks more quickly than if you use a mouse. The following tables list all of Gedit’s shortcut keys. These are in the Gedit user manualas of version 2.18.

Tabs

Shortcut Key Command
Ctrl + Alt + PageUp Switches to the next tab to the left.
Ctrl + Alt + PageDown Switches to the next tab to the right.
Ctrl + W Close tab.
Ctrl + Shift + L Save all tabs.
Ctrl + Shift + W Close all tabs.
Alt + n Jump to nth tab.

Files

Shortcut Key Command
Ctrl + N Create a new document.
Ctrl + O Open a document.
Ctrl + L Open a location.
Ctrl + S Save the current document to disk.
Ctrl + Shift + S Save the current document with a new filename.
Ctrl + P Print the current document.
Ctrl + Shift + P Print preview.
Ctrl + W Close the current document.
Ctrl + Q Quit Gedit.

Edit

Shortcut Key Command
Ctrl + Z Undo the last action.
Ctrl + Shift + Z Redo the last undone action .
Ctrl + X Cut the selected text or region and place it on the clipboard.
Ctrl + C Copy the selected text or region onto the clipboard.
Ctrl + V Paste the contents of the clipboard.
Ctrl + A Select all.

Edit (from GTKTextView)

Shortcut Key Command
Ctrl + D Delete the line.
Ctrl + Left Move the cursor to the beginning of the word or previous word if it’s already in the beginning of the current one.
Ctrl + Right Move the cursor to the end of the word or next word if it’s already in the end of the current one.

Panes

Shortcut Key Command
F9 Show/hide the side pane.
Ctrl + F9 Show/hide the bottom pane.
Shortcut Key Command
Ctrl + F Find a string.
Ctrl + G Find the next instance of the string.
Ctrl + Shift + G Find the previous instance of the string.
Ctrl + K Interactive search.
Ctrl + H Search and replace.
Ctrl + Shift + K Clear highlight.
Ctrl + I Goto line.

Tools

Shortcut Key Command
F7 Check spelling (with plugin).
Alt + F12 Remove trailing spaces (with plugin).
Ctrl + T Indent (with plugin).
Ctrl + Shift + T Remove Indent (with plugin).
F8 Run “make” in current directory (with plugin).
Ctrl + Shift + D Directory listing (with plugin).

Help

Shortcut Key Command
F1 Load Gedit’s online help document.
Posted in Uncategorized

python hashlib md5

#-*- coding:utf-8 -*-
from hashlib import md5
content = 12
content_str = str(content)
ciphertext = md5(content_str).hexdigest() #加密
print ciphertext

#from hashlib import md5
#ciphertext_str=raw_input() #写入要解密的密文,如827ccb0eea8a706c4c34a16891f84e7b
#MD5是不可逆的密码加密,可以说除了暴力破解外无法还原,但同样的输入加密出来的结果是一致的,因此要比较输入是否正确,只要比较一下加密后的结果即可,而Python中可以使用hashlib进行MD5加密,具体方法如下

for i in xrange(100000):
ciphertext_tmp = md5(str(i)).hexdigest()
if ciphertext_tmp == ciphertext:
print ‘the password is %d’ % i
break

python的base64加密解密及md5加密

import hashlib

a = “a test string”
print hashlib.md5(a).hexdigest()
print hashlib.sha1(a).hexdigest()
print hashlib.sha224(a).hexdigest()
print hashlib.sha256(a).hexdigest()
print hashlib.sha384(a).hexdigest()
print hashlib.sha512(a).hexdigest()

import base64
str=’haha’
encoded = base64.b64encode(str)
decoded = base64.b64decode(encoded)

 

 

Posted in Uncategorized

开源许可协议

1       目的

为了让开发人员能够正确合法的使用开源软件,避免因为不小心而触犯到相关法律法规,产生不必要的法律纠纷,现对开源界的几大开原协议进行了翻译和整理。

2       开源许可协议定义

自由软件/开源软件是自由的,免费的,源代码开放的,我们可自由下载安装和使用。同时,为了维护作者和贡献者的合法权利,保证这些软件不被一些商业机构或个人窃取,影响软件的发展,开源社区开发出了各种的开源许可协议。其中主要分三大类。

OSI-Approved Open Source:被开放源码组织(www.opensource.org)所批准的开放源码授权协议。如常见的Apache,GPL,LGPL,MIT Licence,都属于OSI-Approved的授权协议,OSI 的要求之一是二进制文件和源代码的自由发放。

Other/Proprietary License:其他的,私有的授权协议。指软件作者提供源代码,但是对软件的分发和发布有其他的限制。

Public Domain:公共域授权。将软件授权为公共域,表示作者完全放弃版权,任何人都可以随意使用。

大部分开源工程都属于OSI-Approved Open Source,下面对常见的License做简单的介绍。

3       开源许可协议介绍

3.1              GNU GPL

GNU有两种协议其中一种为 General Public Licence (GPL) ,该协议有可能是开源界最常用的许可模式。GPL 保证了所有开发者的权利,同时为使用者提供了足够的复制,分发,修改的权利。主要条款如下:

  1. 使用者可以将软件自由的复制到任何地方。
  2. 使用者可以以任何方式自由的分发,下载。注意分发的时候需要提供源代码和二进制文件。
  3. 使用者可以盈利,基于 GPL 的软件允许商业化销售,但不允许封闭源代码。
  4. 如果使用者对遵循 GPL 的软件进行任何改动和/或再次开发并予以发布,则使用者的产品必须继承 GPL 协议,不允许封闭源代码。

GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用,但不允许修改后和衍生的代码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux,包括商业公司的linux和linux上各种各样的由个人,组织,以及商 业软件公司开发的免费软件了。但对于使用GPL协议的开源代码,商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。GPL3.0详见附录4.1GPL3.0协议

3.2              GNU LGPL

GNU 还有另外一种协议,叫做LGPL(Lesser General Public Licence),它对产品所保留的权利比GPL少,总的来说,LGPL适合那些用于非GPL或非开源产品的开源类库或框架。因为GPL要求,使用了GPL代码的产品必须也使用GPL协议,开发者不允许将GPL代码用于商业产品。而LGPL绕过了这一限制。

  1. 基于LGPL的软件也允许商业化销售,但不允许封闭源代码。
  2. 如果您对遵循LGPL的软件进行任何改动和/或再次开发并予以发布,则您的产品必须继承LGPL协议,不允许封闭源代码。但是如果您的程序对遵循LGPL 的软件进行任何连接、调用而不是包含,则允许封闭源代码。

如果修改LGPL协议的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源代码很适合作为第三方类库被商业软件引用,但不适合希望以LGPL协议代码为基础,通过修改和衍生的方式做二次开发的商业软件采用。具体条款详见LGPL 2.1协议

3.3              BSD

BSD授权许可证(FreeBSD Copyright Information)具有多种授权许可证。其中BSD 在软件分发方面的限制比别的开源协议(如GNU GPL)要少。该协议有多种版本,最主要的版本有两个,新BSD协议与简单BSD协议,这两种协议经过修正,都和 GPL 兼容,并为开源组织所认可。简单BSD协议主要条款如下:

  1. 使用者可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。
  2. 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。
  3. 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
  4. 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。

新版(也称“三句版”)BSD许可证规定,只要软件的版权申明和许可证的免责条款得以保存,软件可以以任何目的不受限制地分发。该许可证还包含如下条款:即未经许可,不得以软件贡献者的名字为软件的衍生产品做代言。这一条款正是新版BSD许可证与简版BSD许可证之间的主要区别。

3.4              Apache license. 2.0

Apache Licence是著名的非盈利开源组织Apache采用的协议。Apache协议 2.0和别的开源协议相比,除了为用户提供版权许可之外,还有专利许可,对于那些涉及专利内容的开发者而言,该协议最适合。以下为Apache Licence的详细介绍:

  1. 需要授予使用代码的用户一份Apache Licence。一旦被授予许可,使用者可以无限期的使用。
  2. 如果使用者修改了代码,需要再被修改的文件中说明。
  3. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。
  4. 如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。

以下是该授权关于对工作中使用的说明和限制:

如果在工作中需要应用该授权,请附上如下样板式说明,以[]围起来,来替换你自己的说明信息。(不要包含括弧)文本通常被适当的文件语法格式所包围。我们也建议,一个文件或者类名和特定目的的描述,一起被包含在印刷页上,该印刷页作为一个简单的第三方文档授权证明。下为授权的文档格式。

 知识共享许可协议
dreamcamp by Francis Jiang is licensed under a Creative Commons 署名-非商业性使用-相同方式共享 3.0 Unported License.
基于github.com上的作品创作。

 

## License
(The MIT License)

Copyright © 2009-2012 Francis Jiang

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#### If you want to be awesome.
– Proudly display the ‘Powered by Francis Jiang’ credit in the footer.
– Add your site to the wiki so we can watch the communi

3.5    MIT许可协议(MIT License)

在所有常用的开源许可协议中,MIT许可协议最为简短,可能也最为广泛。它的条款非常松散,比起大部分其它许可协议来说更加宽松。其基本条款如下:

  1. 使用者可以随意使用,复制,修改这个软件。没有人能够阻止你在任何工程里使用它,你可以复制任意次数、以任何形式,或按你的愿望修改它。
  2. 使用者可以向外免费发放,或出售。你可以随意的分发它,没有任何限制。
  3. 唯一的限制是使用者必须接受协议条款。即软件必须附带版权和许可协议。
  4. MIT 协议是目前最少限制的协议。它基本上就是任何人可以对这个协议下的软件的做任何的事情,只要你能认可这个协议。

3.6    知识共享协议

知识共享(Creative Commons,简称CC)许可协议并非完全的开源许可协议,但设计类项目也常常使用。有各种不同的CC许可协议可供使用,每种授予特定的权利。一个CC许可证包含四个基本部分,每部分即可单独生效,又可联合使用。简述如下:

  1. 署名,使用者必须按照作者指定的方式对作品进行署名。除此之外,作品可被复制、分发、拷贝以及以其它方式使用。
  2. 相同方式共享,即只能基于相同的CC许可证对作品进行修改、分发等。
  3. 非商业性,作品可被修改、分发等,但不得以商业为目的进行。关于什么构成商业行为,许可证条款并未提供清晰的定义,因此使用者可能需要在自己的项目里给予澄清。比如说,有人认为“非商业”只是简单地意味着你不能出售作品,也有人认为你不能把作品放到一个带广告的网站上,还有人认为只有当牟利发生时才能称为“商业”。
  4. 禁止衍生,即使用者可以拷贝和分发授权作品,但不得以任何方式修改、或基于原作进行创作。

如上所述,CC许可证的各个部分可以联合使用。最为严格的许可证为“署名-非商业-禁止衍生”许可证,即使用者可以自由分享作品,但不得修改或收费,同时必须按照作者指定的方式为作品署名。这对那些一方面希望发布作品,另一方面又希望多多少少保留对作品使用方式的控制权的作者来说,颇为不错。限制最少的CC许可证是“署名”许可证,即只要按照作者指定的方式为作品署名,就可以用作品做任何事。

CC许可证在设计类作品中的应用要比在开发中的应用多,但并没有限制你在开发中使用它,只是要清楚各部分条款的细节。

3.7    CPL(Common Public Liecense) vesion 1.0

CPL是IBM 提出的并通过了OSI(Open Source Initiative)批准的开源协议。主要用于一些IBM或跟IBM相关的开源软件 /项目中。如很著名的Java开发环境Eclipse、RIA开发平台Open Laszlo等。

CPL也是一项对商业应用友好的协议。它允许使用者对源码进行任意的使用、复制、分发、传播、展示、修改以及改后做闭源的二次商业发布,这点跟BSD 很类似,也属于自由度比较高的开源协议。但是,需要遵循以下条款:

  1. 当使用者将源码的整体或部分再次开源发布的时候,必须继续遵循CPL 开源协议来发布,而不能改用其他协议发布。除非你得到了原“源码”Owner 的 授权。
  2. CPL协议下,使用者可以将源码不做任何修改来商业发布。但如果要将修改后的源码开源,而且当你再发布的是ObjectCode 的时候,你必须声明它的Source Code是可以获取的,而且要告知获取方法。
  3. 当使用者需要将 CPL 下的源码作为一部分跟其他私有的源码混和着成为一个项目发布的时候,可以将整个项目/产品以私人的协议发布,但要声明哪一部分代码是CPL下的,而且声明那部分代码继续遵循CPL。独立的模块(Separate Module),不需要开源。

3.8              MPL协议

MPL是The Mozilla Public License的简写,是1998年初Netscape的 Mozilla小组为其开源软件项目设计的软件许可证。MPL许可证出现的最重要原因就是,Netscape公司认为GPL许可证没有很好地平衡开发者对源代码的需求和他们利用源代码获得的利益。同著名的GPL许可证和BSD许可证相比,MPL在许多权利与义务的约定方面与它们相同(因为都是符合OSIA认定的开源软件许可证)。但是,相比而言MPL还有以下几个显著的不同之处:

  1. MPL允许免费重发布、免费修改,但要求修改后的代码版权归软件的发起者。这种授权维护了商业软件的利益,它要求基于这种软件得修改无偿贡献版权给该软件。这样,围绕该软件得所有代码得版权都集中在发起开发人得手中。但MPL是无偿使用得。MPL软件对链接没有要求。
  2. MPL要求对于经MPL许可证发布的源代码的修改也要以MPL许可证的方式再许可出来,以保证其他人可以在MPL的条款下共享源代码。但是,在MPL许可证中对“发布”的定义是“以源代码方式发布的文件”,这就意味着MPL允许一个企业在自己已有的源代码库上加一个接口,除了接口程序的源代码以MPL许可证的形式对外许可外,源代码库中的源代码就可以不用MPL许可证的方式强制对外许可。这些,就为借鉴别人的源代码用做自己商业软件开的行为留了一个豁口。
  3. MPL许可证第三条第7款中允许使用者将经过MPL许可证获得的源代码同自己其他类型的代码混合得到自己的软件程序。
  4. 对软件专利的态度,MPL许可证不像GPL许可证那样明确表示反对软件专利,但是却明确要求源代码的提供者不能提供已经受专利保护的源代码(除非他本人是专利权人,并书面向公众免费许可这些源代码),也不能在将这些源代码以开放源代码许可证形式许可后再去申请与这些源代码有关的专利。
  5. MPL许可证第3条有专门的一款是关于对源代码修改进行描述的规定,就是要求所有再发布者都得有一个专门的文件就对源代码程序修改的时间和修改的方式有描述。

3.9              CDDL协议

CDDL全称Common Development and Distribution License.它是一个开源许可证书,采用著名的Mozilla公共许可证(MPL),使其在未做任何改动的情况下可重用。CDDL满足 Open Source Definition 的要求并且已经获得开放源码促进会的认可作为开放源代码的许可证。

  1. MPL作为CDDL的基础。除了保留所有所希望的MPL特性以外(参考前面),CDDL许可证被设计成可重用的,并做了一些改进使其更加通用。
  2. 对于任何遵守CDDL许可的源文件,以及使用者所做的任何修改都需要共享。但是不必将私有源文件共享。
  3. CDDL为在此许可下发布的代码提供了清楚的专利许可。这意味着使用者可以使用、修改并且重新发布CDDL授权的代码而不需要担心代码开发者(包括Sun)的任何技术专利。许可证同时包括了一项条款如果有任何人因为他们所提供的代码而对一个开发者进行专利起诉的话,该条款通过废除代码所有权来阻止任何对于开发者的专利指控。
  4. 可以修改,然后遵守CDDL许可将代码重新发布,并可以进行收费。但是,需要遵循CDDL的条款,包括遵守CDDL许可将修改的代码共享。

4       附录

4.1     GPL3.0协议

4.1.1    导言

GNU通用公共授权是一份针对软件和其他种类作品的自由的、公共的授权文件。

大多数软件授权申明被设计为剥夺您共享和修改软件的自由。相反地,GNU通用公共授权力图保护您分享和修改自由软件地自由——以确保软件对所有使用者都是自由的。我们,自由软件基金会,对我们的大多数软件使用GNU通用公共授权;本授权同样适用于任何其作者以这种方式发布的软件。您也可以让您的软件使用本授权。

当我们谈论自由软件时,我们指的是行为的自由,而非价格免费。GNU通用公共授权被设计为确保您拥有发布自由软件副本(以及为此收费,如果您希望的话)的自由,确保您能收到源代码或者在您需要时能获取源代码,确保您能修改软件或者将它的一部分用于新的自由软件,并且确保您知道您能做这些事情。

为了保护您的权利,我们需要做出要求,禁止任何人否认您的这些权利或者要求您放弃这些权利。因此,如果您发布此软件的副本或者修改它,您就需要肩负起尊重他人自由的责任。

例如,如果您发布自由软件的副本,无论以免费还是以收费的模式,您都必须把您获得的自由同样的给予副本的接收者。您必须确保他们也能收到或者得到源代码。而且您必须向他们展示这些条款,以使他们知道自己享有这样的权利。

使用GNU通用公共授权的开发者通过两项措施来保护您的权利:(1)声明软件的版权;(2)向您提供本授权文件以给您复制、发布并且/或者修改软件的法律许可。

为了保护软件开发者和作者,通用公共授权明确阐释自由软件没有任何担保责任。如用户和软件作者所希望的,通用公共授权要求软件被修改过的版本必须明确标示,从而避免它们的问题被错误地归咎于先前的版本。

某些设备被设计成拒绝用户安装或运行其内部软件的修改版本,尽管制造商可以安装和运行它们。这从根本上违背了通用公共授权保护用户能修改软件的自由的宗旨。此类滥用本授权的系统模式出现在了最让人无法接受的个人用户产品领域。因此,我们设计了这个版本的通用公共授权来禁止那些产品的侵权行为。如果此类问题在其他领域大量出现,我们准备好了在将来的通用公共授权版本里扩展这项规定,以保护用户的自由。

最后,每个程序都经常受到软件专利的威胁。政府不应该允许专利权限制通用计算机软件的发展和使用,但是在政府确实允许这种事情的地区,我们希望避免应用于自由软件的专利权使该软件有效私有化的危险。为了阻止这样的事情的发生,通用公共授权确保没有人能够使用专利权使得自由软件非自由化。

以下是复制,发布和修改软件的详细条款和条件。

4.1.2    条款和条件

4.1.2.1 定义

“本授权”指GNU通用公共授权第三版。

“版权”一词同样指适用于其他产品如半导体防护罩等的保护版权的法律。

“本程序”指任何在本授权下发布的受版权保护的作品。被授权人称为“您”。“被授权人”和“版权接受者”可以是个人或组织。

“修改”作品是指从软件中拷贝或者做出全部或一丁点儿的修改,这不同于逐字逐句的复制,是需要版权许可的。修改成果被称为先前作品的“修改版本”或者“基于”先前作品的软件。

“覆盖程序”指未被修改过的本程序或者基于本程序的程序。

“传播”程序指使用该程序做任何如果没有许可就会在适用的版权法下直接或间接侵权的事情,不包括在电脑上执行程序或者是做出您不与人共享的修改。传播包括复制,分发(无论修改与否),向公众共享,以及在某些国家的其他行为。

“发布”作品指任何让其他组织制作或者接受副本的传播行为。仅仅通过电脑网络和一个用户交流,且没有发送程序拷贝的行为不是发布。

一个显示“适当的法律通告”的交互的用户接口应包括这样一个方便而显著的可视部件,它具有以下功能:(1)显示一个合适的版权通告;(2)告诉用户对本程序没有任何担保责任(除非有担保明确告知),受权人可以在本授权下发布本程序,以及如果阅读本授权协议的副本。如果该接口显示了一个用户命令或选项列表,比如菜单,该列表中的选项需要符合上述规范。

4.1.2.2  源代码

“源代码”指修改程序常用的形式。“目标代码”指程序的任何非源代码形式。

“标准接口”有两种含义,一是由标准组织分支定义的官方标准;二是针对某种语言专门定义的众多接口中,在该类语言的开发者中广为使用的那种接口。

可执行程序的“系统库”不是指整个程序,而是指任何包含于主要部件但不属于该部件的部分,并且只是为了使能该部件而开发,或者为了实现某些已有公开源代码的标准接口。“主要部件”在这里指的是执行程序的特定操作系统(如果有的话)的主要的关键部件(内核,窗口系统等),或者生成该可执行程序时使用的编译器,或者运行该程序的目标代码解释器。

目标代码中的程序“对应的源代码”指所有生成,安装,(对可执行程序而言)运行该目标代码和修改该程序所需要的源代码,包括控制这些行为的脚本。但是,它不包括程序需要的系统库,通用目的的工具,以及程序在完成某些功能时不经修改地使用的那些不包括在程序中的普遍可用的自由软件。例如,对应的源代码包括与程序的源文件相关的接口定义文件,以及共享库中的源代码和该程序设计需要的通过如频繁的数据交互或者这些子程序和该程序其他部分之间的控制流等方式获得的动态链接子程序。

对应的源代码不需要包含任何拥护可以从这些资源的其他部分自动再生的资源。

源代码形式的程序对应的源代码定义同上。

4.1.2.3 基本的许可

所有在本授权协议下授予的权利都是对本程序的版权而言,并且只要所述的条件都满足了,这些授权是不能收回的。本授权明确的确认您可以不受任何限制地运行本程序的未修改版本。运行一个本授权覆盖的程序获得的结果只有在该结果的内容构成一个覆盖程序的时候才由本授权覆盖。本授权承认您正当使用或版权法规定的其它类似行为的权利。

只要您的授权仍然有效,您可以无条件地制作,运行和传播那些您不发布的覆盖程序。只要您遵守本授权中关于发布您不具有版权的资料的条款,您可以向别人发布覆盖程序,以要求他们为您做出专门的修改或者向您提供运行这些程序的简易设备。那些为您制作或运行覆盖程序的人作为您专门的代表也必须在您的指示和控制下做到这些,请禁止他们在他们和您的关系之外制作任何您拥有版权的程序的副本。当下述条件满足的时候,在任何其他情况下的发布都是允许的。转授许可证授权是不允许的,第10节让它变的没有必要了。

4.1.2.4 保护用户的合法权利不受反破解法侵犯

在任何实现1996年通过的世界知识产权组织版权条约第11章中所述任务的法律,或者是禁止或限制这种破解方法的类似法律下,覆盖程序都不会被认定为有效的技术手段的一部分。

当您发布一个覆盖程序时,您将放弃任何禁止技术手段破解的法律力量,甚至在本授权关于覆盖程序的条款下执行权利也能完成破解。同时,您放弃任何限制用户操作或修改该覆盖程序以执行您禁止技术手段破解的合法权利的企图。

4.1.2.5 发布完整副本

你可以通过任何媒介发布本程序源代码的未被修改过的完整副本,只要您显著而适当地在每个副本上发布一个合适的版权通告;保持完整所有叙述本授权和任何按照第7节加入的非许可的条款;保持完整所有的免责申明;并随程序给所有的接受者一份本授权。

您可以为您的副本收取任何价格的费用或者免费,你也可以提供技术支持或者责任担保来收取费用。

4.1.2.6 发布修改过的源码版本

您可以在第4节的条款下以源码形式发布一个基于本程序的软件,或者从本程序中制作该软件需要进行的修改,只要您同时满足所有以下条件:

  1. 制作的软件必须包含明确的通告说明您修改了它,并给出相应的修改日期。
  2. 制作的软件必须包含明确的通告,陈述它在本授权下发布并指出任何按照第7节加入的条件。这条要求修改了第4节的“保持所有通知完整”的要求。
  3. 您必须把整个软件作为一个整体向任何获取副本的人按照本授权协议授权。本授权因此会和任何按照第7节加入的条款一起,对整个软件及其所有部分,无论是以什么形式打包的,起法律效力。本授权不允许以其他任何形式授权该软件,但如果您个别地收到这样的许可,本授权并不否定该许可。
  4. 如果您制作的软件包含交互的用户接口,每个用户接口都必须显示适当的法律通告;但是,如果本程序包含没有显示适当的法律通告的交互接口,您的软件没有必要修改他们让他们显示。如果一个覆盖程序和其他本身不是该程序的扩展的程序的联合体,这样的联合的目的不是为了在某个存储或发布媒体上生成更大的程序,且联合体程序和相应产生的版权没有用来限制程序的使用或限制单个程序赋予的联合程序的用户的合法权利的时候,这样的联合体就被称为“聚集体”。在聚集体中包含覆盖程序并不会使本授权应用于该聚集体的其他部分。

4.1.2.7 发布非源码形式的副本

您可以在第4,5节条款下以目标代码形式发布程序,只要您同时以一下的一种方式在本授权条款下发布机器可读的对应的源代码:

  1. 在物理产品(包括一个物理的发布媒介)中或作为其一部分发布目标代码,并在通常用于软件交换的耐用的物理媒介中发布对应的源代码。
  2. 在物理产品(包括一个物理的发布媒介)中或作为其一部分发布目标代码,并附上有效期至少3年且与您为该产品模型提供配件或客户服务的时间等长的书面承诺,给予每个拥有该目标代码的人(1)要么在通常用于软件交换的耐用物理媒介中,以不高于您执行这种源码的发布行为所花费的合理费用的价格,一份该产品中所有由本授权覆盖的软件的对应的源代码的拷贝;(2)要么通过网络服务器免费提供这些对应源代码的访问。
  3. 单独地发布目标代码的副本,并附上一份提供对应源代码的书面承诺。这种行为只允许偶尔发生并不能盈利,且在您收到的目标代码附有第6节b规定的承诺的时候。
  4. 在指定的地点(免费或收费地)提供发布的目标代码的访问并在同样的地点以不增加价格的方式提供对应源代码的同样的访问权。您不需要要求接收者在复制目标代码的时候一道复制对应的源代码。如果复制目标代码的地点是网络服务器,对应的源代码可以在另外一个支持相同复制功能的服务器上(由您或者第三方运作),只要您在目标代码旁边明确指出在哪里可以找到对应的源代码。无论什么样的服务器提供这些对应的源代码,您都有义务保证它在任何有需求的时候都可用,从而满足本条规定。
  5. 用点对点传输发布目标代码,您需要告知其他的节点目标代码和对应的源代码在哪里按照第6节d的条款向大众免费提供。

目标代码中可分离的部分,其源代码作为系统库不包含在对应的源代码中,不需要包含在发布目标代码的行为中。

“用户产品”指(1)“消费品”,即通常用于个人的、家庭的或日常目的的有形个人财产;或者(2)任何为公司设计或销售却卖给了个人的东西。在判断一个产品是否消费品时,有疑点的案例将以有利于覆盖面的结果加以判断。对特定用户接收到的特定产品,“正常使用”指该类产品的典型的或通常的使用,无论该用户的特殊情况,或者该用户实际使用该产品的情况,或者该产品要求的使用方式如何。一个产品是否是消费品与该产品是否具有实质的经济上的、工业的或非消费品的用处无关,除非该用处是此类产品唯一的重要使用模式。

用户产品的“安装信息”指从对应源码的修改版本安装和运行该用户产品中包含的覆盖程序的修改版本所需要的任何方法、过程、授权密钥或其他信息。这些信息必须足以保证修改后的目标代码不会仅仅因为被修改过而不能继续运行。

如果您在本节条款下在用户产品中,或随同,或专门为了其中的使用,发布目标代码程序,而在发布过程中用户产品的所有权和使用权都永久地或在一定时期内(无论此项发布的特点如何)传递给了接收者,在本节所述的条款下发布的对应的源代码必须包含安装信息。但是如果您或者任何第三方组织都没有保留在用户产品上安装修改过的目标代码的能力(比如程序被安装在了ROM上),那么这项要求不会生效。

提供安装信息的要求并没有要求为接收者修改或安装过的程序,或者修改或安装该程序的用户产品,继续提供支持服务、担保或升级。当修改本身实际上相反地影响了网络的运行,或者违反了网络通信的规则和协议时,网络访问可以被拒绝。

根据本节发布的对应源代码和提供的安装信息必须以公共的文件格式发布(并附加一个该类型文档的实现方法以源码形式向公众共享),解压缩、阅读或复制这些信息不能要求任何密码。

4.1.2.8 附加条款

“附加许可”是通过允许一些本授权的特例来补充本授权的条款。只要它们在使用法律下合法,对整个程序都生效的附加许可就应当被认为是本授权的内容。如果附加许可只是对本程序的一部分生效,那么该部分可以在那些许可下独立使用,但整个程序是在本授权管理下,无论附加许可如何。

当您发布覆盖程序的副本时,您可以选择删除该副本或其部分的任何附加许可。(当您修改程序时,附加许可可能要求在某些情况下将自身删除)。您可以把附加许可放在材料上,加入到您拥有或能授予版权许可的覆盖程序中。

尽管本授权在别处有提供,对于您加入到程序中的材料,您可以(如果您由该材料的版权所有者授权的话)用以下条款补充本授权:

  1. 拒绝担保责任或以与本授权第15和16小节条款不同的方式限制责任;
  2.  要求保留特定的合理法律通告,或者该材料中或包含于适当法律通告中的该程序的作者贡献;
  3. 禁止误传该材料的来源,或者要求该材料的修改版本以合理的方式标志为与原版本不同的版本;
  4. 限制以宣传为目的的使用该材料作者或授权人的姓名;
  5. 降低授权级别以在商标法下使用一些商品名称,商标或服务标记;
  6. 要求任何发布该材料(或其修改版本)的人用对接收者的责任假设合同对授权人和材料作者进行保护,避免任何这样的假设合同直接造成授权人和作者的责任。

所有其他不许可的附加条款都被认为是第10节中的“进一步的约束”。如果您收到的程序或者其部分,声称自己由本授权管理,并补充了进一步约束,那么您可以删除这些约束。如果一个授权文件包含进一步约束,但是允许再次授权或者在本授权下发布,只要这样的进一步的约束在这样的再次授权或发布中无法保留下来,您就可以在覆盖程序中加入该授权文件条款管理下的材料。

如果您依据本小节向覆盖程序添加条款,您必须在相关的源码文件中加入一个应用于那些文件的附加条款的声明或者指明在哪里可以找到这些条款的通告。

附加的条款,无论是许可的还是非许可的条款,都可以写在一个单独的书面授权中,或者申明为例外情况;这两种方法都可以实现上述要求。

4.1.2.9 终止授权

您只有在本授权的明确授权下才能传播或修改覆盖程序。任何其它的传播或修改覆盖程序的尝试都是非法的,并将自动终止您在本授权下获取的权利(包括依据第11节第三段条款授予的任何专利授权)。

然而,如果您停止违反本授权,那么您从某个特定版权所有者处获取的授权许可能够以以下方式恢复(a)您可以暂时地拥有授权,直到版权所有者明确地终止您的授权;(b)如果在您停止违反本授权后的60天内,版权所有者没有以某种合理的方式告知您的违背行为,那么您可以永久地获取该授权。

进一步地,如果某个版权所有者以某种合理的方式告知您违反本授权的行为,而这是您第一次收到来自该版权所有者的违反本授权的通知(对任何软件),并且在收到通知后30天内修正了违反行为,那么您从该版权所有者处获取的授权将永久地恢复。

当您的授权在本节条款下被终止时,那些从您那获取授权的组织只要保持不违反本授权协议,其授权就不会被终止。您只有在授权被版权所有者恢复了之后才有资格依据第10节的条款获取该材料的新的授权。

4.1.2.10         获取副本不需要接受本授权

您不需要为了接收或运行本程序的副本而接受本授权协议。仅仅是因为点对点传输获取副本引起传播行为,也不要求您接受本授权协议。然而,除了本授权外,任何授权协议都不能授予您传播或修改覆盖程序的许可。因此,如果您修改或者传播了本程序的副本,那么您就默认地接受了本授权。

4.1.2.11         下游接收者的自动授权

每次您发布覆盖程序,接收者都自动获得一份来自原授权人的依照本授权协议运行、修改和传播该程序的授权。依据本授权,您不为执行任何第三方组织的要求负责。

“实体事务”指转移一个组织的控制权或全部资产,或者拆分组织,或者合并组织的事务。如果覆盖程序的传播是实体事务造成的,该事务中每一个接收本程序副本的组织都将获取一份其前身拥有的或者能够依据前面的条款提供的任何授权,以及从其前身获取程序对应的源代码的权利,如果前身拥有或以合理的努力能够获取这些源代码的话。

您不可以对从本授权协议获取或确认的权利的执行强加任何约束。比如,您不可以要求授权费用,版税要求或对从本授权获取的权利的执行收取任何费用。您不可以发起诉讼(包括联合诉讼和反诉)声称由于制作、使用、销售、批发或者引进本程序或其任何一部分而侵犯了任何专利权。

4.1.2.12         专利权

“贡献者”是在本授权下授予本程序或者本程序所基于的程序的使用权的版权所有者。这样的程序被成为贡献者的“贡献者版本”。

一个贡献者的“实质的专利申明”是该贡献者所占有和控制的全部专利,无论已经获得的还是在将来获得的,那些可能受到某种方式侵犯的专利权。本授权允许制作、使用和销售其贡献者版本,但不包括那些只会由于对贡献者版本进一步的修改而受到侵犯的专利的申明。为此,“控制”一词包括以同本授权要求一致的方式给予从属授权的权利。

每个贡献者在该贡献者的实质的专利申明下授予您非独家的,全世界的,不需要版税的专利授权,允许您制作、使用、销售、批发、进口以及运行、修改和传播其贡献者版本内容。

在以下三个自然段中,“专利授权”指任何形式表达的不执行专利权的协议或承诺(例如使用专利权的口头许可,或者不为侵犯专利而起诉的契约)。向一个组织授予专利授权指做出这样的不向该组织提出强制执行专利权的承诺。

如果您在自己明确知道的情况下发布基于某个专利授权的覆盖程序,而这个程序的对应的源代码并不能在本授权条款下通过网络服务器或其他有效途径免费地向公众提供访问,您必须做到:(1)使对应的源代码按照上述方法可访问;或者(2)放弃从该程序的专利授权获取任何利益;或者(3)以某种与本授权要求一致的方法使该专利授权延伸到下游的接收者。“在自己明确知道的情况下”指您明确地知道除了获取专利授权外,在某个国家您传播覆盖程序的行为,或者接收者使用覆盖程序的行为,会由于该专利授权而侵犯一个或多个在该国可确认的专利权,而这些专利权您有足够的理由相信它们是有效的。

在依照或者涉及某一次事务或安排时,如果您通过获取发布或传播覆盖程序的传输版本,并给予接收该覆盖程序的某些组织专利授权,允许他们使用,传播,修改或者发布该覆盖程序的特殊版本,那么您赋予这些组织的专利授权将自动延伸到所有该覆盖程序及基于该程序的作品的接收者。

一份专利授权是“有偏见的”,如果它没有在自身所覆盖的范围内包含,禁止行使,或者要求不执行一个或多个本授权下明确认可的权利。以下情况,您不可以发布一个覆盖程序:如果您与软件发布行业的第三方组织有协议,而该协议要求您根据该程序的发布情况向该组织付费,同时该组织在你们的协议中赋予任何从您那里获得覆盖软件的组织一份有偏见的专利授权,要么(a)连同您所发布的副本(或者从这些副本制作的副本);要么(b)主要为了并连同某个的产品或者包含该覆盖程序的联合体。如果您签署该协议或获得该专利授权的日期早于2007年3月28日,那么您不受本条款约束。

本授权的任何部分不会被解释为拒绝或者限制任何暗含的授权或其他在适用专利权法下保护您的专利不受侵犯的措施。

4.1.2.13         不要放弃别人的自由

如果您遇到了与本授权向矛盾的情况(无论是法庭判决,合同或者其他情况),它们不能使您免去本授权的要求。如果您不能同时按照本授权中的义务和其他相关义务来发布覆盖程序,那么您将不能发布它们。比如,如果您接受了要求您向从您这里或许本程序的人收取版税的条款,您唯一能够同时满足本授权和那些条款的方法是完全不要发布本程序。

4.1.2.14         和GNU Affero通用公共授权一起使用

尽管本协议有其他防备条款,您有权把任何覆盖程序和基于第三版GNU Affero通用公共授权的程序链接起来,并且发布该联合程序。本授权的条款仍然对您的覆盖程序有效,但是GNU Affero通用公共授权第13节关于通过网络交互的要求会对整个联合体有效。

4.1.2.15         本授权的修订版

自由软件基金会有时候可能会发布GNU通用软件授权的修订版本和/或新版本。这样的新版本将会和现行版本保持精神上的一致性,但是可能会在细节上有所不同,以处理新的问题和情况。

每个版本都有一个单独的版本号。如果本程序指出了应用于本程序的一个特定的GNU通用公共授权版本号“以及后续版本”,您将拥有选择该版本或任何由自由软件基金会发布的后续版本中的条款和条件的权利。如果本程序没有指定特定的GNU通用公共授权版本号,那么您可以选择任何自由软件基金会已发布的版本。

如果本程序指出某个代理可以决定将来的GNU通用公共授权是否可以应用于本程序,那么该代理的接受任何版本的公开称述都是您选择该版本应用于本程序的永久认可。

后续的授权版本可能会赋予您额外的或者不同的许可。但是,您对后续版本的选择不会对任何作者和版权所有者强加任何义务。

4.1.2.16         免责申明

在适用法律许可下,本授权不对本程序承担任何担保责任。除非是书面申明,否则版权所有者和/或提供本程序的第三方组织,“照旧”不承担任何形式的担保责任,无论是承诺的还是暗含的,包括但不限于就适售性和为某个特殊目的的适用性的默认担保责任。有关本程序质量与效能的全部风险均由您承担。如本程序被证明有瑕疵,您应承担所有必要的服务、修复或更正的费用。

4.1.2.17         责任范围

除非受适用法律要求或者书面同意,任何版权所有者,或任何依前述方式修改和/或发布本程序者,对于您因为使用或不能使用本程序所造成的一般性、特殊性、意外性或间接性损失,不负任何责任(包括但不限于,资料损失,资料执行不精确,或应由您或第三人承担的损失,或本程序无法与其他程序运作等),即便该版权所有者或其他组织已经被告知程序有此类损失的可能性也是如此。

4.1.2.18         第15和16节的解释

如果上述免责申明和责任范围不能按照地方法律条款获得法律效力,复审法庭应该采用最接近于完全放弃关于本程序的民事责任的法律,除非随同本程序的责任担保或责任假设合同是收费的。

4.1.3    如何在您的新程序中应用这些条款?

如果您开发了一个新程序,并且希望能够让它尽可能地被大众使用,达成此目的的最好方式就是让它成为自由软件。任何人都能够依据这些条款对该软件再次发布和修改。

为了做到这一点,请将以下声明附加到程序上。最安全的作法,是将声明放在每份源码文件的起始处,以有效传达无担保责任的讯息;且每份文件至少应有「版权」列以及本份声明全文位置的提示。

<用一行描述程序的名称与其用途简述>

版权所有(C) <年份><作者姓名>

本程序为自由软件;您可依据自由软件基金会所发表的GNU通用公共授权条款,对本程序再次发布和/或修改;无论您依据的是本授权的第三版,或(您可选的)任一日后发行的版本。

本程序是基于使用目的而加以发布,然而不负任何担保责任;亦无对适售性或特定目的适用性所为的默示性担保。详情请参照GNU通用公共授权。

您应已收到附随于本程序的GNU通用公共授权的副本;如果没有,请参照<http://www.gnu.org/licenses/>.同时附上如何以电子及书面信件与您联系的资料。

如果程序进行终端交互方式运作,请在交互式模式开始时,输出以下提示:

<程序> 版权所有(C) <年份> <作者姓名>

本程序不负任何担保责任,欲知详情请键入’show w’。

这是一个自由软件,欢迎您在特定条件下再发布本程序;欲知详情请键入’show c’。

所假设的指令’show w’与’show c’应显示通用公共授权的相对应条款。当然,您可以使用’show w’与’show c’以外的指令名称;对于图形用户界面,您可以用“关于”项代实现此功能。

如有需要,您还应该取得您的雇主(若您的工作为程序设计師)或学校就本程序所签署的“版权放弃承诺书”。欲知这方面的详情,以及如何应用和遵守GNU通用公共授权,请参考<http://www.gnu.org/licenses/>

GNU通用公共授权并不允许您将本程序合并到私有的程序中。若您的程序是一个子程序库,您可能认为允许私有的应用程序链接该库会更有用。如果这是您所想做的,请使用GNU松弛通用公共授权代替本授权。但这样做之前,请阅读<http://www.gnu.org/philosophy/why-not-lgpl.html>

4.2     LGPL 2.1协议

4.2.1    导言

大多数软体许可证决意剥夺您共享和修改软体的自由。相反的,GNU 通用公共许可证力图保证您共享和修改自由软体的自由 —— 保证自由软体对所有使用者都是自由的。

这个许可证,较宽松公共许可证,适用于一些由自由软体基金会与其他决定使用此许可证的软体作者,所特殊设计的软体套件 —— 象是函数库。您也可以使用它,但我们建议您事先仔细考虑,基于以下的说明是否此许可证或原来的通用公共许可证在任何特殊情况下均为较好的方案。

当我们谈到自由软体时,我们所指的是自由,而不是价格。我们的 GNU 通用公共许可证是设计用以确保使您有发布自由软体备份的自由(如果您愿意,您可以对此项服务收取一定的费用);确保您能收到程式原始码或者在您需要时能得到它;确保您能修改软体或将它的一部分用于新的自由软体;而且还确保您知道您可以做上述的这些事情。

为了保护您的权利,我们需要作出限制:禁止任何人否认您上述的权利,或者要求您放弃这些权利。如果您发布软件的副本,或者对之加以修改,这些规定就转化为您的责任。

例如,如果您发布此函数库的副本,不管是免费还是收取费用,您必须将您享有的一切权利给予接受者;您必须确保他们也能收到或得到原始程式码;如果您将此函数库与其他的程式码连结,您必须提供完整的目的对象文件和程序(object file)给接受者,则当他们修改此函数库并重新编译过后,可以重新与目的档连结。您并且要将这些条款给他们看,使他们知道他们有这样的权利。

我们采取两项措施来保护您的权利: (1)用版权来保护函数库。并且,(2)我们提供您这份许可证,赋予您复制,发布和(或)修改这些函数库的法律许可。

为了保护每个发布者,我们需要非常清楚地让每个人明白,自由函数库是没有担保责任的。如果由于某人修改了函数库,并继续加以传播,我们需要它的接受者明白:他们所得到的并不是原始的版本。故由其他人引入的任何问题,对原作者的声誉将不会有任何的影响。

最后,由于软体专利不断地威胁自由软体的存在,我们希望商业公司无法藉由自专利持有者取得一个受限的许可证,而有效地限制自由软体的使用者。因此,我们坚持一个函数库所能取得的任何专利,必须与本许可证所声明的“完全自由使用”一致。

大部分的 GNU 软体,包括一些函数库,是受到原来的 GNU 通用公共许可证的保护。本许可证, GNU 较宽松通用公共许可证,适用于特殊设计的函数库,且与原来的通用公共许可证有很大的不同。我们在特定的函数库中使用它,以准许非自由的程式可以与这些函数库连结。当一个程式与一个函数库连结,不论是静态连结或使用共享函数库,二者的结合可以合理地说是结合的作品,一个原来的函数库的衍生品。因此,原来的通用公共许可证只有在整个结合品满足其自由的标准时,才予许连结。较宽松通用公共许可证则以更宽松的标准允许其他程式码与本函数库连结。

我们称此许可证 “较宽松” 通用公共许可证,是因为它比起原来的通用公共许可证对使用者的自由做到较少的保护。在与非自由软体竞争时,它也提供其他自由软体的写作者较少的优势。这些不利之处正是我们使用原来的通用公共许可证于许多函数库的理由。然而,较宽松的许可证可在某些特殊场合下带来好处。例如,在少数情况下,可能会有特殊的需要而鼓励大家尽可能广泛地使用特定的函数库,因而使它成为实际上的标准。为了达到此目标,必须允许非自由的程式使用此函数库。一个较常发生的情况是一个自由的函数库与一个被广泛使用的非自由函数库做相同的工作,在此情况下,限制只有自由软体可以使用此自由函数库不会有多少好处,故我们如用了较宽松通用公共许可证。

在其他情况下,允许非自由程式使用特定的函数库,可以让更多的人们使用自由软体的大部分。例如,允许非自由程式使用 GNU C 函数库可以让更多的人们使用整个 GNU 作业系统,以及它的变形,GNU/Linux 作业系统。

尽管较宽松通用共公许可证对使用者的自由是较少的保护的,它却能确保与此函数库连结的程式的使用者拥有自由,而且具有使用修改过的函数库版本来执行该程式的必要方法。

以下是复制、发布、以及修改的精确条款与条件。请注意 “基于函数库的作品” 以及 “使用函数库的作品” 之间的差异:前者包含来自函数库修改过的原始码;而后者则必须与函数库结合才能执行。

4.2.2    条款和条件

4.2.2.1 定义

  1. 本许可证适用于任何软体函数库,或其他包含了由版权所有者加入的注意事项的程式,或其他有公信力的团体宣称其程式可以在较宽松通用公共许可证 (也称之为 “本许可证”) 的条款下发布。每一位许可证接受者以 “您” 来称呼。
  2. 一个 “函数库” 意指一些软体函数的集合,以及或准备好的资料以方便与应用程式 (其使用了其中某些函数与资料) 连结形成可执行的程式。以下,”函数库” 一词指的是任何在本条款下发布的这一类软体函数库或作品,个 “基于本函数库的作品” 意指函数库或任何在版权法下的衍生作品:也就是说,一个包含了本函数库或其一部分的作品,可以是原封不动的,或经过修改的,和/或直接翻译成其他语言的。 (在下文中,翻译是不受限地包含在 “修改” 的条款中。)
  3. 作品的 “原始码” 意指对作品进行修改最优先择取的形式。对函数库而言,完整的原始码意指所有模组的所有原始程式,加上有关的介面的定义,加上控制函数库的安装和编译的 script。
  4. 本许可证条款不适用于复制,发布和修改以外的活动。这些活动超出这些条款的范围。使用本函数库来执行本程式的动作不受条款的限制,而程式的输出只有在其内容所构成的作品是基于本函数库时 (与在什么样的工具中使用本函数库来输出无关) ,这一条款才适用。以上是否为真则取决于本函数库具体用来做什么。
  5. 只要您在每一程式副本上明显和恰当地宣告版权声明和不承担担保的声明,并保持此许可证的声明和没有担保的声明完整无损,并和程式一起给其他每位程式接受者一份许可证的副本,您就可以用任何媒体复制和发布您收到的函数库的完整原始码。您可以为转让副本的实际行动收取一定费用。您也可以选择提供担保以换取一定的费用。
  6. 只要您同时满足下面的所有条件,您就可以按前面第一款的要求修改函数库的一个或几个副本或它的任何部分,以此形成基于此函数库的作品,并且复制和发布这一经过修改的程式或作品:

4.2.2.2  条款

1)     被修改的作品本身必须是一个软体函数库。

2)     您必须在修改过的档案中附有明确的说明:

3)     您修改了此一档案及任何修改的日期。您必须让整个作品允许第三方在此许可证条款下可以免费使用。

4)     如果修改过的函数库其某个设备使用到了「使用本函数库的应用程式」所提供的函数或资料表格,却不是当此设备被呼叫时以参数列传入时,则您必须确实做到,当应用程式不提供这样的函数或表格时,则此设备依旧能工作,且其执行的任何目的仍然有意义。

5)     (例如,一个函数库的函数用来计算平方根,其目的是有完整的定义且与应用程式是无关的。因此, 2d 小节要求任何本函数会使用的,由应用程式所提供的函数或表格必须是选择性的:如果应用程式不提供的话,则计算平方根的函数必须依旧能计算平方根)

这些要求适用于整个修改过的作品。如果能够确定作品的一部分并非本函数库的衍生产品,且可以合理地单独考虑并将它与原作品分开的话,则当您将它作为独立的作品发布时,它不受此许可证和其条款的约束。但是当您将这部分与基于本函数库的作品一同发布时,则整个套件将受到本许可证条款约束,其对于其他许可证持有人的使用范围扩大到整个产品,也就是套件的每个部分,不管它是谁写的。

因此,本条款的意图不在于索取权利,或剥夺完全由您完成的作品的权利,而是履行权利来控制基于本函数库的集体作品或衍生作品的发布。 此外,将与本函数库无关的作品和本函数库 (或基于本函数库的作品) 一起放在贮存媒体或发布媒体的同一卷上,并不导致将其他作品置于此许可证的约束范围之内。

  1. 对于一个函数库的副本,您可以选择性地使用原来的 GNU 通用公共许可证上的条款来取代本许可证上的条款。如果您要这么做,您必须修改所有的参考到本许可证的注意事项,使它们指向原来的 GNU 通用公共许可证,第二版,以取代本许可证(如果有比第二版的原来的 GNU 通用公共许可证更新的版本出现的话,则如果您愿意的话可以特别指明使用新版)。请不要对这些注意事项做出其他的改变。一旦在一个副本上做了这样的改变,则该副本就无法撤回这样的改变,故原来的 GNU 通用公共许可证将适用于所有后续的副本以及由此副本衍生出来的作品。此一选择性适用于当您想要将一部分的函数库原始码复制到一个非函数库的程式使用时。
  2. 您可以以目标码或可执行形式复制或发布本函数库 (或符合第 2 款,基于本函数库的作品),只要您遵守前面的第 1、2 款,并同时提供完整的相关机器可读的原始码,而这些原始码必须在前面的第 1 与第 2 款条件下,在一般习惯上用来做软体交换的媒体上发布。如果所发布的目标码是由指定的地点提供拷贝索取,那么由同一地点所提供等价的原始码拷贝索取可以算作原始码的发布,即使第三方不强求与目标码一起复制原始码。
  3. 一个程式若包含不经任何部分修改的函数库,但却是设计经由编译或连结的方式与本函数库一同工作者,称之为 “使用函数库的作品”。这样的一个作品,严格地说,并非本函数库的衍生作品,因而不在本许可证的范围之内。然而,将 “使用函数库的作品” 与本函数库连结而产生可执行程式,则是本函数库的衍生品 (因为它包函了本函数库的一部分),而不是 “使用函数库的作品”,因此其可执行程式包含在本许可证的范围内。第 7 款说明了发布此可执行程式的条款。

当 “使用函数库的作品” 使用了函数库部分的标头档内容时,则此作品即使其原始码不属于本函数库的衍生品,但其目标码仍然是。这一点是否为真特别在是否本作品可以在不需要本函数库即可连结,或者是否该作品本身也是一个函数库时特别明显。

如果这样的目标档只使用数字参数、资料结构层级与附属品、以及小巨集和小内□式 (小于或等于十行) ,则此目标档的使用是不受限的,不论是否它是合法的衍生作品。 (但可执行程式若包函此目标档以及一部分的函数库,仍然将在第 7款的规定下)

否则的话,如果本作品是本函数库的衍生品,您必须在第 6 款的规定下发布该作品的目标码。任何包含该作品的可执行程式也在第 6 款的范围内,不论它们是否直接与本函数库连结。

  1. 做为上述条款的例外情况,您也可以将 “使用函数库的作品” 与本函数库结合或连结,以产生包含部分本函数库的作品,并在允许使用者自身使用时可以修改该作品,以及在对修改进行反组译除错的情况下,您可以依照您的选择发布该作品。

您必须在每个作品的副本突显出如下的注意事项:本函数库在作品中被使用,以及本函数库以及它的使用是在本许可证的规定下。您必须提供本许可证的副本。如果该作品在执行时显示版权声明,您必须在其中包含本函数库的版权声明,以及指引使用者取得本许可证的副本。同时,您必须做到以下其中一件事:

必须将完整的机器可读的函数库原始码包含在该作品中,包括任何该作品使用到的改变 (这些改变必须在前述第 1 与第 2 款的要求下发布);而且,如果该作品是一个与函数库连结的「完整的、机器可□的 “使用函数库的作品”」,则要有目标码和/或原始码,如此使用者可以修改本函数库且可以重新连结,以产生包函修改过的函数库的修改过的可执行程式。 (理所当然的若使用者修改了函数库的档案定义内容时,则该作品不必然可以重新编译以使用修改过的定义。)

在与函数库连结时使用适当的分享函数库连结机制。一个适当的机制是: (1) 在执行时使用已存在于使用者的电脑中的函数库副本,而不是将函数库的函数复制到可执行程式里,以及 (2) 如果使用者安装了一份修改过的函数库,只要修改过的版本在介面上与该作品在编译连结时所用的版本是相容的,则该执行程式可以与修改过的函数库运作良好。

在该作品内提供书面报价,有效期不少于三年,以提供同样的使用者上述第 7a 款中的内容,费用不得超过该程式发布的实际成本。 如果所发布的作品是由指定的地点提供拷贝索取,则由同一地点提供上述内容的等价拷贝索取。

确定使用者已经收到该作品的一份复制,或是您已经寄给该使用者一份复制品。

对于一个可执行程式,其所需的 “使用函数库的作品” 的形式必须包括任何要从中再产生可执行程式时所需的资料与工具程式。然而,有一个特殊例外,其所发布的内容不需要包括任何一般与「可执行本程式的作业系统」的主要部分 (如编译器、核心等) 一起发布的部分 (不论是原始码或可执行码),除非这些组成部分和可执行作品结合在一起。

有一个可能情况是,这些要求与其他通常不与作业系统在一起的私有函数库的版权限制相抵触,这样的抵触表示您不能将它们与本函数库一起用于您发布的可执行程式中。

  1. 您可以将使用本函数库的函数库设备,以及其他不在本许可证范围内的函数库,对等地放入一个单独的函数库中,并在基于本函数库的作品以及其他函数库在其他状态下同意可以个别发布,以及您做到以下两点的情况下,您可以发布此结合的函数库:将基于本函数库的作品单独不与其他函数库设备结合地,与此结合的函数库一同发布。该作品必须在上述条款的规定下发布。在此结合的函数库中明显地指出其中一部分的作品是基于本函数库,并且说明那里可以找到同样不具结合形式的作品。
  2. 除非您明确按许可证提出的要求去做,否则您不能复制、修改、转发许可证、与本函数库连结、和发布本函数库。任何试图用其他方式复制、修改、转发许可证、与本函数库连结、和发布本函数库是无效的,而且将自动结束许可证赋予您的权利。然而,对那些从您那里按许可证条款得到副本和权利的人们,只要他们继续全面履行条款,许可证赋予他们的权利仍然有效。
  3. 您没有在许可证上签字,因而您没有必要一定接受此一许可证。然而,没有任何其他东西赋予您修改和发布本函数库及其衍生作品的权利。如果您不接受许可证,这些行为是法律禁止的。因此,如果您修改或发布函数库 (或任何基于函数库的作品) ,您就表明您接受这一许可证以及它的所有有关复制、发布和修改本函数库或基于它的作品的条款和条件。
  4. 每当您重新发布函数库 (或任何基于函数库的作品) 时,接受者自动从原始许可证颁发者那里接到受这些条款和条件支配的复制、发布、连结或修改本函数库的许可。您不可以强迫接受者履行除了这里赋予他们的权利之外的其他限制。您也没有强求第三方履行许可证条款的义务。
  5. 如果由于法院判决或违反专利的指控或任何其他原因 (不限于专利问题) 的结果,使得强加于您的条件 (不管是法院判决,协议书或其他) 和许可证的条件有冲突时,他们也不能令您背离许可证的条款。在您不能同时满足本许可证规定的义务及其他相关的义务来发布函数库时,则结果您只能够根本不发布函数库。例如,如果某一专利许可证不允许所有直接或间接从您那里接受副本的人们,在不付专利费的情况下重新发布函数库,唯一能同时满足两方面要求的办法是停止发布函数库。

如果本条款的任何部分在特定的环境下无效或无法实施,就使用条款的其余部分,并将这部分条款作为整体用于其他环境。本条款的目的不在于引诱您侵犯专利或其他财产权的要求,或争论这种要求的有效性。本条款的主要目的在于保护自由软体发布系统的完整性。它是通过公共许可证的应用来实现的。许多人已依赖同是出自此系统的应用程式,经由此系统发布大量自由软体而做出慷慨的供献。作者/捐献者有权决定他/她是否通过任何其他系统发布软体,许可证持有人不能强加这种选择。

本节的目的在于明确说明许可证其余部分可能产生的结果。

  1. 如果由于专利或者由于有版权的介面问题使函数库在某些国家的发布和使用受到限制,则在许可证约束下的原始版权拥有者可以增加发布地区的限制条款,将这些国家明确排除在外,并在这些国家以外的地区发布函数库。在这种情况下,许可证套件含的限制条款和许可证正文一样有效。 13. 自由软体基金会可能随时出版较宽松通用公共许可证的修改版或新版。新版和当前的版本在原则上保持一致,但在提到新问题时或有关事项时,在细节上可能出现差别。

每一版本都有不同的版本号。如果函数库指定可适用的许可证版本号以及 “任何更新的版本” ,您有权选择遵循指定的版本或自由软体基金会以后出版的新版本。如果函数库未指定许可证版本,您可选择自由软体基金会已经出版的任何版本。

  1. 如果您愿意将函数库的一部分结合到其他自由程式中,而它们的发布条件不同,请写信给作者,要求准予使用。如果是自由软体基金会加以版权保护的软体,写信给自由软体基金会,我们有时会作为例外的情况处理。我们的决定受两个主要目标的指导,这两个主要目标是:我们的自由软体的衍生作品继续保持自由状态,以及从整体上促进软体的共享和重复利用。
  2. 没有担保

1)     由于函数库准予免费使用,在适用法准许的范围内,对函数库没有担保。除非另有书面说明,版权所有者和/或其他提供函数库的人们 “一样” 不提供任何类型的担保,不论是明确的,还是隐含的,包括但不限于可销售和适合特定用途的隐含保证。全部的风险,如函数库的质量和性能问题都由您来承担。如果函数库出现缺陷,您应当承担所有必要的服务、修复和改正的费用。

2)     除非适用法或书面协议的要求,在任何情况下,任何版权所有者或任何按许可证条款修改和发布函数库的人们都不对您的损失负有任何责任。包括由于使用或不能使用函数库引起的任何一般的、特殊的、偶然发生的或重大的损失 (包括但不限于数据的损失,或者数据变得不精确,或者您或第三方的持续的损失,或者函数库不能和其他软体协调运行等) 。即使版权所有者和其他人提到这种损失的可能性也不例外。

 

 

Posted in Uncategorized