瀏覽代碼

重构完成

James Iter 7 年之前
父節點
當前提交
462d3f47dc
共有 100 個文件被更改,包括 576 次插入150 次删除
  1. 二進制
      .DS_Store
  2. 2 2
      generate_state_code_doc.py
  3. 288 0
      jimvc/__init__.py
  4. 0 0
      jimvc/api/__init__.py
  5. 1 1
      jimvc/api/base.py
  6. 3 3
      jimvc/api/config.py
  7. 1 1
      jimvc/api/dashboard.py
  8. 9 9
      jimvc/api/disk.py
  9. 19 19
      jimvc/api/guest.py
  10. 2 2
      jimvc/api/guest_performance.py
  11. 3 3
      jimvc/api/host.py
  12. 2 2
      jimvc/api/host_performance.py
  13. 4 4
      jimvc/api/log.py
  14. 4 4
      jimvc/api/os_template_image.py
  15. 6 6
      jimvc/api/os_template_initialize_operate.py
  16. 4 4
      jimvc/api/os_template_initialize_operate_set.py
  17. 4 4
      jimvc/api/os_template_profile.py
  18. 7 7
      jimvc/api/snapshot.py
  19. 6 6
      jimvc/api/ssh_key.py
  20. 5 5
      jimvc/api/user.py
  21. 4 16
      jimvc/api_route_table.py
  22. 18 7
      jimvc/models/__init__.py
  23. 4 4
      jimvc/models/config.py
  24. 2 2
      jimvc/models/database.py
  25. 12 12
      jimvc/models/event_processor.py
  26. 0 0
      jimvc/models/filter.py
  27. 1 1
      jimvc/models/guest.py
  28. 1 1
      jimvc/models/guest_performance.py
  29. 3 3
      jimvc/models/guest_xml.py
  30. 2 2
      jimvc/models/host.py
  31. 0 0
      jimvc/models/host_performance.py
  32. 5 5
      jimvc/models/initialize.py
  33. 0 0
      jimvc/models/jimvc_exception.py
  34. 2 2
      jimvc/models/log.py
  35. 1 1
      jimvc/models/orm.py
  36. 2 2
      jimvc/models/os_template_image.py
  37. 2 2
      jimvc/models/os_template_initialize_operate.py
  38. 2 2
      jimvc/models/os_template_initialize_operate_set.py
  39. 2 2
      jimvc/models/os_template_profile.py
  40. 0 0
      jimvc/models/rules.py
  41. 0 0
      jimvc/models/snapshot.py
  42. 0 0
      jimvc/models/snapshot_disk_mapping.py
  43. 0 0
      jimvc/models/ssh_key.py
  44. 0 0
      jimvc/models/ssh_key_guest_mapping.py
  45. 0 0
      jimvc/models/status.py
  46. 0 0
      jimvc/models/user.py
  47. 141 3
      jimvc/models/utils.py
  48. 1 0
      jimvc/state_code.py
  49. 0 0
      jimvc/tests/__init__.py
  50. 1 1
      jimvc/tests/main.py
  51. 0 0
      jimvc/tests/test_boot_job.py
  52. 0 0
      jimvc/tests/test_config.py
  53. 0 0
      jimvc/tests/test_disk.py
  54. 0 0
      jimvc/tests/test_guest.py
  55. 0 0
      jimvc/tests/test_operate_rule.py
  56. 0 0
      jimvc/tests/test_os_template.py
  57. 0 0
      jimvc/themes/default/info.json
  58. 0 0
      jimvc/themes/default/license.txt
  59. 0 0
      jimvc/themes/default/static/applications/mailbox.css
  60. 0 0
      jimvc/themes/default/static/avatar/Burung-Pelatuk_144x144.png
  61. 0 0
      jimvc/themes/default/static/avatar/Burung-Pelatuk_144x144@2x.png
  62. 0 0
      jimvc/themes/default/static/bootstrap-select/css/bootstrap-select.css
  63. 0 0
      jimvc/themes/default/static/bootstrap-select/css/bootstrap-select.css.map
  64. 0 0
      jimvc/themes/default/static/bootstrap-select/css/bootstrap-select.min.css
  65. 0 0
      jimvc/themes/default/static/bootstrap-select/js/bootstrap-select.js
  66. 0 0
      jimvc/themes/default/static/bootstrap-select/js/bootstrap-select.js.map
  67. 0 0
      jimvc/themes/default/static/bootstrap-select/js/bootstrap-select.min.js
  68. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-ar_AR.js
  69. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-ar_AR.min.js
  70. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-bg_BG.js
  71. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-bg_BG.min.js
  72. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-cro_CRO.js
  73. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-cro_CRO.min.js
  74. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-cs_CZ.js
  75. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-cs_CZ.min.js
  76. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-da_DK.js
  77. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-da_DK.min.js
  78. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-de_DE.js
  79. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-de_DE.min.js
  80. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-en_US.js
  81. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-en_US.min.js
  82. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-es_CL.js
  83. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-es_CL.min.js
  84. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-es_ES.js
  85. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-es_ES.min.js
  86. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-et_EE.js
  87. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-et_EE.min.js
  88. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-eu.js
  89. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-eu.min.js
  90. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fa_IR.js
  91. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fa_IR.min.js
  92. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fi_FI.js
  93. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fi_FI.min.js
  94. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fr_FR.js
  95. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fr_FR.min.js
  96. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-hu_HU.js
  97. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-hu_HU.min.js
  98. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-id_ID.js
  99. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-id_ID.min.js
  100. 0 0
      jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-it_IT.js

二進制
.DS_Store


+ 2 - 2
generate_state_code_doc.py

@@ -1,14 +1,14 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 """
-    Usage: python generate_state_code_doc.py > docs/state_code.md
+    Usage: python generate_state_code_doc.py > ../docs/state_code.md
 """
 
 
 from collections import OrderedDict
 
 import jimit as ji
-from state_code import *
+from jimvc.state_code import *
 
 
 __author__ = 'James Iter'

+ 288 - 0
jimvc/__init__.py

@@ -0,0 +1,288 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+import traceback
+import time
+from datetime import timedelta
+import jimit as ji
+import json
+
+import os
+from flask import g, request, redirect, url_for, Response, session, Flask
+
+try:
+    from flask_session import Session
+except ImportError as e:
+    # 兼容老版本
+    from flask.ext.session import Session
+from flask.ext.themes2 import Themes, packaged_themes_loader
+from werkzeug.debug import get_current_traceback
+
+app = Flask(__name__)
+
+from jimvc.models.initialize import logger, Init, app_config, dev_table
+
+import api_route_table
+import views_route_table
+
+from jimvc.models import Utils
+from jimvc.models import EventProcessor
+from jimvc.models import Database as db
+from jimvc.models import Config
+from jimvc.models import User
+from jimvc.api.user import blueprint as user_blueprint
+
+from jimvc.api.os_template_image import blueprint as os_template_image_blueprint
+from jimvc.api.os_template_image import blueprints as os_template_image_blueprints
+from jimvc.api.os_template_initialize_operate_set import blueprint as os_template_initialize_operate_set_blueprint
+from jimvc.api.os_template_initialize_operate_set import blueprints as os_template_initialize_operate_set_blueprints
+from jimvc.api.os_template_initialize_operate import blueprint as os_template_initialize_operate_blueprint
+from jimvc.api.os_template_initialize_operate import blueprints as os_template_initialize_operate_blueprints
+from jimvc.api.os_template_profile import blueprint as os_template_profile_blueprint
+from jimvc.api.os_template_profile import blueprints as os_template_profile_blueprints
+from jimvc.api.guest import blueprint as guest_blueprint
+from jimvc.api.guest import blueprints as guest_blueprints
+from jimvc.api.disk import blueprint as disk_blueprint
+from jimvc.api.disk import blueprints as disk_blueprints
+from jimvc.api.config import blueprint as config_blueprint
+from jimvc.api.log import blueprint as log_blueprint
+from jimvc.api.log import blueprints as log_blueprints
+from jimvc.api.host import blueprint as host_blueprint
+from jimvc.api.host import blueprints as host_blueprints
+from jimvc.api.ssh_key import blueprint as ssh_key_blueprint
+from jimvc.api.ssh_key import blueprints as ssh_key_blueprints
+from jimvc.api.snapshot import blueprint as snapshot_blueprint
+from jimvc.api.snapshot import blueprints as snapshot_blueprints
+from jimvc.api.guest_performance import blueprint as performance_blueprint
+from jimvc.api.guest_performance import blueprints as performance_blueprints
+from jimvc.api.host_performance import blueprint as host_performance_blueprint
+from jimvc.api.host_performance import blueprints as host_performance_blueprints
+from jimvc.api.dashboard import blueprint as dashboard_blueprint
+from jimvc.api.dashboard import blueprints as dashboard_blueprints
+
+from jimvc.views.error_pages import *
+from jimvc.views.config import blueprint as view_config_blueprint
+from jimvc.views.misc import blueprint as view_misc_blueprint
+from jimvc.views.dashboard import blueprint as view_dashboard_blueprint
+from jimvc.views.guest import blueprint as view_guest_blueprint
+from jimvc.views.guest import blueprints as view_guest_blueprints
+from jimvc.views.disk import blueprint as view_disk_blueprint
+from jimvc.views.disk import blueprints as view_disk_blueprints
+from jimvc.views.log import blueprint as view_log_blueprint
+from jimvc.views.log import blueprints as view_log_blueprints
+from jimvc.views.os_template_image import blueprint as view_os_template_image_blueprint
+from jimvc.views.os_template_image import blueprints as view_os_template_image_blueprints
+from jimvc.views.ssh_key import blueprint as view_ssh_key_blueprint
+from jimvc.views.ssh_key import blueprints as view_ssh_key_blueprints
+from jimvc.views.snapshot import blueprint as view_snapshot_blueprint
+from jimvc.views.snapshot import blueprints as view_snapshot_blueprints
+
+from jimvc.views.host import blueprint as view_host_blueprint
+from jimvc.views.host import blueprints as view_host_blueprints
+
+from websockify.websocketproxy import WebSocketProxy
+
+
+__author__ = 'James Iter'
+__date__ = '2017/3/31'
+__contact__ = 'james.iter.cn@gmail.com'
+__copyright__ = '(c) 2017 by James Iter.'
+
+
+app.jinja_env.add_extension('jinja2.ext.i18n')
+app.jinja_env.add_extension('jinja2.ext.do')
+app.config = dict(app.config, **app_config)
+app.jinja_env.add_extension('jinja2.ext.loopcontrols')
+
+# 替换为Flask-Session
+app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(seconds=app_config['PERMANENT_SESSION_LIFETIME'])
+Session(app)
+Themes(app, app_identifier="JimV-C")
+l = packaged_themes_loader(app)
+pass
+
+
+def instantiation_ws_vnc(listen_port, target_host, target_port):
+    # 用于 Web noVNC 代理
+    ws = WebSocketProxy(listen_host="0.0.0.0", listen_port=listen_port, target_host=target_host,
+                        target_port=target_port, run_once=True, daemon=True, idle_timeout=10)
+    ws.start_server()
+
+
+def ws_engine_for_vnc():
+    logger.info(msg='VNC ws engine is launched.')
+
+    while True:
+        payload = db.r.lpop(app_config['ipc_queue'])
+
+        if payload is None:
+            time.sleep(1)
+            continue
+
+        payload = json.loads(payload)
+
+        c_pid = os.fork()
+        if c_pid == 0:
+            instantiation_ws_vnc(payload['listen_port'], payload['target_host'], payload['target_port'])
+
+        # 因为 WebSocketProxy 使用了 daemon 参数,所以当执行到 ws.start_server() 时,会退出其所在的子进程,
+        # 故而这里设置wait来处理结束的子进程的环境,避免出现僵尸进程。
+        os.wait()
+
+
+def is_not_need_to_auth(endpoint):
+    not_auth_table = [
+        'api_config.r_get',
+        'api_config.r_create',
+        'v_config.create',
+        'v_misc.login',
+        'v_misc.recover_password',
+        'v_misc.reset_password',
+        'api_user.r_sign_in',
+        'api_user.r_reset_password',
+        'api_user.r_send_reset_password_email'
+    ]
+
+    if endpoint in not_auth_table:
+        return True
+
+    return False
+
+
+@app.before_request
+@Utils.dumps2response
+def r_before_request():
+    try:
+        g.ts = ji.Common.ts()
+        if not is_not_need_to_auth(request.endpoint) and request.blueprint is not None and request.method != 'OPTIONS':
+            g.config = Config()
+            g.config.id = 1
+            g.config.get()
+
+            token = session.get('token', '')
+            g.token = Utils.verify_token(token)
+
+            user = User()
+            user.id = g.token['uid']
+
+            try:
+                user.get()
+            except ji.PreviewingError, e:
+                # 如果该用户获取失败,则清除该用户对应的session。因为该用户可能已经被删除。
+                for key in session.keys():
+                    session.pop(key=key)
+                return json.loads(e.message)
+
+    except ji.JITError, e:
+        ret = json.loads(e.message)
+
+        if ret['state']['code'] == '404':
+            return redirect(location=url_for('v_config.create'), Response=Response)
+
+        if ret['state']['sub']['code'] in ['41208']:
+            return redirect(location=url_for('v_misc.login'), Response=Response)
+
+        return ret
+
+
+@app.after_request
+@Utils.dumps2response
+def r_after_request(response):
+    try:
+        # https://developer.mozilla.org/en/HTTP_access_control
+        # (中文版) https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Credentials
+        # http://www.w3.org/TR/cors/
+        # 由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。
+
+        if request.referrer is None:
+            # 跑测试脚本时,用该规则。
+            response.headers['Access-Control-Allow-Origin'] = '*'
+        else:
+            # 生产环境中,如果前后端分离。那么请指定具体的前端域名地址,不要用如下在开发环境中的便捷方式。
+            # -- Access-Control-Allow-Credentials为true,携带cookie时,不允许Access-Control-Allow-Origin为通配符,是浏览器对用户的一种安全保护。
+            # -- 至少能避免登录山寨网站,骗取用户相关信息。
+            response.headers['Access-Control-Allow-Origin'] = '/'.join(request.referrer.split('/')[:3])
+
+        response.headers['Access-Control-Allow-Credentials'] = 'true'
+        response.headers['Access-Control-Allow-Methods'] = 'HEAD, GET, POST, DELETE, OPTIONS, PATCH, PUT'
+        response.headers['Access-Control-Allow-Headers'] = 'X-Request-With, Content-Type'
+        response.headers['Access-Control-Expose-Headers'] = 'Set-Cookie'
+
+        # 少于session生命周期一半时,自动对其续期
+        if not is_not_need_to_auth(request.endpoint) and hasattr(g, 'token') and \
+                g.token['exp'] < (ji.Common.ts() + (app_config['token_ttl'] / 2)):
+            token = Utils.generate_token(g.token['uid'])
+            # 清除原有session,由新session代替
+            for key in session.keys():
+                session.pop(key=key)
+            session['token'] = token
+        return response
+    except ji.JITError, e:
+        return json.loads(e.message)
+
+
+@app.teardown_request
+def teardown_request(exception):
+    if exception:
+        _traceback = get_current_traceback()
+        logger.error(_traceback.plaintext)
+
+
+# noinspection PyBroadException
+try:
+    db.init_conn_mysql()
+    db.init_conn_redis()
+
+    app.register_blueprint(user_blueprint)
+
+    app.register_blueprint(os_template_image_blueprint)
+    app.register_blueprint(os_template_image_blueprints)
+    app.register_blueprint(os_template_initialize_operate_set_blueprint)
+    app.register_blueprint(os_template_initialize_operate_set_blueprints)
+    app.register_blueprint(os_template_initialize_operate_blueprint)
+    app.register_blueprint(os_template_initialize_operate_blueprints)
+    app.register_blueprint(os_template_profile_blueprint)
+    app.register_blueprint(os_template_profile_blueprints)
+    app.register_blueprint(guest_blueprint)
+    app.register_blueprint(guest_blueprints)
+    app.register_blueprint(disk_blueprint)
+    app.register_blueprint(disk_blueprints)
+    app.register_blueprint(config_blueprint)
+    app.register_blueprint(log_blueprint)
+    app.register_blueprint(log_blueprints)
+    app.register_blueprint(host_blueprint)
+    app.register_blueprint(host_blueprints)
+    app.register_blueprint(ssh_key_blueprint)
+    app.register_blueprint(ssh_key_blueprints)
+    app.register_blueprint(snapshot_blueprint)
+    app.register_blueprint(snapshot_blueprints)
+    app.register_blueprint(performance_blueprint)
+    app.register_blueprint(performance_blueprints)
+    app.register_blueprint(host_performance_blueprint)
+    app.register_blueprint(host_performance_blueprints)
+    app.register_blueprint(dashboard_blueprint)
+    app.register_blueprint(dashboard_blueprints)
+
+    app.register_blueprint(view_config_blueprint)
+    app.register_blueprint(view_misc_blueprint)
+    app.register_blueprint(view_dashboard_blueprint)
+    app.register_blueprint(view_guest_blueprint)
+    app.register_blueprint(view_guest_blueprints)
+    app.register_blueprint(view_disk_blueprint)
+    app.register_blueprint(view_disk_blueprints)
+    app.register_blueprint(view_log_blueprint)
+    app.register_blueprint(view_log_blueprints)
+    app.register_blueprint(view_os_template_image_blueprint)
+    app.register_blueprint(view_os_template_image_blueprints)
+    app.register_blueprint(view_ssh_key_blueprint)
+    app.register_blueprint(view_ssh_key_blueprints)
+    app.register_blueprint(view_snapshot_blueprint)
+    app.register_blueprint(view_snapshot_blueprints)
+
+    app.register_blueprint(view_host_blueprint)
+    app.register_blueprint(view_host_blueprints)
+
+except:
+    logger.error(traceback.format_exc())
+

+ 0 - 0
api/__init__.py → jimvc/api/__init__.py


+ 1 - 1
api/base.py → jimvc/api/base.py

@@ -6,7 +6,7 @@ from flask import request
 import json
 import jimit as ji
 
-from models import Rules
+from jimvc.models import Rules
 
 
 __author__ = 'James Iter'

+ 3 - 3
api/config.py → jimvc/api/config.py

@@ -7,9 +7,9 @@ from flask import request
 import jimit as ji
 import json
 
-from models import Config, Disk
-from models import Rules
-from models import Utils
+from jimvc.models import Config, Disk
+from jimvc.models import Rules
+from jimvc.models import Utils
 
 
 __author__ = 'James Iter'

+ 1 - 1
api/dashboard.py → jimvc/api/dashboard.py

@@ -8,7 +8,7 @@ import copy
 import jimit as ji
 from flask import url_for, request, Blueprint
 
-from models import Utils
+from jimvc.models import Utils
 
 
 __author__ = 'James Iter'

+ 9 - 9
api/disk.py → jimvc/api/disk.py

@@ -10,14 +10,14 @@ import requests
 from uuid import uuid4
 import jimit as ji
 
-from models import Guest, DiskState, Host
-from models.initialize import dev_table
-from models import Config
-from models import Disk
-from models import Rules
-from models import Utils
-from models import OSTemplateImage
-from models.status import StorageMode
+from jimvc.models import Guest, DiskState, Host
+from jimvc.models.initialize import dev_table
+from jimvc.models import Config
+from jimvc.models import Disk
+from jimvc.models import Rules
+from jimvc.models import Utils
+from jimvc.models import OSTemplateImage
+from jimvc.models import StorageMode
 
 from base import Base
 
@@ -414,7 +414,7 @@ def r_update(uuids):
 
 @Utils.dumps2response
 def r_distribute_count():
-    from models import Disk
+    from jimvc.models import Disk
     rows, count = Disk.get_all()
 
     ret = dict()

+ 19 - 19
api/guest.py → jimvc/api/guest.py

@@ -14,24 +14,24 @@ import time
 import jimit as ji
 from flask import Blueprint, url_for, request
 
-from api.base import Base
-from models.initialize import dev_table
-from models import app_config
-from models import DiskState, Host
-from models import Database as db
-from models import Config
-from models import Disk
-from models import Rules
-from models import Utils
-from models import Guest
-from models import OSTemplateImage
-from models import OSTemplateProfile
-from models import OSTemplateInitializeOperate
-from models import GuestXML
-from models import SSHKeyGuestMapping
-from models import SSHKey
-from models import Snapshot
-from models import status
+from jimvc.api.base import Base
+from jimvc.models.initialize import dev_table
+from jimvc.models import app_config
+from jimvc.models import DiskState, Host
+from jimvc.models import Database as db
+from jimvc.models import Config
+from jimvc.models import Disk
+from jimvc.models import Rules
+from jimvc.models import Utils
+from jimvc.models import Guest
+from jimvc.models import OSTemplateImage
+from jimvc.models import OSTemplateProfile
+from jimvc.models import OSTemplateInitializeOperate
+from jimvc.models import GuestXML
+from jimvc.models import SSHKeyGuestMapping
+from jimvc.models import SSHKey
+from jimvc.models import Snapshot
+from jimvc.models import status
 
 
 __author__ = 'James Iter'
@@ -1013,7 +1013,7 @@ def r_content_search():
 
 @Utils.dumps2response
 def r_distribute_count():
-    from models import Guest
+    from jimvc.models import Guest
     rows, count = Guest.get_all()
 
     ret = dict()

+ 2 - 2
api/guest_performance.py → jimvc/api/guest_performance.py

@@ -6,8 +6,8 @@ from flask import Blueprint
 import json
 import jimit as ji
 
-from api.base import Base
-from models import GuestCPUMemory, GuestTraffic, GuestDiskIO, Utils, Rules
+from jimvc.api.base import Base
+from jimvc.models import GuestCPUMemory, GuestTraffic, GuestDiskIO, Utils, Rules
 
 
 __author__ = 'James Iter'

+ 3 - 3
api/host.py → jimvc/api/host.py

@@ -8,9 +8,9 @@ import requests
 from flask import Blueprint, request, url_for
 import jimit as ji
 
-from models import app_config
-from models import Database as db
-from models import Utils, Rules, Host
+from jimvc.models import app_config
+from jimvc.models import Database as db
+from jimvc.models import Utils, Rules, Host
 
 
 __author__ = 'James Iter'

+ 2 - 2
api/host_performance.py → jimvc/api/host_performance.py

@@ -7,8 +7,8 @@ import json
 import jimit as ji
 import base64
 
-from api.base import Base
-from models import HostCPUMemory, HostTraffic, HostDiskUsageIO, Utils, Rules
+from jimvc.api.base import Base
+from jimvc.models import HostCPUMemory, HostTraffic, HostDiskUsageIO, Utils, Rules
 
 
 __author__ = 'James Iter'

+ 4 - 4
api/log.py → jimvc/api/log.py

@@ -9,10 +9,10 @@ import jimit as ji
 import requests
 from flask import Blueprint, request, url_for
 
-from api.base import Base
-from models import Log
-from models import Rules
-from models import Utils
+from jimvc.api.base import Base
+from jimvc.models import Log
+from jimvc.models import Rules
+from jimvc.models import Utils
 
 
 __author__ = 'James Iter'

+ 4 - 4
api/os_template_image.py → jimvc/api/os_template_image.py

@@ -10,10 +10,10 @@ from flask import request
 import jimit as ji
 import json
 
-from api.base import Base
-from models import OSTemplateImage, OSTemplateProfile, Host, Config, OSTemplateImageKind, Guest
-from models import Rules
-from models import Utils
+from jimvc.api.base import Base
+from jimvc.models import OSTemplateImage, OSTemplateProfile, Host, Config, OSTemplateImageKind, Guest
+from jimvc.models import Rules
+from jimvc.models import Utils
 
 
 __author__ = 'James Iter'

+ 6 - 6
api/os_template_initialize_operate.py → jimvc/api/os_template_initialize_operate.py

@@ -7,12 +7,12 @@ from flask import request
 import jimit as ji
 import json
 
-from api.base import Base
-from models import Rules
-from models import Utils
-from models import OSTemplateInitializeOperate
-from models import OSTemplateInitializeOperateSet
-from models.status import OSTemplateInitializeOperateKind
+from jimvc.api.base import Base
+from jimvc.models import Rules
+from jimvc.models import Utils
+from jimvc.models import OSTemplateInitializeOperate
+from jimvc.models import OSTemplateInitializeOperateSet
+from jimvc.models import OSTemplateInitializeOperateKind
 
 
 __author__ = 'James Iter'

+ 4 - 4
api/os_template_initialize_operate_set.py → jimvc/api/os_template_initialize_operate_set.py

@@ -7,10 +7,10 @@ from flask import request
 import jimit as ji
 import json
 
-from api.base import Base
-from models import Rules
-from models import Utils
-from models import OSTemplateInitializeOperateSet, OSTemplateInitializeOperate
+from jimvc.api.base import Base
+from jimvc.models import Rules
+from jimvc.models import Utils
+from jimvc.models import OSTemplateInitializeOperateSet, OSTemplateInitializeOperate
 
 
 __author__ = 'James Iter'

+ 4 - 4
api/os_template_profile.py → jimvc/api/os_template_profile.py

@@ -7,10 +7,10 @@ from flask import request
 import jimit as ji
 import json
 
-from api.base import Base
-from models import OSTemplateProfile
-from models import Rules
-from models import Utils
+from jimvc.api.base import Base
+from jimvc.models import OSTemplateProfile
+from jimvc.models import Rules
+from jimvc.models import Utils
 
 
 __author__ = 'James Iter'

+ 7 - 7
api/snapshot.py → jimvc/api/snapshot.py

@@ -11,13 +11,13 @@ import json
 import jimit as ji
 import os
 
-from api.base import Base
-from models import Guest, Config, Disk
-from models import Snapshot, SnapshotDiskMapping
-from models import OSTemplateImage
-from models import Utils
-from models import Rules
-from models import OSTemplateImageKind
+from jimvc.api.base import Base
+from jimvc.models import Guest, Config, Disk
+from jimvc.models import Snapshot, SnapshotDiskMapping
+from jimvc.models import OSTemplateImage
+from jimvc.models import Utils
+from jimvc.models import Rules
+from jimvc.models import OSTemplateImageKind
 
 
 __author__ = 'James Iter'

+ 6 - 6
api/ssh_key.py → jimvc/api/ssh_key.py

@@ -11,12 +11,12 @@ from werkzeug.datastructures import ImmutableMultiDict
 import json
 import jimit as ji
 
-from api.base import Base
-from models import SSHKey, OSTemplateImage, OSTemplateProfile, GuestState
-from models import SSHKeyGuestMapping
-from models import Guest
-from models import Utils
-from models import Rules
+from jimvc.api.base import Base
+from jimvc.models import SSHKey, OSTemplateImage, OSTemplateProfile, GuestState
+from jimvc.models import SSHKeyGuestMapping
+from jimvc.models import Guest
+from jimvc.models import Utils
+from jimvc.models import Rules
 
 
 __author__ = 'James Iter'

+ 5 - 5
api/user.py → jimvc/api/user.py

@@ -8,11 +8,11 @@ from flask import session
 import json
 import jimit as ji
 
-from api.base import Base
-from models import app_config
-from models import User
-from models import Utils
-from models import Rules
+from jimvc.api.base import Base
+from jimvc.models import app_config
+from jimvc.models import User
+from jimvc.models import Utils
+from jimvc.models import Rules
 
 
 __author__ = 'James Iter'

+ 4 - 16
api_route_table.py → jimvc/api_route_table.py

@@ -2,22 +2,10 @@
 # -*- coding: utf-8 -*-
 
 
-from models.utils import add_rule_api
-from api import dashboard
-from api import config
-from api import user
-from api import guest
-from api import disk
-from api import snapshot
-from api import os_template_image
-from api import os_template_profile
-from api import os_template_initialize_operate_set
-from api import os_template_initialize_operate
-from api import log
-from api import host
-from api import guest_performance
-from api import host_performance
-from api import ssh_key
+from jimvc.models import add_rule_api
+from jimvc.api import config, os_template_profile, snapshot, os_template_initialize_operate, user, ssh_key, \
+    os_template_image, guest_performance, disk, log, os_template_initialize_operate_set, dashboard, guest, host, \
+    host_performance
 
 
 __author__ = 'James Iter'

+ 18 - 7
models/__init__.py → jimvc/models/__init__.py

@@ -5,7 +5,8 @@
 from initialize import (
     Init,
     app_config,
-    logger
+    logger,
+    dev_table
 )
 
 from rules import (
@@ -13,7 +14,9 @@ from rules import (
 )
 
 from utils import (
-    Utils
+    Utils,
+    add_rule_api,
+    add_rule_views
 )
 
 from database import (
@@ -38,7 +41,9 @@ from config import (
 )
 
 from guest import (
-    Guest, Disk
+    Guest,
+    Disk,
+    GuestMigrateInfo
 )
 
 from ssh_key import (
@@ -71,7 +76,11 @@ from status import (
     ResponseState,
     DiskState,
     LogLevel,
-    OSTemplateImageKind
+    OSTemplateImageKind,
+    StorageMode,
+    GuestCollectionPerformanceDataKind,
+    HostCollectionPerformanceDataKind,
+    OSTemplateInitializeOperateKind
 )
 
 from guest_xml import (
@@ -119,9 +128,11 @@ __copyright__ = '(c) 2017 by James Iter.'
 
 __all__ = [
     'Rules', 'Utils', 'Init', 'app_config', 'logger', 'Database', 'FilterFieldType', 'Filter', 'EmitKind', 'GuestState',
-    'DiskState', 'LogLevel', 'ORM', 'User', 'Config', 'Guest', 'Disk', 'GuestXML', 'Log', 'SSHKey',
-    'SSHKeyGuestMapping', 'OSTemplateImage', 'OSTemplateProfile', 'OSTemplateInitializeOperateSet',
+    'DiskState', 'LogLevel', 'ORM', 'User', 'Config', 'Guest', 'Disk', 'GuestXML', 'Log', 'SSHKey', 'add_rule_api',
+    'SSHKeyGuestMapping', 'OSTemplateImage', 'OSTemplateProfile', 'OSTemplateInitializeOperateSet', 'add_rule_views',
     'OSTemplateInitializeOperate', 'EventProcessor', 'ResponseState', 'GuestCPUMemory', 'GuestTraffic', 'GuestDiskIO',
-    'HostCPUMemory', 'HostTraffic', 'HostDiskUsageIO', 'Host', 'Snapshot', 'SnapshotDiskMapping', 'OSTemplateImageKind'
+    'HostCPUMemory', 'HostTraffic', 'HostDiskUsageIO', 'Host', 'Snapshot', 'SnapshotDiskMapping', 'OSTemplateImageKind',
+    'GuestMigrateInfo', 'GuestCollectionPerformanceDataKind', 'HostCollectionPerformanceDataKind', 'StorageMode',
+    'OSTemplateInitializeOperateKind', 'dev_table'
 ]
 

+ 4 - 4
models/config.py → jimvc/models/config.py

@@ -6,10 +6,10 @@ import json
 import jimit as ji
 from IPy import IP, intToIp
 
-from models import app_config
-from models import Database as db
-from models import ORM
-from models import status
+from jimvc.models import app_config
+from jimvc.models import Database as db
+from jimvc.models import ORM
+from jimvc.models import status
 
 
 __author__ = 'James Iter'

+ 2 - 2
models/database.py → jimvc/models/database.py

@@ -11,8 +11,8 @@ from mysql.connector import errorcode
 import time
 import jimit as ji
 
-from models import app_config
-from models import logger
+from jimvc.models import app_config
+from jimvc.models import logger
 
 
 __author__ = 'James Iter'

+ 12 - 12
models/event_processor.py → jimvc/models/event_processor.py

@@ -8,18 +8,18 @@ import time
 from IPy import IP
 import jimit as ji
 
-from models import logger, app_config
-from models import Database as db, Config, GuestCPUMemory, GuestTraffic, GuestDiskIO, SSHKeyGuestMapping
-from models import Guest
-from models import Disk
-from models import Snapshot, SnapshotDiskMapping, OSTemplateImage
-from models import Log
-from models import Utils
-from models import EmitKind
-from models import ResponseState, GuestState, DiskState
-from models.guest import GuestMigrateInfo
-from models.status import GuestCollectionPerformanceDataKind, HostCollectionPerformanceDataKind
-from models import HostCPUMemory, HostTraffic, HostDiskUsageIO
+from jimvc.models import logger, app_config
+from jimvc.models import Database as db, Config, GuestCPUMemory, GuestTraffic, GuestDiskIO, SSHKeyGuestMapping
+from jimvc.models import Guest
+from jimvc.models import Disk
+from jimvc.models import Snapshot, SnapshotDiskMapping, OSTemplateImage
+from jimvc.models import Log
+from jimvc.models import Utils
+from jimvc.models import EmitKind
+from jimvc.models import ResponseState, GuestState, DiskState
+from jimvc.models import GuestMigrateInfo
+from jimvc.models import GuestCollectionPerformanceDataKind, HostCollectionPerformanceDataKind
+from jimvc.models import HostCPUMemory, HostTraffic, HostDiskUsageIO
 
 
 __author__ = 'James Iter'

+ 0 - 0
models/filter.py → jimvc/models/filter.py


+ 1 - 1
models/guest.py → jimvc/models/guest.py

@@ -95,7 +95,7 @@ class Disk(ORM):
 
     def quota(self, config=None):
 
-        from models import Config
+        from jimvc.models import Config
         assert isinstance(config, Config)
 
         # 系统盘 IOPS 默认不计算增益

+ 1 - 1
models/guest_performance.py → jimvc/models/guest_performance.py

@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 
-from models import ORM, FilterFieldType
+from jimvc.models import ORM, FilterFieldType
 
 
 __author__ = 'James Iter'

+ 3 - 3
models/guest_xml.py → jimvc/models/guest_xml.py

@@ -2,9 +2,9 @@
 # -*- coding: utf-8 -*-
 
 
-from models import Config, Disk
-from models import Guest
-from models import status
+from jimvc.models import Config, Disk
+from jimvc.models import Guest
+from jimvc.models import status
 
 
 __author__ = 'James Iter'

+ 2 - 2
models/host.py → jimvc/models/host.py

@@ -5,8 +5,8 @@
 import json
 from flask import g
 
-from models import app_config
-from models import Database as db
+from jimvc.models import app_config
+from jimvc.models import Database as db
 
 
 __author__ = 'James Iter'

+ 0 - 0
models/host_performance.py → jimvc/models/host_performance.py


+ 5 - 5
models/initialize.py → jimvc/models/initialize.py

@@ -15,7 +15,7 @@ import time
 import errno
 
 from jimvc_exception import PathNotExist
-from state_code import own_state_branch
+from jimvc.state_code import own_state_branch
 
 
 reload(sys)
@@ -128,8 +128,8 @@ class Init(object):
 
     @staticmethod
     def pub_sub_ping_pong():
-        from models import Database as db
-        from models import Utils
+        from jimvc.models import Database as db
+        from jimvc.models import Utils
 
         logger.info(msg='PS PING PONG engine is launched.')
         while True:
@@ -148,8 +148,8 @@ class Init(object):
 
     @staticmethod
     def clear_expire_monitor_log():
-        from models import GuestCPUMemory, GuestTraffic, GuestDiskIO, HostCPUMemory, HostTraffic, HostDiskUsageIO
-        from models import Utils
+        from jimvc.models import GuestCPUMemory, GuestTraffic, GuestDiskIO, HostCPUMemory, HostTraffic, HostDiskUsageIO
+        from jimvc.models import Utils
 
         already_clear = False
         the_time = '03:30'

+ 0 - 0
models/jimvc_exception.py → jimvc/models/jimvc_exception.py


+ 2 - 2
models/log.py → jimvc/models/log.py

@@ -2,8 +2,8 @@
 # -*- coding: utf-8 -*-
 
 
-from models import FilterFieldType
-from models import ORM
+from jimvc.models import FilterFieldType
+from jimvc.models import ORM
 
 
 __author__ = 'James Iter'

+ 1 - 1
models/orm.py → jimvc/models/orm.py

@@ -7,7 +7,7 @@ import jimit as ji
 from mysql.connector import errorcode, errors
 
 from database import Database as db
-from models import Filter
+from jimvc.models import Filter
 
 
 __author__ = 'James Iter'

+ 2 - 2
models/os_template_image.py → jimvc/models/os_template_image.py

@@ -4,8 +4,8 @@
 
 import jimit as ji
 
-from models import FilterFieldType
-from models import ORM
+from jimvc.models import FilterFieldType
+from jimvc.models import ORM
 
 
 __author__ = 'James Iter'

+ 2 - 2
models/os_template_initialize_operate.py → jimvc/models/os_template_initialize_operate.py

@@ -2,8 +2,8 @@
 # -*- coding: utf-8 -*-
 
 
-from models import FilterFieldType
-from models import ORM
+from jimvc.models import FilterFieldType
+from jimvc.models import ORM
 
 
 __author__ = 'James Iter'

+ 2 - 2
models/os_template_initialize_operate_set.py → jimvc/models/os_template_initialize_operate_set.py

@@ -2,8 +2,8 @@
 # -*- coding: utf-8 -*-
 
 
-from models import FilterFieldType
-from models import ORM
+from jimvc.models import FilterFieldType
+from jimvc.models import ORM
 
 
 __author__ = 'James Iter'

+ 2 - 2
models/os_template_profile.py → jimvc/models/os_template_profile.py

@@ -2,8 +2,8 @@
 # -*- coding: utf-8 -*-
 
 
-from models import FilterFieldType
-from models import ORM
+from jimvc.models import FilterFieldType
+from jimvc.models import ORM
 
 
 __author__ = 'James Iter'

+ 0 - 0
models/rules.py → jimvc/models/rules.py


+ 0 - 0
models/snapshot.py → jimvc/models/snapshot.py


+ 0 - 0
models/snapshot_disk_mapping.py → jimvc/models/snapshot_disk_mapping.py


+ 0 - 0
models/ssh_key.py → jimvc/models/ssh_key.py


+ 0 - 0
models/ssh_key_guest_mapping.py → jimvc/models/ssh_key_guest_mapping.py


+ 0 - 0
models/status.py → jimvc/models/status.py


+ 0 - 0
models/user.py → jimvc/models/user.py


+ 141 - 3
models/utils.py → jimvc/models/utils.py

@@ -7,15 +7,18 @@ import socket
 import commands
 import jimit as ji
 import json
+import time
 
 from flask import make_response, g, request
 from flask.wrappers import Response
 from werkzeug.utils import import_string, cached_property
 import jwt
 
-from models import app_config, logger
+from jimvc.models import app_config, logger, dev_table
 from database import Database as db
 
+from jimvc import app
+
 
 __author__ = 'James Iter'
 __date__ = '2017/03/01'
@@ -152,10 +155,145 @@ class LazyView(object):
 
 
 def add_rule_api(blueprint, rule, api_func=None, **options):
-    blueprint.add_url_rule(rule=rule, view_func=LazyView(''.join(['api.', api_func])), **options)
+    blueprint.add_url_rule(rule=rule, view_func=LazyView(''.join(['jimvc.api.', api_func])), **options)
 
 
 def add_rule_views(blueprint, rule, views_func=None, **options):
-    blueprint.add_url_rule(rule=rule, view_func=LazyView(''.join(['views.', views_func])), **options)
+    blueprint.add_url_rule(rule=rule, view_func=LazyView(''.join(['jimvc.views.', views_func])), **options)
+
+
+@app.context_processor
+def utility_processor():
+    def format_price(amount, currency=u'¥'):
+        return u'{0:.2f}{1}'.format(amount, currency)
+
+    def format_datetime_by_ts(ts, fmt='%Y-%m-%d %H:%M'):
+        return time.strftime(fmt, time.localtime(ts))
+
+    def format_datetime_by_tus(tus, fmt='%y-%m-%d %H:%M'):
+        return time.strftime(fmt, time.localtime(tus / 1000 / 1000))
+
+    def format_guest_status(_status, progress):
+        from jimvc.models import GuestState
+
+        color = 'FF645B'
+        icon = 'glyph-icon icon-bolt'
+        desc = '未知状态'
+
+        if _status == GuestState.booting.value:
+            color = '00BBBB'
+            icon = 'glyph-icon icon-circle'
+            desc = '启动中'
+
+        elif _status == GuestState.running.value:
+            color = '00BB00'
+            icon = 'glyph-icon icon-circle'
+            desc = '运行中'
+
+        elif _status in [GuestState.no_state.value, GuestState.creating.value]:
+            color = 'FFC543'
+            icon = 'glyph-icon icon-spinner'
+            desc = ' '.join(['创建中', str(progress) + '%'])
+
+        elif _status == GuestState.blocked.value:
+            color = '3D4245'
+            icon = 'glyph-icon icon-minus-square'
+            desc = '被阻塞'
+
+        elif _status == GuestState.paused.value:
+            color = 'B7B904'
+            icon = 'glyph-icon icon-pause'
+            desc = '暂停'
+
+        elif _status == GuestState.shutdown.value:
+            color = '4E5356'
+            icon = 'glyph-icon icon-terminal'
+            desc = '关闭'
+
+        elif _status == GuestState.shutoff.value:
+            color = 'FFC543'
+            icon = 'glyph-icon icon-plug'
+            desc = '断电'
+
+        elif _status == GuestState.crashed.value:
+            color = '9E2927'
+            icon = 'glyph-icon icon-question'
+            desc = '已崩溃'
+
+        elif _status == GuestState.pm_suspended.value:
+            color = 'FCFF07'
+            icon = 'glyph-icon icon-anchor'
+            desc = '悬挂'
+
+        elif _status == GuestState.migrating.value:
+            color = '1CF5E7'
+            icon = 'glyph-icon icon-space-shuttle'
+            desc = '迁移中'
+
+        elif _status == GuestState.dirty.value:
+            color = 'FF0707'
+            icon = 'glyph-icon icon-remove'
+            desc = '创建失败,待清理'
+
+        else:
+            pass
+
+        return '<span class="{icon}" style="color: #{color};">&nbsp;&nbsp;{desc}</span>'.format(
+            icon=icon, color=color, desc=desc)
+
+    def format_sequence_to_device_name(sequence):
+        # sequence 不能大于 25。dev_table 序数从 0 开始。
+        if sequence == -1:
+            return u'无'
+
+        if sequence >= dev_table.__len__():
+            return 'Unknown'
+
+        return dev_table[sequence]
+
+    def format_disk_state(state):
+        from jimvc.models import DiskState
+
+        color = 'FF645B'
+        icon = 'glyph-icon icon-bolt'
+        desc = '未知状态'
+
+        if state == DiskState.pending.value:
+            color = 'FFC543'
+            icon = 'glyph-icon icon-spinner'
+            desc = '创建中'
+
+        elif state == DiskState.idle.value:
+            color = '0077BB'
+            icon = 'glyph-icon icon-unlink'
+            desc = '待挂载'
+
+        elif state == DiskState.mounted.value:
+            color = '00BB00'
+            icon = 'glyph-icon icon-link'
+            desc = '使用中'
+
+        elif state == DiskState.mounting.value:
+            color = '00BBBB'
+            icon = 'glyph-icon icon-elusive-upload'
+            desc = '挂载中'
+
+        elif state == DiskState.unloading.value:
+            color = '93969B'
+            icon = 'glyph-icon icon-elusive-download'
+            desc = '卸载中'
+
+        elif state == DiskState.dirty.value:
+            color = 'FF0707'
+            icon = 'glyph-icon icon-remove'
+            desc = '创建失败,待清理'
+
+        else:
+            pass
 
+        return '<span class="{icon}" style="color: #{color};">&nbsp;&nbsp;{desc}</span>'.format(
+            icon=icon, color=color, desc=desc)
 
+    return dict(format_price=format_price, format_datetime_by_tus=format_datetime_by_tus,
+                format_datetime_by_ts=format_datetime_by_ts, format_guest_status=format_guest_status,
+                format_sequence_to_device_name=format_sequence_to_device_name, format_disk_state=format_disk_state)

+ 1 - 0
state_code.py → jimvc/state_code.py

@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
+
 __author__ = 'James Iter'
 __date__ = '16/06/08'
 __contact__ = 'james.iter.cn@gmail.com'

+ 0 - 0
tests/__init__.py → jimvc/tests/__init__.py


+ 1 - 1
tests/main.py → jimvc/tests/main.py

@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 
-import tests
+from jimvc import tests
 import unittest
 
 

+ 0 - 0
tests/test_boot_job.py → jimvc/tests/test_boot_job.py


+ 0 - 0
tests/test_config.py → jimvc/tests/test_config.py


+ 0 - 0
tests/test_disk.py → jimvc/tests/test_disk.py


+ 0 - 0
tests/test_guest.py → jimvc/tests/test_guest.py


+ 0 - 0
tests/test_operate_rule.py → jimvc/tests/test_operate_rule.py


+ 0 - 0
tests/test_os_template.py → jimvc/tests/test_os_template.py


+ 0 - 0
themes/default/info.json → jimvc/themes/default/info.json


+ 0 - 0
themes/default/license.txt → jimvc/themes/default/license.txt


+ 0 - 0
themes/default/static/applications/mailbox.css → jimvc/themes/default/static/applications/mailbox.css


+ 0 - 0
themes/default/static/avatar/Burung-Pelatuk_144x144.png → jimvc/themes/default/static/avatar/Burung-Pelatuk_144x144.png


+ 0 - 0
themes/default/static/avatar/Burung-Pelatuk_144x144@2x.png → jimvc/themes/default/static/avatar/Burung-Pelatuk_144x144@2x.png


+ 0 - 0
themes/default/static/bootstrap-select/css/bootstrap-select.css → jimvc/themes/default/static/bootstrap-select/css/bootstrap-select.css


+ 0 - 0
themes/default/static/bootstrap-select/css/bootstrap-select.css.map → jimvc/themes/default/static/bootstrap-select/css/bootstrap-select.css.map


+ 0 - 0
themes/default/static/bootstrap-select/css/bootstrap-select.min.css → jimvc/themes/default/static/bootstrap-select/css/bootstrap-select.min.css


+ 0 - 0
themes/default/static/bootstrap-select/js/bootstrap-select.js → jimvc/themes/default/static/bootstrap-select/js/bootstrap-select.js


+ 0 - 0
themes/default/static/bootstrap-select/js/bootstrap-select.js.map → jimvc/themes/default/static/bootstrap-select/js/bootstrap-select.js.map


+ 0 - 0
themes/default/static/bootstrap-select/js/bootstrap-select.min.js → jimvc/themes/default/static/bootstrap-select/js/bootstrap-select.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-ar_AR.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-ar_AR.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-ar_AR.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-ar_AR.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-bg_BG.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-bg_BG.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-bg_BG.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-bg_BG.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-cro_CRO.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-cro_CRO.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-cro_CRO.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-cro_CRO.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-cs_CZ.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-cs_CZ.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-cs_CZ.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-cs_CZ.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-da_DK.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-da_DK.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-da_DK.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-da_DK.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-de_DE.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-de_DE.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-de_DE.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-de_DE.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-en_US.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-en_US.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-en_US.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-en_US.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-es_CL.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-es_CL.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-es_CL.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-es_CL.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-es_ES.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-es_ES.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-es_ES.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-es_ES.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-et_EE.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-et_EE.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-et_EE.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-et_EE.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-eu.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-eu.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-eu.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-eu.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-fa_IR.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fa_IR.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-fa_IR.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fa_IR.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-fi_FI.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fi_FI.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-fi_FI.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fi_FI.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-fr_FR.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fr_FR.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-fr_FR.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-fr_FR.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-hu_HU.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-hu_HU.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-hu_HU.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-hu_HU.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-id_ID.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-id_ID.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-id_ID.min.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-id_ID.min.js


+ 0 - 0
themes/default/static/bootstrap-select/js/i18n/defaults-it_IT.js → jimvc/themes/default/static/bootstrap-select/js/i18n/defaults-it_IT.js


部分文件因文件數量過多而無法顯示