ZeroNet Blogs

Static ZeroNet blogs mirror

带emoji输入支持的ZeroBlog

First of all,Thanks for @Nofish ZeroNet site development tutorial

介于中文站点开发教程还是too young too simple,我准备也来一个了。

大多数新手开发者都是windows环境,因此主要介绍windows下的配置,用Linux的跟着官方教程走就好:wink:

因为windows下ZeroBundle自带的coffee script编译器有BUG,经常会出现各种无法编译或者出错,为了不被这些破事折腾死自己,在这里我直接推荐windows下的开发也上nodejs原版编译器。:smiley::smiley::smiley:

在本教程中,我们将用少于100行的代码中构建一个完全P2P、无需后端服务器的聊天站点。


1.​​​​​​​环境搭建

  1. 首先,到nodejs官网下载nodejs最新版本(现在最新V7.0.4)并安装,安装一路下一步确认即可。
  2. 打开命令行,如果不知道怎么快捷打开可以到开始菜单->附件->命令提示符,点击运行,之后在弹出的窗口内贴入以下命令:npm install -g coffee-script并回车,等待运行完毕,重新出现C:\xxxxx>这样的文字即可。
  3. 这里下载WebStorm并安装,安装过程一路下一步。安装好后看不惯英文界面的可以自行到这里下载汉化包,并把压缩包里lib目录下的resources_zh.jar文件放到WebStorm的lib目录下即可。(WebStorm默认安装目录为C:\Program Files (x86)\JetBrains下的WebStorm+版本号目录)
  4. 右键单击这里另存为DebugMedia.py,覆盖自己的ZeroBundle\ZeroNet\src\Debug\DebugMedia.py,以解决中文字符在win下coffee script编译器编译失败的问题。
  5. 右键单击这里另存为debug.cmd,保存到ZeroBundle目录下,退出ZeroNet,然后双击刚刚放到ZeroBundle目录下的debug.cmd,启动DEBUG模式的ZeroNet。

现在,开发环境就已经配置好了:smiley:让我们一起来建立一个属于自己的新站点吧:smile:

创建新网站

  • 点击ZeroHello左上角的⋮>“新建空站点”菜单项。您将被重定向到一个属于你的全新的空白网站,只有你对这个网站具有完整控制权哟~
  • 右上方的“0”按钮拖动到左侧以显示侧边栏

  • 鼠标滚轮滑动到侧边栏底部,将_站点标题更改为“我的ZeroChat教程”,然后点击“保存网站设置”。

聊天网站的HTML代码

  • 使用WebStorm打开“data/ [yoursiteaddress] /index.html”文件。
  • 编辑 index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>ZeroChat</title>
</head>
<body>
<input type="text" id="message"><input type="button" id="send" value="发送"/>
<ul id="messages">
    <li>欢迎来到 ZeroChat!</li>
</ul>
</body>
</html>

第一个ZeroFrame API调用

Note:要禁用浏览器的缓存,请保持JavaScript控制台打开并启用禁用缓存(F12)

ZeroFrame API允许您查询服务器/站点/用户信息,加载或修改文件。

创建 jsjs/lib 目录,然后下载并将ZeroFrame.coffee文件复制到 js/lib ,这有助于使用ZeroFrame API

  • 创建包含以下内容的 js / ZeroChat.coffee 文件:
class ZeroChat extends ZeroFrame
    init: ->
        @addLine "初始化成功"

    addLine: (line) ->
        messages = document.getElementById("messages")
        messages.innerHTML = "<li>#{line}</li>"+messages.innerHTML

    # Wrapper websocket 链接建立完成
    onOpenWebsocket: (e) =>
        @cmd "serverInfo", {}, (server_info) =>
            @addLine "服务器信息: <pre>" + JSON.stringify(server_info,null,2) + "</pre>"
        @cmd "siteInfo", {}, (site_info) =>
            @addLine "站点信息: <pre>" + JSON.stringify(site_info,null,2) + "</pre>"

window.Page = new ZeroChat()

此代码将在websocket连接准备就绪后查询有关网站和服务器(您的ZeroNet客户端)的所有信息,然后将结果作为json格式的文本添加到消息html节点。

  • 在index.html文件中添加<script type ="text/javascript" src ="js / all.js" async> </ script></body>之前,加入这行以让DEBUG模式下的ZeroNet自动编译和合并所有在 js 目录下的.coffee文件到单个all.js文件。

  • 如果一切顺利,它应该看起来像这样:

tutorial 您应该具有以下目录结构:

data / [您的网站地址]
├─js /
│├─lib /
││└─ZeroFrame.coffee
│├─ZeroChat.coffee
│└─all.js
├──index.html
└──content.json
  • 在网站上完成修改后,您必须到侧边栏最底下点击“签名”、“发布”按钮,这样他人才能在浏览您的站点时看到您的更改。

进一步的功能实现

我们将其扩展为使用SQLite数据库接受,存储和查询消息,并使用ZeroID来标识用户名。

添加ZeroID用户选择器

添加一个新的链接到 index.html ,这将允许我们选择我们要使用的ZeroID身份:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>ZeroChat</title>
</head>
<body>
<a href="#Select+user" id="select_user" onclick='return Page.selectUser()'>选择用户</a>:
<input type="text" id="message"><input type="button" id="send" value="发送"/>
<ul id="messages">
    <li>欢迎来到 ZeroChat!</li>
</ul>
<script type="text/javascript" src="js/all.js" async></script>
</body>
</html>

要使其工作添加一个函数到js/ZeroChat.coffee显示证书选择对话框给用户:

    selectUser: =>
        Page.cmd "certSelect", [["zeroid.bit"]]
        return false

作为参数,您应该包括接受的证书提供程序名称。 (在这里使用zeroid.bit)

如果您进行刷新并单击“选择用户”,则应该会看到对话框,但在选择zeroid证书时没有任何更改。

显示用户当前的ZeroID帐户

当更改影响网站(新内容到达,用户更改等)的内容时,websocket事件将被推送到您的浏览器。 (格式与查询setSiteInfo命令相同)

要处理此事件,请添加此函数:

    route: (cmd, message) ->
        if cmd == "setSiteInfo"
            if message.params.cert_user_id
                document.getElementById("select_user").innerHTML = message.params.cert_user_id
            else
                document.getElementById("select_user").innerHTML = "选择用户"
            @site_info = message.params # 保存网站信息数据以允许稍后访问

此代码将实时更新用户当前选择的用户名。

要在页面加载时更新用户名,请修改onOpenWebsocket 函数:

    onOpenWebsocket: (e) =>
        @cmd "serverInfo", {}, (server_info) =>
            @addLine "serverInfo response: <pre>" + JSON.stringify(server_info,null,2) + "</pre>"
        @cmd "siteInfo", {}, (site_info) =>
            @addLine "siteInfo response: <pre>" + JSON.stringify(site_info,null,2) + "</pre>"
            # 更新当前选择的用户名
            if site_info.cert_user_id
                document.getElementById("select_user").innerHTML = site_info.cert_user_id
            @site_info = site_info  # 保存网站信息数据以允许以后访问

设置用户内容权限

要允许用户在我们的网站上发布,我们必须定义第三方内容的规则。

创建一个data/users 目录,并在其中创建一个 data/users/content.json 文件:

{
  "files": {},
  "ignore": ".*",
  "modified": 0.0,
  "signs": {},
  "user_contents": {
    "cert_signers": {
      "zeroid.bit": [ "1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz" ]
    },
    "permission_rules": {
      ".*": {
        "files_allowed": "data.json",
        "max_size": 10000
      },
      "bitmsg/.*@zeroid.bit": { "max_size": 15000 }
    },
    "permissions": {
      "bad@zeroid.bit": false,
      "nofish@zeroid.bit": { "max_size": 100000 }
    }
  }
}
  • "ignore”:".*":当网站所有者签署这个content.json时,没有添加任何文件,它们将被用户签名。
  • cert_signers:我们接受* @zeroid.bit用户,他们必须带有一个证书,必须由1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz地址签名。
  • permission_rules:我们给每个用户10kbytes的空间(如果是使用bitmessage注册的用户则给15kb)
  • permissions:每用户权限:禁止用户 bad@zeroid.bit 登录以及允许用户nofish@zeroid.bit有100k存储空间。 ( ZeroNet 的开发者 : ) )

在我们保存此文件后,我们必须修改我们站点根目录下的 content.json 文件 ,以便忽略此目录中的文件,并加载包含规则的文件:

  ...
  "ignore": "data/.*",
  "includes": {
    "data/users/content.json": {
      "signers": [],
      "signers_required": 1
    }
  },
  ...

注意:您可以通过向“签名者”列表添加地址,向其他用户授予审核权限。

  • 现在,通过按下网页侧边栏的“签名”按钮签名content.json 来保存修改。
  • 然后保持侧边栏打开,将“content.json”更改为“data/users/content.json”,然后再次按“签名”按钮!

添加消息到我们的json文件

当点击发送按钮时,将消息添加到data.json文件,签名,然后发布到其他用户。

  • 首先添加onclick ="return Page.sendMessage()"事件监听器来发送输入按钮html标签。

  • 然后在 ZeroChat.coffee 中创建一个新函数:


sendMessage: => if not Page.site_info.cert_user_id # 未选择帐户,显示错误 Page.cmd "wrapperNotification", ["info", "请选择您的账户"] return false inner_path = "data/users/#{@site_info.auth_address}/data.json" # 这是我们的数据文件 # 加载当前的消息 @cmd "fileGet", {"inner_path": inner_path, "required": false}, (data) => if data # Parse if already exits data = JSON.parse(data) else # Not exits yet, use default data data = { "message": [] } # 将消息添加到数据 data.message.push({ "body": document.getElementById("message").value, "date_added": (+new Date) }) # 将数据数组编码为utf8 json文本 json_raw = unescape(encodeURIComponent(JSON.stringify(data, undefined, '\t'))) # 将文件写入磁盘 @cmd "fileWrite", [inner_path, btoa(json_raw)], (res) => if res == "ok" # 将文件发布给其他用户 @cmd "sitePublish", {"inner_path": inner_path}, (res) => document.getElementById("message").value = "" # 将输入框清空 else @cmd "wrapperNotification", ["error", "文件写入错误: #{res}"] return false
  • 完成后在消息输入框内写点什么,然后点击发送按钮,您应该在data / users / [your auth address] /data.json 文件中看到该消息。

该教程未翻译完,有空再更。

New blog post

- Posted in 带emoji输入支持的ZeroBlog by with comments

​​​​​​​:kissing_closed_eyes::stuck_out_tongue_closed_eyes::stuck_out_tongue::nerd_face::hugging_face::no_mouth::kissing::heart_eyes::yum::upside_down_face::blush::innocent::sweat_smile::smiley::joy::grimacing::grinning::grin::smile::laughing::wink::slightly_smiling_face::relaxed::relieved::kissing_heart::kissing_smiling_eyes::smirk::sunglasses::money_mouth_face::stuck_out_tongue_winking_eye:​​​​​​​:flag-ch::clock930::arrow_up::accept::door::railway_track::mountain::oncoming_police_car::sun_with_face::waning_gibbous_moon::frog::construction_worker::sleuth_or_spy::angel::bride_with_veil::runner::boy::older_man::man_with_gua_pi_mao::speaking_head_in_silhouette::bust_in_silhouette::eye::ear::lips::point_up::point_down::the_horns::writing_hand::muscle::hand::v::facepunch::+1::heart_eyes_cat::kissing_cat::clap::smile_cat::robot_face::ghost::japanese_goblin::imp::sob::astonished::mask::zzz::sweat::disappointed_relieved::anguished::hushed::fearful::pensive::slightly_frowning_face::persevere::tired_face::triumph::rage::worried::flushed::face_with_rolling_eyes::expressionless::neutral_face::unamused::thinking_face::disappointed::angry::open_mouth::weary::confounded::white_frowning_face::confused::scream::cold_sweat::frowning::cry::sleepy::face_with_head_bandage::hankey::sleeping::face_with_thermometer::zipper_mouth_face::dizzy_face::smiling_imp::japanese_ogre::skull::alien::crying_cat_face::smiley_cat::wave::pouting_cat::raised_hands::scream_cat::smirk_cat::joy_cat::-1::fist::ok_hand::point_right::open_hands::pray::middle_finger::spock-hand::raised_hand_with_fingers_splayed::point_left::point_up_2::nail_care::tongue::nose::man::eyes::busts_in_silhouette::woman::man_with_turban::person_with_blond_hair::older_woman::girl::baby::walking::princess::cop::santa::guardsman::beetle::last_quarter_moon_with_face::baby_chick::beers::monkey_face::police_car::sunrise::motorway::bellhop_bell::white_flower::leftwards_arrow_with_hook::flag-sb::black_medium_small_square::flag-se::black_joker:

:smiley: :smiley: :smiley: :smiley: :smiley: