忍者ブログ
Admin / Write / Res
ちゃんとカテゴリ分けされておりませんので、 記事をお探しならブログ内検索が便利です。 ご活用くださいませー+.(≧∀≦)゚+.゚
ブログ内検索
カレンダー
02 2024/03 04
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
カウンター
アクセスカウンター
最新コメント
[01/16 jilibet]
[10/20 Call Girl in Delhi]
[09/07 לפרטים נוספים]
[08/14 nuevos casinos online 2022]
[08/11 Gbototo]
最新トラックバック
プロフィール
+ハンドル+
y_ayamori(purple)
+職業+
IT系エンジニア
+すまい+
さいたま
バーコード
[1]  [2]  [3]  [4]  [5]  [6
djangoのPermissionはわかりにくいですよね。
恐らくやり方だけが出回っているため、その全体像がイメージしにくいために把握に時間が掛かってしまうのだと思います。

私もかなり調べました。
djangoのPermissionの考え方はシンプルでCRUDに基づき、追加・削除・更新・閲覧がデフォルトで用意されています。
そしてその権限はアプリとモデルに紐づくということです。

アプリに紐づくというのはイメージしやすいのですがモデルに紐づくというのがちょっと混乱を招いている気がします。
というのも権限の範囲がアプリというスコープなのはイメージしやすいですが1アプリの中でモデルは複数存在するものではないかと思います。
にもかかわらず権限はモデルに紐づくため、モデルと言ってもどのモデルを使えば…?
という疑問から始まってしまいます。

しかもモデルに紐づけている割にはその仕組みをコンテントタイプ(ContentType)というここにきて新しい概念で括ってきます。
これらの立て付けをちゃんと説明しているサイトが少なく、権限付与のやり方という結論しかないため難しくしているのではないでしょうか。
ちなみにContentTypeはざっくりアプリ名とモデル名を紐づけたものです。

さらにContentTypeはdjangoアプリに。
permission自体はauthアプリに紐づくのもわかりにくい。
ここはもはや標準機能内のおはなしなのでそういうもの、で終わらせておきましょう。

これらから私はdjangoのPermissionsは以下のように立て付けることとしました。
アプリまたは業務スコープ内でPersmissionsテーブルを作ってしまう。
よくあるブログと投票の例でいうと

class BlogPost(models.Model):
    # ...


class Vote(models.Model):
    # ...
こんな感じがあったとしてブログを管理できる権限と管理ができる権限を分ける場合、こんな感じのモデルを作っちゃいます。
class BlogPermission(models.Model):
    class Meta:
        managed = False


class VotePermission(models.Model):
    class Meta:
        managed = False
Permissionはモデル(テーブル)に自動的に自動的に紐づくので、中身や管理も不要です。
managed=Falseでもパーミッションは作成されてしまうようなので、modelsに記載されているかどうかが重要のようです。
またモデルを消してもPermissionは残るので、もしかしたらカスタムPermissionのほうが良いかもしれません…
とはいえ権限の設定があることがmodelsに記載すること明白になるので、まったくメリットがないというわけじゃないと思っています。
なのでここまでできてしまえば、後は簡単。
# 必要なモデル群をimport
from django.contrib.auth.models import User, ContentType, Permission
from sample.models import BlogPermission

# ContentTypeを引き出して、該当の権限を引っ張る
content_type = ContentType.objects.get_for_model(BlogPermission)
permissions = Permission.objects.filter(content_type=content_type)

# それをユーザに紐づけるだけ
user.user_permissions.set(permissions)
if user.has_perm("sample.add_blogpermission"):
    print('権限あります')

# 上記はCRUD全てですが、特定の権限に絞る場合はこんな感じ
permissions = Permission.objects.filter(content_type=content_type, codename__startswith='delete')

次にグループです。
グループの概念がある割にグループに関する操作マニュアルが希薄でこれまたわからない…
どこにグループの作り方の記載あるのでしょうか…
テーブル見る限り、単純にINSERTで対応してしまえばよいみたいです…
ここもキャメルケースにすべきかどうかも不明ですね…
# グループを作成
group = Group(name='BlogAdmin')
group.save()

# グループが持つ権限をセット
permissions = Permission.objects.filter(content_type=content_type)
group.permissions.set(permissions)
group.save()

# ユーザにグループ権限を付与
user.groups.set([group])
慣れればこれだけ。
ただグループとユーザが同列のため、その権限はユーザPermissionなのかグループPermissionなのかはしっかり設計が必要です。

私は権限のスコープはモデルで、権限の塊はグループで分けることにしました。
# 閲覧のみ
group = Group(name='BlogViewer')
group.save()
permissions = Permission.objects.filter(content_type=content_type, codename__startswith='view')
group.permissions.set(permissions)
group.save()

# 編集者
group = Group(name='BlogEditor')
group.save()
group.permissions.set([Permission.objects.get(content_type=content_type, codename__startswith='view'),
                      Permission.objects.get(content_type=content_type, codename__startswith='add'),
                      Permission.objects.get(content_type=content_type, codename__startswith='change'),])
group.save()

少しでも参考になれば幸いです。

拍手

PR
aaSで悩ましいのはコスト計算。
運用したら移行コストも含めてペイできないもよく聞きます。
最近では脱クラウド、オンプレ回帰という言葉もよく見ます。

しかしながらクラウドが便利であることには変わり有りません。
特にデータ周りはバックアップや耐障害性も踏まえるとaaSはとても優位です。

そんな中で新鋭とも呼べるaaSがTiDB。
MySQLベースのRDBMSのサービスでDaaSに分類されます。

そんなTiDBはDisk容量とRU、リクエストユニットというこれまたわからない使用量の単位で課金をしてきます。
Diskもシンプルかと思いきや、行ストレージと列ストレージがあります。
いったん行だけ考えます。
無料枠は5GiB、5000万RUまで。
単位を聞くとそこそこ使えそうです。

実際は、というと77MBのデータを保存して85MiB。
RUは66万です。
小さいアプリケーションならそこそこ使えそう。
ということでざっくり、1MB書き込み処理を行うのに10,000RU、1MB読み込み処理を行うのに100RUくらいという試算がでました。

ビッグデータをゴリゴリ解析するのでないなら5GiBはかなりの容量です。
5000万RUまで無料を考えるとRUも思ったより消費しませんね。

どこかで一度本運用してみたいと思います。

拍手

画像をベースライン形式からプログレッシブ形式に変換する要件が出てきたので、楽な方法は無いかと検索したところ jpegtran コマンドがよさそうってなりました。
しかし dnf などで入らないようなのでコンパイルが必要です。
備忘録的にシェルスクリプトを作成しました。

# シンプルにインストール
curl http://notebook.mor-maid.info/scripts/jpegtran_install.sh | bash -
# インストール先などを変える場合はいったん保存が必要
# working_path はソースのダウンロードやコンパイルを行うディレクトリです
curl http://notebook.mor-maid.info/scripts/jpegtran_install.sh > jpegtran_install.sh
chmod +x jpegtran_install.sh
./jpegtran_install.sh -i path_to_install -w working_path
# インストールに必要な dnf などで入るパッケージも含めてインストールする場合は -d でやってくれます
# その場合は要rootユーザです
curl http://notebook.mor-maid.info/scripts/jpegtran_install.sh > jpegtran_install.sh
chmod +x jpegtran_install.sh
./jpegtran_install.sh -i /user/local/ -w working_path -d

refs: jpegtranのインストール方法と使い方【JPG画像最適化】
要望不具合はXにて賜ります

拍手

まぁ、ググれば出てくるんですが、まだググり方にコツがいるので、備忘録的に…
WEBサイトのテストや邪道な使い方としてクローラを作成するときにseleniumはよく使う手段です。
が、geckodriverはともかくchromedriverは毎回chromeのバージョンに合わせたchromedriverを使わなければなりません。
そのため、毎回chromedriverを起動するchromeに合わせて落としてくる必要があるのですが…
pipにて自動インストールするモジュールがありましたので、こちらを使うと便利ですよ、というお話しです。

またfind_element_by_xpathもなくなったようなので、合わせて代替方法も記載します。


事前作業
pip install selenium
pip install webdriver_manager

簡易的に確認
2023.08.21 更新
# 4.3.0 以降は呼び出し方が変わったみたいです

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager


service = Service(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
driver.get('https://yahoo.co.jp/')
driver.find_elements(By.XPATH, '//a')

# 4.3.0 以前のやりかた

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get('https://yahoo.co.jp/')
driver.find_elements_by_xpath('//a')

検索タグ
#python #python3 #クローラ #chrome #chromedriver #selenium

拍手

バージョン管理は主に案件、システム単位で行うことは多いと思いますがそうなるとその単位でリポジトリを切ることになります。
ローカル、または共有サーバ上でディレクトリを作成してそれぞれにリポジトリを作ることはリポジトリの管理の面でとても楽ちんです。

一方でローカル、またはイントラにあるネットワークからはデプロイが困難という側面もあります。
高度なインテグレーション体制(CIツールの利用)があれば、解決可能でしょうが、そこに至らない小規模開発ベンチャーにはハードルが上がります。<br />
<br />
またアクセス権という意味ではしっかりしておかないと、リポジトリにアクセスできる人はどのリポジトリにもアクセス可能になってしまいます。<br />
githubなどはそれらをうまく回避可能なのでしょうが、Mercurialではどうでしょうか、ということで前置き長くなりましたが、hgwebの導入について、です。<br />
<br />
hgwebの特徴<br />
・WEB経由で行える<br />
・リバプロで対応することでインターネットはSSL通信を容易に実現可能
・BASIC認証などを組み合わせればアクセス制限を簡易的に実現できる


ほぼ以下を丸パクリ<br />
https://github.com/benoitc/gunicorn-recipes/issues/1
 
でもいくつか思い通りにならないので後ほど修正します。
<br />
事前準備
<pre>
# 必要なモジュールを pip で入れていく
# 必要に応じてvenvは事前にして置くこと
pip install mercurial
 
# リポジトリ群を格納するディレクトリを作成(場所は任意)
mkdir -p /var/vcs/mercurial/repos
# hgwebの設定を諸々記載するディレクトリを作成(場所は任意)
mkdir -p /var/vcs/mercurial/hgweb
 
# hgweb.py を作っていく
vim /var/vcs/mercurial/hgweb/hgweb.py
----

from mercurial.hgweb import hgweb

# bytes にするところがミソ
CONFIG = b'./hgweb.config'
app = hgweb(CONFIG)
 
----
 
# hgweb config を作っていく
vim /var/vcs/mercurial/hgweb/hgweb.config
----
 
[ui]
editor = vim
 
[web]
# 今回は /hgweb/ からリバプロからのリクエスト想定なのでこのようにする
baseurl = hgweb/
# 今回は paths でワイルドカードを指定し、動的(再帰的)にリポジトリを検索する
descend = True
# SSLはApacheで、リバプロと hgweb はイントラ内なのでSSLは無効にする
push_ssl = false
# pushを許可する
allow_push = *
 
[paths]
/ = /var/vcs/mercurial/repos/*
 
----
 
# gunicorn の設定
vim /var/vcs/mercurial/hgweb/gunicorn.conf.py
----
import pathlib
base_dir = pathlib.Path(__file__).parent
 
wsgi_app = 'hgweb:app'
 
host = "127.0.0.1"
port = "9000"
bind = f"{host}:{port}"
 
daemon = True
reload = True
----
 
# httpd.conf この辺は諸々省略します
----
cat << EOS > /etc/httpd/conf.d/hgweb.conf
ProxyPass /hgweb/ http://127.0.0.1:9000/
ProxyPassReverse /hgweb/ http://127.0.0.1:9000/
EOS
----
 
# リポジトリ作成
cd /var/vcs/mercurial/
hg init repos/test_repo && touch hgweb/gunicorn.conf.py
 
# リポジトリが見えることを確認する
https://hgweb.host/hgweb/
 
</pre>

拍手

すぐ忘れてしまうのでメモします。
Sc config wsearch start=disabled
Net stop wsearch

EsentUtl.exe /d C:\ProgramData\Microsoft\Search\Data\Applications\Windows\Windows.edb

Sc config wsearch start=delayed-auto

Net start wsearch

拍手

Redmineでプロジェクト管理しているところは多いのではないでしょうか。
最近はバッグログやJIRAなどが台頭し、インターフェースもお堅めなRedmineは時代遅れなイメージがあります。
比較的中規模以上の案件で真価を発揮するタイプだと思うので、
・まずは使ってみる。
・少人数の情シスが使う。
・個人のタスク管理に使う。
には向かないと思います。

しかしながら企業で採用されていたり顧客先で導入されているとあらば、利用せざるを得ません。
どんな感じでつかえるのかなー、と思っても気軽に構築するのも割と手間だったりします。

sqlite3でそこでとりあえずサクッと、動かしたい。
あの機能はどの権限で使えるんだっけ?
この権限付与するとどうなるの?
このボタン押すと取り消しつかない??
そんな悩みはエンジニアならまず使ってみよう精神で突破したい。
少なくともあたしはそうなのよね。

なので、インストーラ作ってみました。
# Ubuntsu Server 20.04LTS
wget 'http://notebook.mor-maid.info/scripts/redmine.sh'
sudo sh redmine.sh

本当にまっさらなOSに一からインストールし、自由に操作可能な場合のみです。
DBやMailなど設定しませんので決してプロダクション環境で使用しないように!
refs: https://kojion.com/posts/894

拍手

OSによってはデフォでインストールするとUTCになっちゃう場合があります。
システムログなどはUTCでもいいかと思いますが、cronの設定などは現地時間がじゃないといろいろ混乱をきたします。
その設定についてすぐ忘れちゃうのでメモっておきます。
と、いってもコピペですが…

# タイムゾーン一覧を表示
timedatectl list-timezones

# タイムゾーン設定
timedatectl set-timezone Asia/Tokyo

# 設定確認
timedatectl

refs: https://www.server-world.info/query?os=Ubuntu_20.04&p=timezone

# 検索タグ
UbuntuServer20.04

拍手

OSをインストールした直後にとりあえずやっておきたいこと。
それはその時点で最新の状態にしておきたい。
サーバならセキュリティも考慮してなおのこと。
最近はコマンドのオプションも変わって来ているのでざっくりメモです。

下記メッセージにも有効です
0 updates can be installed immediately.
0 of these updates are security updates.


## Ubuntu Server 20.04

sudo apt list --upgradable
sudo apt --allow-downgrades --allow-remove-essential --allow-unauthenticated -y update
sudo apt --allow-downgrades --allow-remove-essential --allow-unauthenticated -y upgrade
sudo apt --allow-downgrades --allow-remove-essential --allow-unauthenticated -y dist-upgrade
sudo apt --allow-downgrades --allow-remove-essential --allow-unauthenticated -y autoremove

sudo reboot

# 検索タグ
UbuntuServer20.04

拍手

fioのコマンドについてすぐ忘れてしまうのでメモ。
といっても他サイトのコピペですけど ←

# インストールされていない場合
sudo apt --allow-unauthenticated -y install fio

# ざっくり計測
fio -filename=/tmp/testr  -direct=1 -rw=read      -bs=4k -size=1G -numjobs=64 -runtime=10 -group_reporting -name=file1
fio -filename=/tmp/testw  -direct=1 -rw=write     -bs=4k -size=1G -numjobs=64 -runtime=10 -group_reporting -name=file2
fio -filename=/tmp/testrr -direct=1 -rw=randread  -bs=4k -size=1G -numjobs=64 -runtime=10 -group_reporting -name=file3
fio -filename=/tmp/testrw -direct=1 -rw=randwrite -bs=4k -size=1G -numjobs=64 -runtime=10 -group_reporting -name=file4

# writeバッファを利かせた計測の場合
fio -filename=/tmp/testr  -rw=read      -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1
fio -filename=/tmp/testw  -rw=write     -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file2
fio -filename=/tmp/testrr -rw=randread  -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file3
fio -filename=/tmp/testrw -rw=randwrite -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file4


refs: https://qiita.com/toshihirock/items/fa4d310115e6921ab0ac

# 検索タグ
fio
UbuntuServer20.04

拍手

Copyright ©  アナログを愛するデジタル生活館 All Rights Reserved.
* material by Pearl Box   * Template by tsukika

忍者ブログ [PR]