Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
Lnncoco committed Dec 21, 2020
0 parents commit bc6dfc2
Show file tree
Hide file tree
Showing 65 changed files with 2,187 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package-lock.json
.build
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"printWidth": 200,
"tabWidth": 2,
"semi": true,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": true
}
Binary file added HostsSwitch.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# HostsSwitch

![HostsSwitch](./HostsSwitch.jpg)

## 介绍

这是一个为了练手做的小工具。看见`aardio`官方有一个修改版的[`hostsSwitchHelper`](https://github.com/aardio/hostsSwitchHelper),于是学习了一下实现。
自己重头设计实现了界面和逻辑,逻辑都在前端,只有涉及保存文件之类放到`aardio`里。
前端使用`LuLu UI`+`LESS`+`TypeScript`实现。

功能与`SwitchHosts!`类似,就是方便修改系统 Hosts 信息的小工具。与之不同的是,每个项都是一份独立的 Host 信息,可以自己手动输入,也可以设置`url`参数,方便网络`Hosts`更新(默认会走系统代理设置)。侧边`Switch开关`开启时会自动将所有开启的数据合并,然后存入系统的`Hosts`文件中。

### 目录

`dist`:存放一份编译后的`exe`应用程序
`lib``aardio`的用户库文件存放目录
`web`:前端编译后的文件,`aardio`打包使用的文件
`web_source`:前端项目源码。使用`parcel`工具

### 修改生成

-`web_source`目录中执行 `npm i` 安装依赖
- 安装完成后,执行 `npm run dev` 启动项目,然后在`aardio`中同时启动,此时`aardio`的页面会访问本地的前端项目,可以实时修改查看(不知道是`aardio`不兼容`parcel`还是本来就是如此,在浏览器直接访问`aardio`的依赖会报错导致无法正常显示程序)。要确保 `6060` 端口未被占用,否则需要修改响应代码
- 修改完成后使用 `npm run build` 编译,程序会自动生成到父级的`web`目录下
Binary file added app.ico
Binary file not shown.
21 changes: 21 additions & 0 deletions default.aproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<project ver="10" name="HostsSwitch" libEmbed="true" icon="app.ico" ui="win" output="HostsSwitch.exe" CompanyName="LnnCoCo" FileDescription="HostsSwitch" LegalCopyright="Copyright (C) LnnCoCo 2020" ProductName="HostsSwitch" InternalName="HostsSwitch" FileVersion="1.0.0.0" ProductVersion="1.0.0.0" publishDir="\dist\" dstrip="false" local="false">
<file name="main.aardio" path="main.aardio" comment="main.aardio"/>
<folder name="web" path="web" comment="web" local="false" embed="true">
<file name="addition.75f59799.svg" path="web\addition.75f59799.svg" comment="web\addition.75f59799.svg"/>
<file name="download.779c3df5.svg" path="web\download.779c3df5.svg" comment="web\download.779c3df5.svg"/>
<file name="edit.e5e6ea37.svg" path="web\edit.e5e6ea37.svg" comment="web\edit.e5e6ea37.svg"/>
<file name="favicon.da3735d5.png" path="web\favicon.da3735d5.png" comment="web\favicon.da3735d5.png"/>
<file name="home.3a7af05d.svg" path="web\home.3a7af05d.svg" comment="web\home.3a7af05d.svg"/>
<file name="index.aardio" path="web\index.aardio" comment="web\index.aardio"/>
<file name="lock.623ff62a.svg" path="web\lock.623ff62a.svg" comment="web\lock.623ff62a.svg"/>
<file name="main.2a31e670.js" path="web\main.2a31e670.js" comment="web\main.2a31e670.js"/>
<file name="main.a46e3e18.css" path="web\main.a46e3e18.css" comment="web\main.a46e3e18.css"/>
<file name="record.56e10638.svg" path="web\record.56e10638.svg" comment="web\record.56e10638.svg"/>
<file name="recordFind.08a261bc.svg" path="web\recordFind.08a261bc.svg" comment="web\recordFind.08a261bc.svg"/>
<file name="refresh.0b748f9a.svg" path="web\refresh.0b748f9a.svg" comment="web\refresh.0b748f9a.svg"/>
<file name="save.8ed52c9e.svg" path="web\save.8ed52c9e.svg" comment="web\save.8ed52c9e.svg"/>
<file name="subtraction.600c820b.svg" path="web\subtraction.600c820b.svg" comment="web\subtraction.600c820b.svg"/>
<file name="unlock.6ef52b3f.svg" path="web\unlock.6ef52b3f.svg" comment="web\unlock.6ef52b3f.svg"/>
</folder>
</project>
Binary file added dist/HostsSwitch.exe
Binary file not shown.
108 changes: 108 additions & 0 deletions lib/hosts.aardio
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
namespace hosts;

import fsys;
import fsys.hosts;
import fsys.table;
import inet.http;


fsys.hosts.ownCacls(); // hosts夺权,修正一些系统hosts无法编辑

path = "~/";
backupFileName = 'system.bak';

// 配置文件
config = fsys.table("~/config.hosts");
config.load();

// 获取完整保存文件路径
getSavePath = function(name){
if(!name) return null,false,'请输入文件名';
var pathDir = ..io.fullpath(path);
return pathDir ++ name,true,"";
}

// 判断文件是否存在
isExistFile = function(name){
return !!..io.exist(path++name);
}

/**
* 获取系统Hosts
**/
getSystemHosts = function(){
return fsys.hosts.loadText();
}

/**
* 保存到系统Hosts
* @param {string} content
**/
saveSystemHosts = function(content){
return ..fsys.hosts.saveText(content);
}

/**
* 刷新DNS缓存
**/
clearDnsCache = function(){
fsys.hosts.flushDns();
return true;
}

/**
* 发送请求获取网络Hosts
* @param {string} url
* @param {Object} proxy
**/
requestHosts = function(url, proxy){
if(!proxy) proxy = {}
var http = inet.http(proxy.ua, proxy.host);
if(proxy.user && proxy.password) http.setProxyAuth(proxy.user, proxy.password);
var html,err,errCode = http.get(url);
if(html) return { code = 0, message = 'success', html = html }
else {
if(http.statusCode) return { code = http.statusCode, message = http.lastResponse() }
else return { code = errCode || 9, message = err }
}
}

/**
* 备份系统文件
* @param {boolean} coverage 是否强制覆盖
**/
backupLocalHosts = function(coverage = false){
var path,status,errMsg = getSavePath(backupFileName)
if(!status) return status
if(isExistFile(backupFileName) && !coverage) return status;
return ..string.save(path, getSystemHosts());
}

/**
* 获取所有数据
* @param {table} data 所有数据
**/
getConfigData = function(){
return config;
}

/**
* 保存所有数据
* @param {table} data 所有数据
**/
saveConfigData = function(data){
config.main = data;
config.time = ..time.now();
return config.save();
}


/**intellisense(hosts)
clearDnsCache() = 刷新DNS缓存
requestHosts() = 从url获取Hosts信息
getSystemHosts() = 获取系统的Hosts信息
saveSystemHosts() = 保存到系统的Hosts
backupLocalHosts() = 备份系统文件
getConfigData() = 获取所有数据
saveConfigData() = 保存所有数据
end intellisense**/
73 changes: 73 additions & 0 deletions main.aardio
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import fsys.hosts;
import chrome.app;
import hosts;

var theApp = chrome.app();

/*
external定义的对象可以通过aardio进行调用
*/
theApp.external = {

//获取本地hosts
getSystemHosts = hosts.getSystemHosts;

//获取本地hosts
saveSystemHosts = hosts.saveSystemHosts;

//手动刷新dns缓存
clearDnsCache = hosts.clearDnsCache;

// 发送请求获取网络HOSTS
requestHosts = hosts.requestHosts;

// 备份系统文件
backupLocalHosts = hosts.backupLocalHosts;

// 获取配置信息
getConfigData = hosts.getConfigData;

// 保存配置信息
saveConfigData = hosts.saveConfigData;

}

/*
// 加载一个页面完成会触发这个事件(要求引用了"/aardio.js")
theApp.onUrlReady = function($,url){

}

// 窗口关闭时触发
theApp.onQuit = function($,url){

}
*/

//WebSocke/RPC中遇到的错误都会触发这个函数,可以在这里自定义错误处理方式
theApp.ws.onError = function(hSocket,err){
errput(err, "chrome/rpc error");//当然也可以在 global.onError 里自定义全部的错误信息怎么显示
}

var url = "/web/index.aardio"

// 调试模式
if(_STUDIO_INVOKED){
import web.rest.client;
if( web.rest.client().api("http://localhost:6060/",,"HostsSwitch").get() ){
url = "http://localhost:6060/";
}
}

// 窗口大小
theApp.indexReady(
function(){
//theApp.setPos(,,820,430)
}
)

// 正式的启动chrome进程,aardio会自动把下面的文件转换为服务端请求
theApp.start(url);

// 网页中可以调用 aardio.quit() 退出,也可以直接关闭chrome窗口退出
win.loopMessage();
1 change: 1 addition & 0 deletions web/addition.75f59799.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions web/download.779c3df5.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions web/edit.e5e6ea37.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/favicon.da3735d5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions web/home.3a7af05d.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions web/index.aardio
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html><html><head><title>HostsSwitch</title><meta charset="utf-8"><meta name="author" content="LnnCoCo"><meta name="description" content=""><meta name="google" content="notranslate"><link rel="icon shortcut" type="image/ico" href="/web/favicon.da3735d5.png"><link rel="stylesheet" href="/web/main.a46e3e18.css"></head><body> <div class="container"> <nav> <div class="nav-container" id="nav"><ul></ul></div> </nav> <main> <div class="textarea"> <div class="operation"> <div class="save"></div> <div class="net"></div> <div class="refresh"></div> </div> <textarea class="ui-textarea" id="textarea"></textarea> </div> </main> </div> <div class="context-menu"></div> <div class="shade"></div> <div class="dialog-item"> <div class="item-hader">修改配置</div> <div class="item-body"> <div class="form-item">标签名称: <input class="ui-input" name="name"></div> <div class="form-item">远程地址: <input class="ui-input" name="url" placeholder="无需远程获取则留空"></div> </div> <div class="clearfix item-operation"> <button class="ui-button" data-type="primary" id="dialog_apply">确定</button> <button class="ui-button" id="dialog_cancel">取消</button> </div> </div> <script charset="utf-8" src="/web/main.2a31e670.js"></script> <script id="template_nav" type="text/html">
{{each $data item}}
<li data-id="{{item.id}}" class="nav-item {{item.active ? 'active' : ''}} {{ item.home? 'home' : '' }} {{ item.url? 'net' : '' }}">
{{item.name}}
<div class="onoff"><input type="checkbox" id="onoff{{$index}}" {{item.checked && "checked"}} {{item.home && 'disabled'}} /><label class="ui-switch" for="onoff{{$index}}"></label></div>
</li>
{{/each}}
</script> <script id="template_contextMenu" type="text/html">
<div>
{{if $data.target}}
<div class="menu-target">{{target}}</div>
{{/if}}
<ul>
{{each list item}} {{if item.line}}
<li class="menu-line"></li>
{{else}}
<li class="menu-item {{ ((item.action === 'update' && isLocal) || ((item.action === 'remove' || item.action === 'unlock' || item.action === 'modify') && isHome))? 'disabled' : ''}}" data-action="{{item.action}}">
{{if item.icon}}
<div class="icon"><img src="{{item.icon}}" alt="" /></div>
{{/if}} {{item.text}}
</li>
{{/if}} {{/each}}
</ul>
</div>
</script> </body></html>
1 change: 1 addition & 0 deletions web/lock.623ff62a.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit bc6dfc2

Please sign in to comment.