commit 7ce577bb2f1300f183430bf3499a116f97176db8 Author: Cor Kalis Date: Mon May 21 13:27:54 2018 +0200 First open source version. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b1aa47b --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +build +dist +dist_installer +docs/*.html +docs/index.htm +*.pyc +#*# +*~ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e436257 --- /dev/null +++ b/README.md @@ -0,0 +1,88 @@ +Net2Scripting +=== + +Python scripting for the Paxton Net2 SDK. + +This project builds a setup file, that will install a Python scripting environment +that can communicate with Paxton Net2, using the SDK (or a direct DB connection). + + +### **Read this first** +The scripts in this package are currently quite inflexible, in that they assume +that packages are installed in particular directories. For future versions this +should be changed to maybe an environment setting or a 'user' file containg the +definitions. (this file should be in .gitignore) + +For now, the install directories are specificly marked in the requirements. + +### Requirements +The NetScripting project relies on the following: + * An x86 Windows environment (64-bit did not work). Windows7-32bit should be ok. + * DotNet 4.0 + - Installing Paxton Net2 V5.x should take care of that + - The Paxton Net2 OEMClientLibrary dlls (v5.01) are included in this package. + * Python x86 3.4.4 + - Is the Python environment + - Download from http://www.python.org + - Install in C:\WinPrg\Python34\ !!! + * pythonnet-2.3.0-cp34-cp34m-win32.whl + - Is Python .net extension + - Download from http://pythonnet.sourceforge.net + - Install with pip install + * py2exe-0.9.2.2-py33.py34-none-any.whl + - To create a python executable + - Download from http://www.py2exe.org + - Install with pip install + - Remove 'clr' in c:/WinPrg/Python34/lib/site-packages/py2exe/hooks.py !!! + - Note that py2exe does/did not support 3.5 and up yet + * Inno Setup 5.4.2 (higher versions most likely also work) + - To create an installer (uses the inno_script.iss) + - Download from http://www.jrsoftware.org + - Install in C:\Program Files\Inno Setup 5\ !!! + +The following convenience batch files are available: + * run.bat + - To run de scripting tool while testing sample code + - It will wait after execution and run again after pressing enter (ctrl C=exit) + - Do no just click it in explorer; this will not work + - Create a sendTo shortcut to it, to execute python scripts from the explorer. + + type "shell:sento" in the file explorer address bar to access the + SentTo folder + + Create shortcut to run.bat and call it "Test with Net2Scripting" + * make.bat + - Creates an exe-based distro in ./dist + - You can click it in explorer + * build_installer.bat + - Requires make.bat to run first + - Creates a 'SetupNet2Scripting.exe' in ./dist_installer + - You can click it in explorer + +Beware of the following: + * That the doc's generated, need to be defined in src/docgen.py + * That for py2exe, new modules must be defined in 'Net2Scripting.py', + to have py2exe include them in the exe generation. + * That the makefile.bat will show warnings (which we ignore for now): +``` + 8 missing Modules + ------------------ +? Paxton imported from net2xs +? _dbm imported from dbm.ndbm +? log4net imported from pylog4net +? multiprocessing.SimpleQueue imported from concurrent.futures.process +? netbios imported from uuid +? win32evtlog imported from logging.handlers +? win32evtlogutil imported from logging.handlers +? win32wnet imported from uuid +``` + +### Configuration +Runtime configuration file is: src/Net2Scripting.exe.config +(complies to the dotnet standard) + +### Version updates +To update the version number, adjust the following files: + * inno_script.iss + * src/settings.py + +### License +MIT diff --git a/build_installer.bat b/build_installer.bat new file mode 100644 index 0000000..733d32a --- /dev/null +++ b/build_installer.bat @@ -0,0 +1,10 @@ +@echo off +del dist_installer\* /s/q > nul + +rem taskkill /IM explorer.exe /F +rem cd /d %userprofile%\AppData\Local +rem del IconCache.db /a +rem start explorer.exe + +"C:\Program Files\Inno Setup 5\ISCC.exe" inno_script.iss +pause diff --git a/docs/Net2Scripting.png b/docs/Net2Scripting.png new file mode 100644 index 0000000..e5f6ca6 Binary files /dev/null and b/docs/Net2Scripting.png differ diff --git a/docs/README.txt b/docs/README.txt new file mode 100644 index 0000000..20690bd --- /dev/null +++ b/docs/README.txt @@ -0,0 +1,121 @@ +Net2Scripting +============= + +The Net2Scripting program is an add-on for the Paxton Net2 software. +It offers the possibility to run Python scripts against the Net2 SDK or +straight against the Net2 database. +Using the SDK, you can access remote Net2 servers. Using the direct database +interface, only local access is possible. + +Scripting allows ad-hoc functionality to be created, without compilation. +Useful for proof of concepts, filling Net2 with test data, simple door +control, Net2 data exports, etc. + +REQUIREMENTS +* A PC running a recent Windows version. The software has been tested on + WinXP(SP3), Win7 and Win8. +* Administrator rights. +* The Net2 V5.1 or higher software package. + +INSTALLATION +* Run the installer program, which will create an IntoAccess folder in the + Programs menu with a shortcut to Net2Scripting, install the executable, + libraries, samples and documentation. +* Optionally edit the Net2Scripting.exe.config file that can be found in the + program installation folder. + (by default it contains a reference to a sample script + 'samples/user_script.py') + +USAGE +* Option 1: Edit the Net2Scripting.exe.config file, changing the + 'user_script' setting to point to your script. Run the Net2Scripting + program. +* Option 2: Edit the Net2Scripting.exe.config file, adding more entries to + the 'appSetting' section. Run the Net2Scripting program adding the parameter + /k=, where points to the script you want to execute. +* Option 3: Run the Net2Scripting program, adding the path to the script you + wish to execute as parameter. +* If you run the Net2Scripting using the explorer, you may want the window + containing the script result to remain open. Set the appSetting + 'confirm_wait' to 'true' to have it wait for the key before closing. + If you want to run a script using a scheduler, set this option to 'false'. +* By default, the application logs fairly much and both to the console as + well as to a (rolling) file. Change the root 'level' value from DEBUG to + INFO, WARN, ERROR or FATAL to make it less verbose. You can add or remove + any log4net conpatible log appenders to suit your needs. + Beware that the scripting program locks the log file, so if you run more + than one instance, it will complain about not being able to log. + +DOCUMENTATION / HELP +* Some pydoc generated 'help' for the API is placed in the 'docs' + subdirectory of the installation folder. It does not hurt however to also + keep the Net2 API doc at hand while scripting. +* A number of script samples are provided, meant for those with some basic + knowledge of Python. For a full Python language reference, check out + http://www.python.org/doc/ + Not all Net2 SDK functions are available through the python api yet. + If you would like to add stuff however, check out the'inheritance.py' + sample to get you started. +* The (free) Net2Query tool, available at http://www.intoaccess.com, can + also of use to get some insight on available tables, column names and + data types. + +BACKGROUND +* Originally created by CRC Value. +* Maintained (sort of) by IntoAccess from July 2017 - May 2018. +* Open source from May 2018 onward. +* The package websites: + - http://www.net2scripting.nl + - https://github.com/cor-kalis/Net2Scripting + +ACKNOWLEDGEMENTS +* The Net2Scripting program is created using the following libraries/tools: + - Python => http://www.python.org + - Python.Net => http://pythonnet.sourceforge.net + - Py2exe => http://www.py2exe.org + - Paxton.Net2.OEMClientLibrary => http://www.paxton.co.uk + - Inno Setup => http://www.jrsoftware.org + +LICENSE +* MIT + +DISCLAIMER +* You will use this software at your own risk. No responsibility is accepted for + any damage it may accidentally cause. + +HISTORY +* V1.0 was published in April 2013. Initial version +* V1.1 was published in July 2013. + - Fixes a module scope issue (imported modules not recognized in functions). + - User image manipulation. + - Confirm wait, even on a sys.exit(). + - Allow remote native db access. + - Net2Plus module detection using udp broadcasts. + - SQLServer detection using udp broadcasts. + - Default values for add_user and modify_user (less hassle). +* V1.2 was published in July 2013. + - Enable linecache.getline by default, so 'list' in pdb.set_trace() shows + something useful. (disable in config by setting 'linecache_enable' to false) + - Added __scripting_version__ var, to test script compatibility. + - Fixed bug in Net2XS.deactivate_user fuction. +* V1.3 was published in September 2013. + - Fix / implement acu monitoring + - Fix get_users / get_user_by_id bug +* V1.4 was published in October 2013. + - Fix password encryption on remote native database connection +* V2.0 was published in April 2014. + - Net2 V5 compatible. +* V2.1 was published in July 2014. + - Fix hard coded event and subtype bug in add_event_record. +* V2.2 was published in October 2014. + - Removed misplaced delete_image parameter in add_user +* V2.3 was published in December 2015. + - Upgraded to Python 2.7.10 and included most standard Python modules. +* V2.4 was published in August 2016. + - Added the option to use either a dotnet or python date time objects for + the add_user and modify_user methods. + - Added delete_card and get_cards methods. +* V3.0 was published in August 2017. + - Upgrade to Python 3.4.4 +* V4.0 was published in May 2018. + - Made open source. diff --git a/inno_script.iss b/inno_script.iss new file mode 100644 index 0000000..6556235 --- /dev/null +++ b/inno_script.iss @@ -0,0 +1,47 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define MyAppName "Net2Scripting" +#define MyAppVersion "4.0" +#define MyAppPublisher "Net2Scripting" +#define MyAppURL "http://www.net2scripting.nl/" + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{3940C8D4-5D5F-43CF-B92E-4086ED2198B2} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +;AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={pf}\Paxton Access/{#MyAppName} +DefaultGroupName=Paxton Access +InfoAfterFile=.\dist\docs\README.txt +OutputDir=.\dist_installer +OutputBaseFilename=SetupNet2Scripting +SetupIconFile=.\dist\resources\Net2Scripting.ico +Compression=lzma +SolidCompression=yes + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: ".\dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{group}\Net2Scripting"; Filename: "{app}\{#MyAppName}.exe" +Name: "{group}\Net2Scripting API"; Filename: "{app}\docs\index.htm" +Name: "{commondesktop}\Net2Scripting"; Filename: "{app}\{#MyAppName}.exe"; Tasks: desktopicon + +[Run] + +[UninstallRun] diff --git a/make.bat b/make.bat new file mode 100644 index 0000000..3a43801 --- /dev/null +++ b/make.bat @@ -0,0 +1,21 @@ +@echo off + +echo --- Cleaning... +del build\* /s/q > nul +del dist\* /s/q > nul +del docs\*.html /s/q > nul +echo --- Cleaning done + +echo --- Generating docs +cd src +c:/WinPrg/Python34/python docgen.py +cd .. +echo --- Generating docs done + +echo --- Building executable +cd src +c:/WinPrg/Python34/python setup.py py2exe +cd .. +echo --- Building executable done + +pause diff --git a/resources/Net2Scripting.ico b/resources/Net2Scripting.ico new file mode 100644 index 0000000..b0faed6 Binary files /dev/null and b/resources/Net2Scripting.ico differ diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..01348fa --- /dev/null +++ b/run.bat @@ -0,0 +1,6 @@ +@echo off +cd src +:again +c:\WinPrg\Python34\python Net2Scripting.py %1 +pause +goto again diff --git a/runtime/Python.Runtime.dll b/runtime/Python.Runtime.dll new file mode 100644 index 0000000..c2d6627 Binary files /dev/null and b/runtime/Python.Runtime.dll differ diff --git a/src/Net2Scripting.exe.config b/src/Net2Scripting.exe.config new file mode 100644 index 0000000..d7f3606 --- /dev/null +++ b/src/Net2Scripting.exe.config @@ -0,0 +1,43 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Net2Scripting.py b/src/Net2Scripting.py new file mode 100644 index 0000000..c48f22e --- /dev/null +++ b/src/Net2Scripting.py @@ -0,0 +1,329 @@ +""" +Main program for Net2Scripting. +""" +import os +import sys +import settings +import traceback + +# This is just to force py2exe to include these packages +if False == True: + import net2xs + import net2dbxs + import network + # Not required but nice to have + import abc + import aifc + import antigravity + import argparse + import ast + import asynchat + import asyncio + import asyncore + import base64 + import bdb + import binhex + import bisect + import bz2 + import cProfile + import calendar + import cgi + import cgitb + import chunk + import cmd + import code + import codecs + import codeop + import collections + import colorsys + import compileall + import concurrent + import configparser + import contextlib + import copy + import copyreg +# import crypt + import csv + import ctypes +# import curses + import datetime +# import dbm + import decimal + import difflib + import dis + import distutils + import doctest + import threading + import email + import encodings +# import ensurepip + import enum + import filecmp + import fileinput + import fnmatch + import formatter + import fractions + import ftplib + import functools + import genericpath + import getopt + import getpass + import gettext + import glob + import gzip + import hashlib + import heapq + import hmac + import html + import http + import idlelib + import imaplib + import imghdr + import imp + import importlib + import inspect + import io + import ipaddress + import json + import keyword + import lib2to3 + import linecache + import locale + import logging + import lzma +# import macpath +# import macurl2path + import mailbox + import mailcap + import mimetypes + import modulefinder + import msilib +# import multiprocessing + import netrc + import nntplib + import ntpath + import nturl2path + import numbers + import opcode + import operator + import optparse + import os + import pathlib + import pdb + import pickle + import pickletools + import pipes + import pkgutil + import platform + import plistlib + import poplib + import posixpath + import pprint + import profile + import pstats + import pty + import pyclbr + import pydoc + import pydoc_data + import queue + import quopri + import random + import re + import reprlib + import rlcompleter + import runpy + import sched + import selectors + import shelve + import shlex + import shutil + import site +# import smtpd + import smtplib + import sndhdr + import socket + import socketserver + import sqlite3 +# import compile +# import constants +# import parse + import ssl + import stat + import statistics + import string + import stringprep + import struct + import subprocess + import sunau + import symbol + import symtable + import sysconfig + import tabnanny + import tarfile + import telnetlib + import tempfile + import test + import textwrap + import this + import threading + import timeit + import tkinter + import token + import tokenize + import trace + import traceback + import tracemalloc + import tty + import turtle + import turtledemo + import types + import unittest + import urllib + import uu + import uuid + import venv + import warnings + import wave + import weakref + import webbrowser + import wsgiref + import xdrlib + import xml + import xmlrpc + import zipfile + + +# Setup logging first +from pylog4net import Log4Net +try: + Log4Net.read_config(settings.CONFIG_FILE) +except Exception as e: + print('Log error: %s' % (str(e))) + sys.exit(1) + +from config import Config +try: + cfg = Config(settings.CONFIG_FILE) +except Exception as e: + print('Config error: %s' % (str(e))) + sys.exit(1) + +# Running as py2exe: check if linecache should be enabled +# if hasattr(sys, 'frozen'): +# if cfg.get("enable_linecache", True, bool): +# # Monkey patch it back to the original value +# import linecache +# linecache.getline = linecache.orig_getline +# del linecache + +# Log4net logger +logger = Log4Net.get_logger('Net2Scripting') + + +def run(script_file): + """Run script file + """ + try: + if not os.path.isfile(script_file): + raise Exception("User script '%s' does not exist!" % (script_file)) + + # Get script dir and add it to the module search path + sys.path.insert(0, os.path.dirname(script_file)) + + print("Press ' C' to quit...") + logger.Debug("Calling user script '%s'" % (script_file)) + try: + # Strip Net2Scripting param from arguments + sys.argv = sys.argv[1:] + # Explicitly provide dict, to prevent scope issues + with open(script_file) as f: + code = compile(f.read(), script_file, 'exec') + exec(code, + {"__name__": "__main__", + "__file__": script_file, + "__scripting_version__": settings.VERSION}) + except KeyboardInterrupt: + logger.Debug("User interrupt") + + except Exception as ex: + + msg = "Fatal error: " + str(ex) + if cfg.get("log_stacktrace", default=False, vtype=bool): + msg += "\n" + traceback.format_exc() + logger.Fatal(msg) + return 1 + + +def run_key(script_key): + """Run file referenced by setting keyword + """ + try: + script_key = script_key.strip() + if not script_key: + raise "The provided script keyword is empty!" + + # Fetch setting from config + cfg.check_required([(script_key, str)]) + + return run(cfg.get(script_key)) + + except Exception as ex: + logger.Fatal("Fatal error: " + str(ex)) + return 1 + + +def confirm_wait(): + """Wait for user confirmation + """ + # Fetch setting from config + wait = cfg.get("confirm_wait", default=False, vtype=bool) + if wait: + print() + input("Press enter to continue: ") + + +# Main program entry +if __name__ == '__main__': + + ret_val = 0 + + try: + if len(sys.argv) > 1: + arg = sys.argv[1] + + if arg == "/?": + print() + print("Net2Scripting V%s, by Net2 Solutions" % (settings.VERSION)) + print() + print(" /? = help") + print(" /k:keyword = run script referenced by appSettings keyword") + print("