JenkinsスレーブをWindowsサービスとしてインストールする

Jenkinsからslave.jarをダウンロード。

https://github.com/svilambi/JenkinsSlaveSetupからjenkins-slave.exeとjenkins-slave.xmlをslave.jarと同じフォルダへダウンロード。

jenkins-slave.xmlを開いて、

<arguments>-Xrs  -jar "%BASE%\slave.jar" -jnlpUrl http://サーバ:ポート番号/jenkins/computer/IS064/slave-agent.jnlp -secret <secret> </arguments>

を以下のように修正

<arguments>-jar slave.jar -jnlpUrl http://サーバ:ポート番号/jenkins/computer/IS064/slave-agent.jnlp</arguments>

 

slave.jar所在から以下のコマンドを実行

jenkins-slave.exe install

すると、サービス一覧に「Jenkins agent」という名前で登録される。

社内サーバ(Linux)にPythonモジュールをインストール手順

対象モジュールをダウンロード
URL:https://pypi.org/

例:cx-Oracle

①cx-Oracleで検索

②検索結果の「cx_Oracle version 8.1」をクリック

③Download filesをクリック

④Linuxのため、cx_Oracle-8.1.0.tar.gzをクリックしてダウンロード

⑤ダウンロードしたファイルをLinuxサーバにアップロード(任意場所)して、以下のコマンドを実行
tar -zxvf cx_Oracle-8.1.0.tar.gz
cd cx_Oracle-8.1.0
python setup.py build
python setup.py install

カラム名を指定できるSELECT結果配列

# coding: utf-8
import cx_Oracle as ora

tns = ora.makedsn('ホスト名', 1521, 'sid')
conn = ora.connect('ユーザ名', 'パスワード', tns, encoding='utf-8')
cur = conn.cursor()

cur.execute('SELECT COL1, COL2 FROM TBLNAME')
# Python3
columnname = {desc[0]:idx for idx, desc in enumerate(cur.description)}
# Python2
# col = {}
# for (idx, desc) in enumerate(cur.description): col.update({ desc[0]:idx })

rows = cur.fetchall()

for r in rows:
	# 配列番号で指定
	# print("%s, %s" % (r[0], r[1]))
	# カラム名で指定
	print("%s %s" % (r[columnname['COL1']], r[columnname['COL2']]))

conn.close()

chromedriver自動アップデート

Pythonで自動的にchromedriverアップデート処理。

例外処理など全てなし、必要な部分のみ。

# coding: utf-8

import os
from webdriver_manager.utils import chrome_version
from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import urllib.request
import zipfile

# ファイルパス
zipfilepath = r'配置パス\chromedriver_win32.zip'
exefilepath = r'配置パス\chromedriver.exe'

# chromeバージョン
chrome_version = chrome_version()

# ダウンロードURL取得
url = 'https://chromedriver.chromium.org/downloads'
download_url = None

html = urlopen(url).read()
soup = BeautifulSoup(html, 'html.parser')
elements = soup.select('html body a')
pattern = r"^[0-9]{2}[.]+[0-9]{1,2}[.]+[0-9]{4}$"
for element in elements:
	if ('ChromeDriver' in element.text):
		vd = element.text.replace('ChromeDriver', '').strip()[0:len(chrome_version)]

		if (re.match(pattern, vd) and chrome_version >= vd):
			download_url = element.get('href')
			break

# ダウンロード
download_url = download_url.replace('index.html?path=', '') + os.path.basename(zipfilepath)
urllib.request.urlretrieve(download_url, zipfilepath)

# 解凍
with zipfile.ZipFile(zipfilepath) as existing_zip:
	existing_zip.extract('chromedriver.exe', os.path.dirname(exefilepath))

poplibで利用したメール受信

# coding: utf-8

import time
import poplib
import email
from email.header import decode_header

# ヘッダ情報取得
def get_header(msg, name):
	header = ''
	if msg[name]:
		for tup in decode_header(str(msg[name])):
			if type(tup[0]) is bytes:
				charset = tup[1]
				if charset:
					header += tup[0].decode(tup[1])
				else:
					header += tup[0].decode()
			elif type(tup[0]) is str:
					header += tup[0]
	return header

# 受信日時
def get_date(msg):
	mdate = email.utils.parsedate(msg.get('date'))
	return time.strftime('%Y/%m/%d %H:%M:%S', mdate)

# body情報
def get_content(msg):
	if msg.is_multipart() is True:
		rst = ""
		for part in msg.walk():
			payload = part.get_payload(decode=True)
			if payload is None:
				continue
			charset = part.get_content_charset()
			if charset is not None:
				payload = payload.decode(charset, "ignore")
			rst += str(payload)
		return rst
	else:
		charset = msg.get_content_charset()
		payload = msg.get_payload(decode=True)
		try:
			if payload:
				if charset:
					return payload.decode(charset)
				else:
					return payload.decode()
			else:
				return ""
		except:
			return payload

# サーバに接続
cli = poplib.POP3('www.example.com')

# 認証
cli.user('ユーザID')
cli.pass_('パスワード')

# メールボックス内のメールの総数を取得
count = cli.stat()[0]

for i in range(count):
	no = i + 1
	content = cli.retr(no)[1]
	msg = email.message_from_bytes(b'\r\n'.join(content))

	print(get_header(msg, 'from'))
	print(get_header(msg, 'subject'))
	print(get_date(msg))
	print(get_content(msg))

	# 削除
	# cli.dele(no)

Pythonをexe化

pyinstaller ファイル.py <オプション>

    1. –onefile / -F
      出力ファイルを1つにまとめる
    2. –noconsole / -w / –windowed
      コンソールなし
    3. –icon / -i
      アイコン指定
    4. –name / -n
      exe名指定
    5. –clean
      キャッシュ削除

数独計算プログラム

汚いソースですが…

$lsts = array(
	array( 0, 1, 2, 3, 4, 5, 6, 7, 8),
	array( 9,10,11,12,13,14,15,16,17),
	array(18,19,20,21,22,23,24,25,26),
	array(27,28,29,30,31,32,33,34,35),
	array(36,37,38,39,40,41,42,43,44),
	array(45,46,47,48,49,50,51,52,53),
	array(54,55,56,57,58,59,60,61,62),
	array(63,64,65,66,67,68,69,70,71),
	array(72,73,74,75,76,77,78,79,80),

	array( 0, 9,18,27,36,45,54,63,72),
	array( 1,10,19,28,37,46,55,64,73),
	array( 2,11,20,29,38,47,56,65,74),
	array( 3,12,21,30,39,48,57,66,75),
	array( 4,13,22,31,40,49,58,67,76),
	array( 5,14,23,32,41,50,59,68,77),
	array( 6,15,24,33,42,51,60,69,78),
	array( 7,16,25,34,43,52,61,70,79),
	array( 8,17,26,35,44,53,62,71,80),

	array( 0, 1, 2, 9,10,11,18,19,20),
	array( 3, 4, 5,12,13,14,21,22,23),
	array( 6, 7, 8,15,16,17,24,25,26),
	array(27,28,29,36,37,38,45,46,47),
	array(30,31,32,39,40,41,48,49,50),
	array(33,34,35,42,43,44,51,52,53),
	array(54,55,56,63,64,65,72,73,74),
	array(57,58,59,66,67,68,75,76,77),
	array(60,61,62,69,70,71,78,79,80)
);

$rst = array();
$rst['flag'] = true;

// $target = array(
// 	0,0,0, 0,0,0, 0,0,0,
// 	0,1,2, 0,0,0, 0,9,0, 
// 	7,0,0, 9,0,0, 2,1,0,

// 	0,0,0, 6,0,3, 0,8,0,
// 	0,0,8, 0,0,5, 0,2,0,
// 	0,3,0, 0,7,2, 1,6,5,

// 	4,0,0, 0,0,0, 0,3,0,
// 	8,6,1, 2,0,0, 0,7,0,
// 	0,0,0, 0,0,0, 0,0,0
// );

$target = $_POST['lists'];

$tinx = array();
for ($i = 0; $i < count($target); $i++)
{
	if ($target[$i] == 0)
	{
		$tinx [] = $i;
	}
}

$i = 0;
$flag = false;
while(true)
{
	do
	{
		$target[$tinx[$i]]++;

		if ($target[$tinx[$i]] > 9)
		{
			$target[$tinx[$i]] = 0;
			$i--;
			$flag = true;
			break;
		}
	}
	while (check_duplicate($lsts, $target) == false);

	if ($flag == true)
	{
		$flag = false;
		continue;
	}

	$i++;

	if ($i < 0)
	{
		$rst['flag'] = false;
		break;
	}
	else if ($i >= count($tinx))
	{
		break;
	}
}

$rst['lists'] = $target;

echo json_encode($rst);

function check_duplicate($lsts, $tgt)
{
	foreach($lsts as $lst)
	{
		$arr = array();
		foreach($lst as $key)
		{
			if ($tgt[$key] != 0)
				$arr[] = $tgt[$key];
		}

		if (count($arr) > 1)
		{
			$value_count = array_count_values($arr);
			if (max($value_count) > 1)
			{
				// echo var_dump($lst);
				return false;
			}
		}
	}
	return true;
}

https://sample.keaven.cyou/sudoku/

CSSにより改行させない

white-space: nowrap;

ちなみに
normal
ソース中のホワイトスペースを無視
ソース中の改行を1つの半角スペースとして表示
ボックスサイズが指定されている場合にはそれに合わせて自動改行する(初期値)
pre
ソース中のホワイトスペースをそのまま表示
ソース中の改行をそのまま表示
ボックスサイズが指定されている場合にも自動改行しない
nowrap
ソース中のホワイトスペースを無視
ソース中の改行を1つの半角スペースとして表示
ボックスサイズが指定されている場合にも自動改行しない
pre-wrap
ソース中のホワイトスペースをそのまま表示
ソース中の改行をそのまま表示
ボックスサイズが指定されている場合にはそれに合わせて自動改行する
pre-line
ソース中のホワイトスペースを無視
ソース中の改行をそのまま表示
ボックスサイズが指定されている場合にはそれに合わせて自動改行する

http://www.htmq.com/style/white-space.shtml