Pleasanterのコードスタイル コメント編

Pleasanter開発チームのいしざきです。

PleasanterはオープンソースのWebデータベースでGitHubにソースが公開されています。

今回はPleasanterへプルリクエスト(PR)する際に気にしたいコードスタイル コメント編です。

よく見るスタイルとPleasanterの比較

次の例はよく見るコードルールで書かれたC#クラスです。このクラスがPleasanterではどうなるか見てみましょう。
(コードは空白行編と同じものです。)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace SampleApp
{
    public class PopularStyleClass
    {
        public async Task<string> GetDataFromWeb()
        {
            // Create HttpClient
            var httpClient = CreateHttpClient();
            httpClient.Timeout = new TimeSpan(TimeSpan.TicksPerSecond * 20L);

            // Request Data
            var contentData = "<contentData>";
            var requestContent = new StringContent(contentData);

            // Post
            var responceMessage = 
                await httpClient.PostAsync("<requestUrl>", requestContent);

            // Responce Data
            var responceContent = responceMessage.Content;
            var responceData = await responceContent.ReadAsStringAsync();
            return responceData;
        }

        HttpClient CreateHttpClient()
            => new HttpClient();
    }
}

Pleasanterでは次のようになります。
(※筆者も勉強中のため100%正しいPleasanterのスタイルではないかもしれません。勉強のためにこの記事を書いている面もあります)

using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace SampleApp
{
    public static class PleasanterStyleClass
    {
        public static async Task<string> GetDataFromWeb()
        {
            var hc = CreateHttpClient();
            hc.Timeout = new TimeSpan(ticks: TimeSpan.TicksPerSecond * 20L);
            return await (await hc
                .PostAsync(
                    requestUri: "<requestUrl>",
                    content: new StringContent("<contentData>")))
                .Content
                .ReadAsStringAsync();
        }

        private static HttpClient CreateHttpClient()
        {
            return new HttpClient();
        }
    }
}

Pleasanterのコメント

Pleasanterのコメントはメソッドの内部には一切書きません。
また他の場所でもごく一部の特別な例外を除いて、一切書きません。例えば次のようなメソッドのドキュメンテーションコメントが例外の一例です。

/// <summary>
/// Fixed:
/// </summary>
private void OnConstructed(Context context)

このドキュメンテーションコメントは見かけたら消さずに残してください。

PRのお願い

PleasanterへのPRいただける際にはコメントはなしでお願いします。
また、メソッド内部のコメントを見つけた方、ぜひ修正してPRお願いします。

その他のコードスタイル

今回のコード例だけでもコメント以外にも様々なコードルールが読み取れますが、Pleasanterは日々進化中でPR時のお願い事項などの整備は取り組み中の状態です。

不定期になりますが今後も少しずつこちらのブログで紹介してまいります。今後PRするかもしれないという方、継続してチェックしていただけると嬉しいです。

Pleasanterのサポートツール

あけましておめでとうございます Pleasanter開発チームの小林です。 今年もPleasanterをどうぞよろしくお願いいたします。

今回は、プリザンターで発生する問題の解決をサポートするツール「Implem.SupportTools」をご紹介します。

Implem.SupportToolsの機能

Implem.SupportToolsは、現在以下の機能を提供しています。

SysLogビューア

プリザンターのログが記録されているSysLogsテーブルの内容を閲覧する機能です。 最新のログをリアルタイムで閲覧するモードと、表示する期間を日付で指定して閲覧するモードがあります。

メール送信テスト

SMTPメール送信の設定内容を確認するための機能です。
"App_Data\Parameters\Mail.json"に設定されているパラメータを使用してメールの送信を試行します。

LDAP同期テスト

Active Directoryの同期設定の内容を確認するための機能です。
"App_Data\Parameters\Authentication.json"に設定されているパラメータで取得可能なADアカウントを一覧表示します。

ご利用方法

利用方法等、詳しい説明は以下のマニュアルをご確認ください。
サポートツール · Implem/Implem.Pleasanter Wiki · GitHub

サポートツールをご活用いただき、問題解決の手助けになれば幸いです。

サイト設定が格納されているSitesテーブルのSiteSettingsカラム

Pleasanter開発チームの内田です。

新年あけましておめでとうございます。
今年も宜しくお願いいたします。

弊社は中野駅北口のブロードウェイから徒歩3分の所にオフィスがあるのですが、中野駅の北口は飲食店がとても多く、毎日のように何を食べるか悩んでしまうほどです。今日は家系ラーメン「五丁目ハウス」で美味しいラーメンを食べてきました。家系なのにさっぱりとした味で胃もたれせずに美味しく食べれます。オススメ! tabelog.com

中野アピールはこのくらいにして、今日はサイト設定についてです。 Pleasanterは「テーブルの管理」のメニューから、項目をカスタマイズしたり計算式やスクリプトを挿入したりできます。ここで設定した内容がどこに保存されるのか、みなさん気になりますよね。

ずばり、保存先はデータベースImplem.PleasanterのSitesテーブルのSiteSettingsカラムにJSON形式で格納されます。

実際は、こんな形で保存されています。SQL Server Management Studioなどで開いてみてください。

{
  "Version": 1.014,
  "ReferenceType": "Issues",
  "GridView": 1,
  "GridColumns": [
    "IssueId",
    "ClassA",
    "ClassB",
    "TitleBody",
    "Comments",
    "Manager",
    "Owner",
    "StartTime",
    "CompletionTime",
    "WorkValue",
    "ProgressRate",
    "RemainingWorkValue",
    "Status",
    "Updator",
    "UpdatedTime"
  ],
  "EditorColumns": [
    "IssueId",
    "Ver",
    "Title",
    "Body",
    "StartTime",
    "CompletionTime",
    "WorkValue",
    "ProgressRate",
    "RemainingWorkValue",
    "Status",
    "Manager",
    "Owner",
    "ClassA",
    "ClassB",
    "ClassC",
    "AttachmentsA",
    "Comments"
  ],
  "TitleColumns": [
    "ClassA",
    "ClassB",
    "Title"
  ],
  "Columns": [
    {
      "ColumnName": "AttachmentsA",
      "LabelText": "添付資料"
    },
    {
      "ColumnName": "ClassA",
      "LabelText": "作業工程",
      "ChoicesText": "要件定義\n設計\n構築\nテスト\nリリース・展開\n初期サポート\n運用"
    },
    {
      "ColumnName": "ClassB",
      "LabelText": "作業内容",
      "ChoicesText": "調査\n調整/依頼\n申請\nドキュメント作成\n作業[定型]\n作業[非定型]\n打ち合わせ\nその他"
    },
    {
      "ColumnName": "ClassC",
      "LabelText": "機能分類",
      "ChoicesText": "ネットワーク・セキュリティ\nサーバ\n運用\n業務\n"
    }
  ],
  "Aggregations": [
    {
      "Id": 1,
      "GroupBy": "[NotGroupBy]",
      "Type": 1,
      "Target": "WorkValue"
    },
    {
      "Id": 5,
      "GroupBy": "[NotGroupBy]",
      "Type": 1,
      "Target": "RemainingWorkValue"
    },
    {
      "Id": 4,
      "GroupBy": "Owner",
      "Type": 1,
      "Target": "RemainingWorkValue"
    }
  ],
  "ViewLatestId": 1,
  "Views": [
    {
      "Id": 1,
      "Name": "標準",
      "TimeSeriesGroupBy": "ClassC",
      "TimeSeriesAggregateType": "Total",
      "KambanGroupByY": "ClassC"
    }
  ],
  "TitleSeparator": ""
}

比較的単純なので、「テーブルの管理」を使わずに直接編集することも可能です。以下に、いくつか主要なものを説明します。これ以外にも「テーブルの管理」で設定するものは、ほとんどこちらのJSONに格納されます。

・GridColumns:一覧画面に表示する項目
・EditorColumns:編集画面に表示する項目
・TitleColumns:タイトルに結合して表示する項目
・Columns:各項目の表示名や詳細設定
・Aggregations:集計機能で利用する項目と集計方法
・Views:ビューの設定

テーブルの管理で設定して、JSONを確認すると、どの設定がどの項目に対応するか簡単に把握できます。ぜひためしてみてください。

また、このJSONは、コピーして他のテーブルで使用したり、他の環境に移行するために使うこともできます。ただし、以下の項目は環境ごとに異なるIDをもっていたり、他のテーブルにも関連情報が格納されるので再設定が必要です。ご注意ください。

・リンクの設定(環境毎に異なるサイトIDが含まれる)
・サイトのアクセス制御(Permissionsテーブルに設定情報が格納される)
・レコードのアクセス制御(環境毎に異なる組織ID, グループID, ユーザIDが含まれる)
・項目のアクセス制御(環境毎に異なる組織ID, グループID, ユーザIDが含まれる)

今年もPleasanter開発チームをよろしくおねがいします!

PleasanterをAzureに構築する際に必要なリソース

Pleasanter開発チームのしわです。

Azure上で構築が可能なプリザンターですが、その際に必要な最低限のリソースをまとめてみました。

最低限必要なリソースは以下の4つです。
(すべて同じリソースグループ内に作成する必要があります) f:id:implem-shiwa:20181213093900p:plain

1.App Service
 プリザンターのソースをデプロイするのに必要です。ここでプリザンターが動作します。
2.App Service プラン
 App Serviceにデプロイされるアプリケーションのパフォーマンスに影響します。
 App Service作成時に同時にプラン設定を行うことで自動的に作成されます。
3.SQL Server
 SQL データベースを動作させるために必要な論理サーバーです。
4.SQL データベース
 プリザンターのデータ格納に必要です。

上記の最低限必要なAzure環境を用意したうえで、以下のマニュアルの手順に従うとAzure上でプリザンターの構築が可能です。

プリザンターのインストール Azure編 · Implem/Implem.Pleasanter Wiki · GitHub

メールの設定

また、メールによるリマインダや通知機能を追加する際は以下の記事を参考にSendGridの設定もしておきましょう。

プリザンターをMicrosoft Azureにインストールした後のメール送信の設定 - Pleasanter developers blog

リマインダの設定

リマインダの設定には上記に加えてAzure上でWebジョブの設定が必要です。
1.以下のURLよりReminder.ps1ファイルをダウンロード
Implem.Pleasanter/Reminder.ps1 at master · Implem/Implem.Pleasanter · GitHub
2.ダウンロードしたReminder.ps1ファイルを開き、「http://localhost/pleasanter」の部分をお手元のプリザンターの環境に合わせて修正
3.1行目のコメントアウトを有効化する
4.Azuzre ポータルでプリザンターのApp Serviceを選択
5.左側の機能一覧から「Webジョブ」を選択
6.メニューバーの「+追加」をクリック
7.ジョブ名(任意)を入力し、Reminder.ps1ファイルをアップロード。
  その際、「種類」は”継続”を、「スケール」は”単一のインスタンス”を選択

まとめ

プリザンターをAzureに構築する際に必要な手順
・Azure環境の構築
・プリザンターのパラメータ(json)設定
・プリザンターのデプロイ

手順としてはそこまで複雑ではないので、
これを機会にAzure上でのプリザンター構築を検討してみてはいかがでしょうか?
ぜひお試しください!

Pleasanterのコードスタイル 空白行編

Pleasanter開発チームのいしざきです。

PleasanterはオープンソースのWebデータベースでGitHubにソースが公開されています。

今回はPleasanterへプルリクエスト(PR)する際に気にしたいコードスタイル 空白行編です。

コードの上で空白行というと何を思い浮かべるでしょうか? 詳し方ならリーダブルコード

コードを「段落」に分割する

の節を思い浮かべるかもしれません。リーダブルコードは素晴らしい指針です。しかし世界の全てのプロジェクトが同じルールを採用しているわけではありません。

よく見るスタイルとPleasanterの比較

次の例はよく見るコードルールで書かれたC#クラスです。このクラスがPleasanterではどうなるか見てみましょう。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace SampleApp
{
    public class PopularStyleClass
    {
        public async Task<string> GetDataFromWeb()
        {
            // Create HttpClient
            var httpClient = CreateHttpClient();
            httpClient.Timeout = new TimeSpan(TimeSpan.TicksPerSecond * 20L);

            // Request Data
            var contentData = "<contentData>";
            var requestContent = new StringContent(contentData);

            // Post
            var responceMessage = 
                await httpClient.PostAsync("<requestUrl>", requestContent);

            // Responce Data
            var responceContent = responceMessage.Content;
            var responceData = await responceContent.ReadAsStringAsync();
            return responceData;
        }

        HttpClient CreateHttpClient()
            => new HttpClient();
    }
}

Pleasanterでは次のようになります。
(※筆者も勉強中のため100%正しいPleasanterのスタイルではないかもしれません。勉強のためにこの記事を書いている面もあります)

using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace SampleApp
{
    public static class PleasanterStyleClass
    {
        public static async Task<string> GetDataFromWeb()
        {
            var hc = CreateHttpClient();
            hc.Timeout = new TimeSpan(ticks: TimeSpan.TicksPerSecond * 20L);
            return await (await hc
                .PostAsync(
                    requestUri: "<requestUrl>",
                    content: new StringContent("<contentData>")))
                .Content
                .ReadAsStringAsync();
        }

        private static HttpClient CreateHttpClient()
        {
            return new HttpClient();
        }
    }
}

Pleasanterの空白行

Pleasanterの空白行はクラスのメンバーとメンバーの間だけです。

usingとnamespaceの間について

よく見るスタイルではusingとnamespaceの間に空白行があります。

using System.Threading.Tasks;

namespace SampleApp

Pleasanterではusingとnamespaceの間に空白はありません。

using System.Threading.Tasks;
namespace SampleApp

メソッド内の段落について

よく見るスタイルではメソッド内に段落の空白行があります。

// Create HttpClient
var httpClient = CreateHttpClient();
httpClient.Timeout = new TimeSpan(TimeSpan.TicksPerSecond * 20L);

// Request Data
var contentData = "<contentData>";

Pleasanterではメソッド内に段落の空白はありません。

var hc = CreateHttpClient();
hc.Timeout = new TimeSpan(ticks: TimeSpan.TicksPerSecond * 20L);
return await (await hc

メソッドとメソッドの間

Pleasanterでは空白はクラスのメンバーとメンバーの間だけです。

        .ReadAsStringAsync();
}

private static HttpClient CreateHttpClient()

PRのお願い

PleasanterへのPRいただける際には空白はメンバーとメンバーの間だけでお願いします。
また、メンバーとメンバーの間以外の空白行やメンバーとメンバーの間に空白行のない箇所を見つけた方、ぜひ修正してPRお願いします。

その他のコードスタイル

今回のコード例だけでも空白行以外にも様々なコードルールが読み取れますが、Pleasanterは日々進化中でPR時のお願い事項などの整備は取り組み中の状態です。

不定期になりますが今後も少しずつこちらのブログで紹介してまいります。今後PRするかもしれないという方、継続してチェックしていただけると嬉しいです。

プリザンターAPIの仕様見直しについて

開発チームの小林です。 今回、プリザンターのAPIの仕様を見直し、バージョン 0.49.57.x 以降にて新方式のAPIが利用可能となっております。 なお、旧バージョンのAPIについても継続してご利用可能です。

API機能:レコード操作 · Implem/Implem.Pleasanter Wiki · GitHub

変更点

旧バージョンからの変更点は、以下の3点です

URL

リクエストURLを以下のように変更しました。

Content-Type

リクエストヘッダに指定するContent-Typeを'application/json'に変更

  • 変更前: 'application/x-www-form-urlencoded'
  • 変更後: 'application/json'

エラーレスポンス時のステータスコード

旧バージョンでは、エラー時でもステータスコード200(OK)を返却し、レスポンスBodyのJSON内にエラーのステータスコードを格納していましたが、 エラーの内容に一致するステータスコードを設定するように変更いたしました。

  • 変更前:
Status Code : 200 
Body: 
{
      "Id":0,
      "StatusCode":500,
       "Message":"この操作を行うための権限がありません。"
}
  • 変更後:
Status Code : 500
Body: 
{
      "Id":0,
      "StatusCode":500,
       "Message":"この操作を行うための権限がありません。"
}

上記の変更点以外、リクエストおよび、レスポンスのJSONの形式等に変更はありません。

CustomDefinitionsによるPleasanterの定義情報の書き換え

開発チームの内田です。 プリザンターのロゴおよびノベルティが出来上がって、開発チームもテンションがあがってきました。

 

 

今日はプリザンターの定義情報(データベースのカラム情報など)を設定ファイルCustomDefinitionsで置き換える方法についてです。プリザンターの設定ファイルは以下にExcel形式で格納されています。

\Pleasanter\Implem.Pleasanter\App_Data\Definitions

 

上記の内容は、CustomDefinitionsのJsonファイルで特定の項目の値をオーバーライドすることが可能です。たとえば「記録テーブル」の規定の表示名「分類A」を「項目A」に変更する場合には、以下のようなファイルを配置します。ファイルを配置した後は、IISの再起動が必要です。

 

ファイルパス:

\Pleasanter\Implem.Pleasanter\App_Data\Parameters\CustomDefinitions

ファイル名:(definition_Column.xlsmを変更する場合はColumn.jsonとします)

Column.json

内容:(ResultsテーブルのClassA項目の表示名を変更する場合の記述)

{
    "Results_ClassA": {
        "LabelText": "項目A"
    }
}

definition_Column.xlsmを書き換えても同様のことが可能ですが、xlsmファイルは変更点の管理が面倒なので、CustomDefinitionsによる設定をお勧めしています。