2019年7月4日 星期四

My first PWA Progressive Web Application Google Part 03 Manifest

主要參考:https://codelabs.developers.google.com/codelabs/your-first-pwapp/#3


manifest.json
網頁沒有manifest.json的時候,Chrome裏面的Application Manifest會顯示找不到manifest


在templates裏面增加manifest.json后,然後在index.html裏面加入后,Chrome會顯示裏面的資料:
<link rel="manifest" href="/manifest.json">













Apple iOS
Safari目前再2019年7月的時候依然不支持manifest.json,網頁强行加到主畫面會產生很差的效果,包括缺乏常見的App圖示,而且打開之後沒有全畫面并且會見到Safari頂部網址欄及底部上下頁操作,明顯不像一個App。


因此在我們可以加入<meta>及"apple-mobile-web"相關的資料到index.html裏面:
<!-- CODELAB: Add iOS meta tags and icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Weather PWA">
<link rel="apple-touch-icon" href="/images/icons/icon-152x152.png">

當capable時候的特別之處在於,啓動WebApp后會進入standalone模式,不會顯示頂部網址欄,不會顯示底部上下頁等操控按鈕。而status-bar-style控制ios頂部顯示信號電信商wifi時間電量的部分,可以選填default的白底黑字、black的黑底白字,或者最進取的black-translucent的app底色白字:









上圖中的navbar的顔色在inline.css裏面設定了為#3f51b5,如果將body background從#ececec改成#3f51b5。改完css檔案之後safari很可能已經cache了舊版本的css檔案,那麽最好在index.html裏面加上<link href="/styles/inline.css?v=1">,WebApp做好了。


























Theme Color

在Android Chrome裏面設定了theme-color可以讓status bar也顯示漂亮的顔色

<!-- CODELAB: Add description here -->
<meta name="description" content="A sample weather app">


<!-- CODELAB: Add meta theme-color -->
<meta name="theme-color" content="#2F3BA2" />














End

My first PWA Progressive Web Application Google Part 02 with Python Flask

主要參考:https://codelabs.developers.google.com/codelabs/your-first-pwapp/#1

Google網頁裏面强烈建議使用Glitch作爲全雲端開發工具,另外一個方法是使用Node.js在自己的電腦運行,然而實際開發中需要使用Python+Flask,於是下載your-first-pwapp-master.zip后,將public文件夾改名成templates,將server.js改寫成main.py及config.json,然後輸入python main.py就會見到Chrome運行網頁

config.json

{
  "Web": [
    {
      "name": "Web01",
      "host": "0.0.0.0",
      "port": 80
    }
  ]
}

main.py

from flask import Flask, request, send_from_directory, render_template, url_for, redirect
import datetime, os, json, logging, webbrowser, requests

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')
    
@app.route('/forecast/<location>')
def forecast(location):
    try:
        BASE_URL = 'https://api.darksky.net/forecast'
        API_KEY = '7cfcae53bb33928e9a7d9a85df825bce'
        url = '/'.join([BASE_URL, API_KEY, location])
        r = requests.get(url)
        return json.dumps(r.json())
    except Exception as e:
        logging.error(e)
        
        fakeForecast = {
          fakeData: True,
          latitude: 0,
          longitude: 0,
          timezone: 'America/New_York',
          currently: {
            time: 0,
            summary: 'Clear',
            icon: 'clear-day',
            temperature: 43.4,
            humidity: 0.62,
            windSpeed: 3.74,
            windBearing: 208,
          },
          daily: {
            data: [
              {
                time: 0,
                icon: 'partly-cloudy-night',
                sunriseTime: 1553079633,
                sunsetTime: 1553123320,
                temperatureHigh: 52.91,
                temperatureLow: 41.35,
              },
              {
                time: 86400,
                icon: 'rain',
                sunriseTime: 1553165933,
                sunsetTime: 1553209784,
                temperatureHigh: 48.01,
                temperatureLow: 44.17,
              },
              {
                time: 172800,
                icon: 'rain',
                sunriseTime: 1553252232,
                sunsetTime: 1553296247,
                temperatureHigh: 50.31,
                temperatureLow: 33.61,
              },
              {
                time: 259200,
                icon: 'partly-cloudy-night',
                sunriseTime: 1553338532,
                sunsetTime: 1553382710,
                temperatureHigh: 46.44,
                temperatureLow: 33.82,
              },
              {
                time: 345600,
                icon: 'partly-cloudy-night',
                sunriseTime: 1553424831,
                sunsetTime: 1553469172,
                temperatureHigh: 60.5,
                temperatureLow: 43.82,
              },
              {
                time: 432000,
                icon: 'rain',
                sunriseTime: 1553511130,
                sunsetTime: 1553555635,
                temperatureHigh: 61.79,
                temperatureLow: 32.8,
              },
              {
                time: 518400,
                icon: 'rain',
                sunriseTime: 1553597430,
                sunsetTime: 1553642098,
                temperatureHigh: 48.28,
                temperatureLow: 33.49,
              },
              {
                time: 604800,
                icon: 'snow',
                sunriseTime: 1553683730,
                sunsetTime: 1553728560,
                temperatureHigh: 43.58,
                temperatureLow: 33.68,
              }
            ]
          }
        }
        
        if location.split(',')==2:
            result['latitude'] = location.split(',')[0]
            result['longitude'] = location.split(',')[1]
        
        return json.dumps(fakeForecast)

@app.route('/<path:path>')
def path(path):
    if path.endswith(('.js', '.css', '.png', '.ico', 'manifest.json', '.svg')):
        return send_from_directory("templates", path)
    return redirect(url_for('index'))
    
def init(name):
    os.chdir(os.path.dirname(os.path.abspath(__file__)))
    now = datetime.datetime.utcnow().strftime("%Y%m%d.%H%M%S")
    fileName = '.'.join([name, now, str(os.getpid()), 'log'])
    logPath = 'logs'
    os.makedirs(logPath, exist_ok=True)
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]  %(message)s",
        handlers=[
            logging.FileHandler("{0}/{1}".format('logs', fileName)),
            logging.StreamHandler()
    ])
    
def run_flask():
    os.chdir(os.path.dirname(os.path.abspath(__file__)))
    host='127.0.0.1'
    port=80
    with open('config.json', 'r') as infile:
        data = json.load(infile)
        print(data)
        web = data["Web"][0]
        host = web["host"]
        port = web["port"]
    webbrowser.open('http://{}:{}'.format('127.0.0.1' if host=='0.0.0.0' else host, port))
    app.secret_key = os.urandom(12)
    app.run(host=host, port=port)

    
if __name__ == "__main__":
    init('flask')
    run_flask()









End

2019年7月3日 星期三

My first PWA Progressive Web Application Google Part 01


主要參考:
https://codelabs.developers.google.com/codelabs/your-first-pwapp/#0


1. API

首先去darksky.net注冊并且得到一個DARKSKY_API_KEY,我更改了一點后的Key是7cfcae53bb33928e9a7d9a85df825bce,於是可以測試HTTP GET返回的JSON:
https://api.darksky.net/forecast/7cfcae53bb33928e9a7d9a85df825bce/40.7720232,-73.9732319


2. Glitch

去https://glitch.com注冊一個賬號然後Clone from Git Repo,輸入https://github.com/googlecodelabs/your-first-pwapp.git,將Dark Sky API key寫在.env檔案裏面,按下Show Next to the Code,見到很有Google味道的界面以及天氣溫度就算是成功了。
























































3. manifest.json

index.html裏面填上<link rel="manifest" href="/manifest.json">,加入<meta>以及關於apple-mobile-web-app等東西,加入<meta> description,加入<meta> theme-color。

4. 基本離綫體驗

要讓離綫時候畫面有資料并且返回http 200,需要注冊service worker,填上需要緩存的檔案例如offline.html,


End

2019年4月26日 星期五

J1900 Performance

J1900

J3455 Comparison


J3455 ESXi 6.7 + Windows 10 1GB on SSD datastore reads at 60MB/s while DSM 6.1 2GB with ASMedia passthrought gives max speed at 110MB/s to J1900 over Netgear R6400.

Windows 10


BareMetal Windows 10 files read at 110MB/s.
After Hyper-V installed, dropped to 60MB/s.
Hyper-V supports only DSM5.2 but not DSM 6.1 so no nfs mounting allowed.

BareMetal Windows + Virtual Box 6 installed still reads at 110MB/s with no performance loss. Virtual Box 6 supports DSM 6.1 but even though using Virtual Box raw disk, DSM 6.1 writes speed at only 20MB/s and fluctuates from 5MB/s to 30MB/s.

DSM 6.1


BareMetal DSM 6.1 reads at 110MB/s while sync data from J3455.
But DSM VMM Windows 10 reads at 15MB/s and Windows UI response slow.

ESXi 6.7


Uploading Windows 10 iso file 4GB to ESXi SSD datastore seems slow.
Windows 10 first installation feels slow.
Windows 10 2CPU 2GB on ESXi 6.7 SSD datastore reads J3455 at 55MB/s, not too bad.

2019年4月25日 星期四

Static and dynamic link ZeroMQ on Windows for Visual Studio 2017 x64




Static ZeroMQ (difficult setup)

cd /d C:\
mkdir Repos
cd /d C:\Repos\
git clone https://github.com/Microsoft/vcpkg
cd /d C:\Repos\vcpkg\
bootstrap-vcpkg.bat
cd /d C:\Repos\vcpkg\
vcpkg install zeromq:x64-windows-static

Visual Studio 2017 creates empty project and a.cpp
#include <zmq.h>
#include <iostream>

#ifdef _DEBUG
#pragma comment(lib,"libzmq-mt-sgd-4_3_2.lib")
#else
#pragma comment(lib,"libzmq-mt-s-4_3_2.lib")
#endif
#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib,"Iphlpapi.lib")
 
int main()
{
 int major = 0;
 int minor = 0;
 int patch = 0;
 zmq_version( &major, &minor, &patch );
 std::wcout << "Current 0MQ version is " << major << '.' << minor << '.' << patch << '\n';
}

Copy files to folder of a.cpp from
C:\Repos\vcpkg\packages\zeromq_x64-windows-static\include
zmq.h
zmq_utils.h
Copy from C:\Repos\vcpkg\packages\zeromq_x64-windows-static\lib\libzmq-mt-s-4_3_2.lib
C:\Repos\vcpkg\packages\zeromq_x64-windows-static\debug\lib\libzmq-mt-sgd-4_3_2.lib

Preprocessor Definitions:
ZMQ_STATIC

Debug Code Generation from /MDd to /MTd
Release Code Generation from /MD to /MT


Dynamic ZeroMQ (simpler setup)


cd /d C:\Repos\vcpkg\
vcpkg install zeromq:x64-windows

Visual Studio 2017 creates empty project and a.cpp
#include "zmq.h"
#include <iostream>

#ifdef _DEBUG
#pragma comment(lib,"libzmq-mt-sgd-4_3_2.lib")
#else
#pragma comment(lib,"libzmq-mt-s-4_3_2.lib")
#endif
#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib,"Iphlpapi.lib")
 
int main()
{
 int major = 0;
 int minor = 0;
 int patch = 0;
 zmq_version( &major, &minor, &patch );
 std::wcout << "Current 0MQ version is " << major << '.' << minor << '.' << patch << '\n';
}
Copy to folder beside a.cpp from
C:\Repos\vcpkg\packages\zeromq_x64-windows\include
zmq.h
zmq_utils.h
C:\Repos\vcpkg\packages\zeromq_x64-windows\debug\lib\libzmq-mt-gd-4_3_2.lib
C:\Repos\vcpkg\packages\zeromq_x64-windows\lib\libzmq-mt-4_3_2.lib
C:\Repos\vcpkg\packages\zeromq_x64-windows\debug\bin\libzmq-mt-gd-4_3_2.dll
C:\Repos\vcpkg\packages\zeromq_x64-windows\bin\libzmq-mt-4_3_2.dll

Static ZeroMQ (Original full version)



https://joshuaburkholder.com/wordpress/2018/05/25/build-and-static-link-zeromq-on-windows/









Build and static link ZeroMQ on Windows


ZeroMQ ( http://zeromq.org and https://github.com/zeromq/libzmq ) is a library that allows code to communicate between threads, processes, or computers in just a few lines and uses simple, composable patterns (like publish-subscribe and broadcast).
In this post, we’ll build ZeroMQ on Windows as a static library (to take advantage of the “static linking exception” in its license: http://zeromq.org/area:licensing ) and then bake that static library into a simple Windows executable.  There are many posts around the web that show you how to do this … here’s one more:

Steps:

  1. Build Vcpkg ( https://github.com/Microsoft/vcpkg )
  2. Use vcpkg to build ZeroMQ ( vcpkg install zeromq:x64-windows-static )
  3. Build an executable that statically links ZeroMQ

Step 1: Build Vcpkg ( https://github.com/Microsoft/vcpkg )

Notes:
  • Vcpkg does not manage pre-built binaries (like NuGet or Homebrew)
  • Vcpkg manages source code and builds that source code on Windows, Linux, and MacOS.
  • At the time of this post, the documentation for Vcpkg was located here:
    https://docs.microsoft.com/en-us/cpp/vcpkg
In a Visual Studio 2017 developer command prompt (with Git installed), execute the following commands:
cd /d C:\
mkdir Repos
cd /d C:\Repos\
git clone https://github.com/Microsoft/vcpkg
cd /d C:\Repos\vcpkg\
bootstrap-vcpkg.bat
… now, C:\Repos\vcpkg\vcpkg.exe should exist.

Step 2: Use vcpkg to build ZeroMQ ( vcpkg install zeromq:x64-windows-static )

Note:
  • On purpose … to make things more explicit and more difficult in Step 3, we do not execute the following command:
vcpkg integrate install
Now that C:\Repos\vcpkg\vcpkg.exe exists, execute the following commands:
cd /d C:\Repos\vcpkg\
vcpkg install zeromq:x64-windows-static
… now, we should have the following:
  • ZeroMQ source code folder: C:\Repos\vcpkg\buildtrees\zeromq\src
  • ZeroMQ debug build folder: C:\Repos\vcpkg\buildtrees\zeromq\x64-windows-static-dbg
  • ZeroMQ release build folder: C:\Repos\vcpkg\buildtrees\zeromq\x64-windows-static-rel
  • ZeroMQ target folder: C:\Repos\vcpkg\packages\zeromq_x64-windows-static
  • ZeroMQ target include folder: C:\Repos\vcpkg\packages\zeromq_x64-windows-static\include
  • ZeroMQ target debug lib folder: C:\Repos\vcpkg\packages\zeromq_x64-windows-static\debug\lib
    • At the time of this post, the static library built was: libzmq-mt-sgd-4_3_1.lib
    • Note: The mt and d in libzmq-mt-sgd-4_3_1.lib means multi-threaded debug (requiring the debug executable in the next step to be compiled using /MTd)
  • ZeroMQ target release lib folder: C:\Repos\vcpkg\packages\zeromq_x64-windows-static\lib
    • At the time of this post, the static library built was: libzmq-mt-s-4_3_1.lib
    • Note: The mt in libzmq-mt-s-4_3_1.lib means multi-threaded (requiring the release executable in the next step to be compiled using /MT)

Step 3: Build an executable that statically links ZeroMQ

In Visual Studio 2017, do the following:
  • File / New / Project…



     
  • Add / New Item…

     
  • Paste the following code into Source.cpp:
    #include <zmq.h>
    #include <iostream>
     
    int main()
    {
     int major = 0;
     int minor = 0;
     int patch = 0;
     zmq_version( &major, &minor, &patch );
     std::wcout << "Current 0MQ version is " << major << '.' << minor << '.' << patch << '\n';
    }
  • Change the Solution Platform to x64:

     
  • Select the “ZeroMQ-Version” project, select Project / Properties, change the Configuration to “All Configurations“, select Configuration Properties / C/C++ / General, and then add the following include folder to “Additional Include Directories“:
    C:\Repos\vcpkg\packages\zeromq_x64-windows-static\include



     
  • Next, for “All Configurations“, select Configuration Properties / C/C++ / Preprocessor, and then add the following preprocessor definition to “Preprocessor Definitions“:
    ZMQ_STATIC

     
  • Next, change the Configuration to “Debug“, select Configuration Properties / C/C++ / Code Generation, and then change the “Runtime Library” to “Multi-threaded Debug (/MTd)“:



     
  • Next, change the Configuration to “Release“, select Configuration Properties / C/C++ / Code Generation, and then change the “Runtime Library” to “Multi-threaded (/MT)“:



     
  • Next, we’ll add the static libraries … and while we could break these up into separate lib folder and lib file entries, I’ll just use each lib’s full file path here.
  • First, switch the Configuration back to “Debug“, select Configuration Properties / Linker / Input, and then add the following entries to “Additional Dependencies“:
    C:\Repos\vcpkg\packages\zeromq_x64-windows-static\debug\lib\libzmq-mt-sgd-4_3_1.lib
    Ws2_32.lib
    Iphlpapi.lib



     
  • Second, switch the Configuration back to “Release“, select Configuration Properties / Linker / Input, and then add the following entries to “Additional Dependencies“:
    C:\Repos\vcpkg\packages\zeromq_x64-windows-static\lib\libzmq-mt-s-4_3_1.lib
    Ws2_32.lib
    Iphlpapi.lib



     
  • Build / Rebuild Solution:

     
  • Debug / Start Without Debugging:

     
Note:
  • When building for Debug, my Output window reads:
    1>------ Rebuild All started: Project: ZeroMQ-Version, Configuration: Debug x64 ------
    1>Source.cpp
    1>ZeroMQ-Version.vcxproj -> C:\Repos\ZeroMQ-Version\x64\Debug\ZeroMQ-Version.exe
    ========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
  • When building for Release, my Output window reads:
    1>------ Rebuild All started: Project: ZeroMQ-Version, Configuration: Release x64 ------
    1>Source.cpp
    1>Generating code
    1>All 3752 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
    1>Finished generating code
    1>ZeroMQ-Version.vcxproj -> C:\Repos\ZeroMQ-Version\x64\Release\ZeroMQ-Version.exe
    ========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
Hope This Helps!
Tagged on: 

2007 to 2023 HP and Dell Servers Comparison

  HP Gen5 to Gen11  using ChatGPT HP ProLiant Gen Active Years CPU Socket Popular HP CPUs Cores Base Clock Max RAM Capacity Comparable Dell ...