Photo by Amy Chandra on Pexels.com

tMDbのAPIを使用して今まで観た映画をリスト化してみましたよ.

2025.04.27

Logging

おはようございます.tMDbのAPIを使用して今まで観た映画をリスト化してみましたよ.sqliteの構造は下記になります.idはbigintと記載していますが、AUTO_INCREMENTの間違いです🐼.

Xにも呟きましたがAPIを使用して何かするのはこの頃飽きてきて触らなかったのですが、たまには触れてみようとコードを書いているうちに簡単に作れるようになってしまって少々物足りなさを感じています.

次回はAPIを使う側ではなくて作る側になろうと思っています.GW期間になると思いますが600円のレンタルサーバーのフリードメインを使ってツマラナイAPIみたいな失笑系を作ってみます.

なお、ソースコードの解説がなくてすみません、このソースコードを生成AIに投げてどのような処理か説明して言えば恐らく正解を教えてくれます.

明日へ続く

#真相をお話します.
少年と犬
Flow
curl -sS https://getcomposer.org/installer | php
composer require guzzlehttp/guzzle
composer require illuminate/database
<?php
require_once 'config.php';
require_once 'vendor/autoload.php';
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Database\Capsule\Manager as DB;

class MovieList
{
    public $result = '';
    public $imgBasicUrl = 'https://image.tmdb.org/t/p/w500';
    public $filePath = FILEPATH_DIR_;
    public function __construct($filePath='')
    {
        $filePath = $filePath?$filePath:$this->filePath;
        if (!file_exists($filePath.'/movie-list.db')) {
            exit;
        }        
        $capsule = new Capsule();

        $capsule->addConnection([
            'driver'   => 'sqlite',
            'database' => $filePath.'/movie-list.db',
            'prefix'   => '',
        ]);

        $capsule->setAsGlobal();
        $capsule->bootEloquent();
    }

    public function getMovieList(string $q): void
    {
        $client = new \GuzzleHttp\Client();

        $response = $client->request('GET', 'https://api.themoviedb.org/3/search/multi?query=' . $q . '&include_adult=false&language=ja-JP&page=1', [
            'headers' => [
                'Authorization' => 'Bearer ' . API_KEY,
                'accept' => 'application/json',
            ],
        ]);
        $this->result = $response->getBody();
    }

    public function getResult(): void
    {
        $data = DB::table('list')->get();
        $lists = [];
        foreach ($data as $key => $value) {
           $result = unserialize($value->value);
            if(isset($result?->media_type) && $result->media_type == 'movie'){
                $lists[] = [
                    'id'=>$data[$key]->id,
                    'title'=>$result->title,
                    'img'=>$this->imgBasicUrl . $result->poster_path,
                ];
            }
        }
        print json_encode($lists);
    }

    public function saveCsvlist(): void
    {
        $fileData = explode("\n",file_get_contents('movie-list.csv'));
        $fileData = array_reverse($fileData);
        foreach($fileData as $line)
        {
            foreach(explode(',',$line) as $data){
                $q = urlencode($data);
                $movieList = new MovieList();
                $movieList->getMovieList($q);
                foreach((json_decode($movieList->result))?->results as $result){
                    DB::table('list')->insert([
                        'value' => serialize($result)
                    ]);
                }
            }
        }        
    }

    public function delete($id): void
    {
        
        DB::table('list')->where('id', '=', $id)->delete();
        print json_encode(['res'=>'true']);
    }

}
//(new MovieList())->saveCsvlist();
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
    if(!isset($_POST['id'])){
        (new MovieList())->getResult();
    }else{
        //(new MovieList())->delete($_POST['id']);
    }   
}

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

```, コード, ソースコード, ツマラナイ, フリードメイン, レンタルサーバー, , , 処理, 失笑系, 少年, 構造, 次回, 正解, , 生成, 真相,

Camera+ recipe? ? scene: Cloudy ? crop: Golden ? effect: Redscale (77%) ? border: Round White

Reactでパスワード生成にバグがあって数値、記号が確実に入らなかったので.

2025.04.22

Logging

おはようございます.Reactでパスワード生成にバグがあって数値、記号が確実に入らなかったのでその修正を先日行いました.そういやそうだなってソースコードを見返して思った次第です…

修正したコードはこちらになります.その話とは別にVScodeにもAI補助が付いてから自分も生成AIと言う物を個人開発するときに使用するようになっただけど…

import RingLoader from "react-spinners/RingLoader";
import { useState } from "react";
import "./App.css";

function PasswordTmp() {
  const [passwordLength, setPasswordLength] = useState(8);
  const [password, setPassword] = useState("");
  const [includeSymbols, setIncludeSymbols] = useState(false);
  const [includeNumbers, setIncludeNumbers] = useState(false);

  function makePassword(passwordLength, includeSymbols, includeNumbers) {
    const lowercase = "abcdefghijklmnopqrstuvwxyz";
    const uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const numbers = "0123456789";
    const symbols = "!@#$%^&*()_+[]{}|;:,.<>?";
    let characters = lowercase + uppercase; // 文字のセットを初期化
    if (includeNumbers) {
      characters += numbers; // 数字を追加
    }
    if (includeSymbols) {
      characters += symbols; // 記号を追加
    }
    let result = remakePassword(characters,includeNumbers,includeSymbols);
    setPassword(result);
  }

  function remakePassword(characters,includeNumbers,includeSymbols){
    let passwords = "";
    let NumbersChecking = true;
    let SymbolsChecking = true;
    for (let i = 0; i < passwordLength; i++) {
      const randomIndex = Math.floor(Math.random() * characters.length);
      passwords += characters[randomIndex]; // ランダムな文字を選択
    }
    if (includeNumbers) {
      NumbersChecking = passwords.match(/[0-9]/g) ? true : false;
    }
    if (includeSymbols) {
      SymbolsChecking = passwords.match(/[\!@#\$%\^&\*\(\)_\+\[\]\{\}\|;:\,\.<>\?]/g) ? true :false;
    }
    return NumbersChecking && SymbolsChecking?passwords:remakePassword(characters,includeNumbers,includeSymbols);
  }


  return (
    <>
      <div>
        <h1>パスワード生成</h1>
        <p>
          <input
            type="number"
            value={passwordLength}
            placeholder="パスワードの長さ"
            max={99}
            min={3}
            onChange={(e) => setPasswordLength(e.target.value)}
          />
        </p>
        <p>
          <input id={'Symbols'}
            type="checkbox"
            value={1}
            checked={includeSymbols}
            onChange={(e) => setIncludeSymbols(e.target.checked)}
          />
          <label for={'Symbols'}>記号を含める</label>
        </p>
        <p>
          <input id={'Numbers'}
            type="checkbox"
            value={1}
            checked={includeNumbers}
            onChange={(e) => setIncludeNumbers(e.target.checked)}
          />
          <label for={'Numbers'}>数字を含める</label>
        </p>
        <button
          className="btn"
          onClick={() =>
            makePassword(passwordLength, includeSymbols, includeNumbers)
          }
        >
          パスワードを生成
        </button>
        <button
          className="btn"
          onClick={() => navigator.clipboard.writeText(password)}
        >
          パスワードをコピー
        </button>
        <p>生成されたパスワード: {password}</p>
        <p>パスワードの長さ: {passwordLength}</p>
        <p>記号を含める: {includeSymbols ? "はい" : "いいえ"}</p>
        <p>数字を含める: {includeNumbers ? "はい" : "いいえ"}</p>
      </div>
    </>
  );
}

export default PasswordTmp;

この頃、補完機能がとても「うざったく」思う時と「ありがとう」と思うときが存在していてなんとも言えない.特にウザって思うときは自分が望んでいないコードが出てきた時は正直困る.コードを直打ちしないといけないので今までの補完機能がやはり良いなと思います.

自分としては生成AIの補完機能をOFFに出来る機能がほしいところ、それがあればとてもコードを書くのは快適ですねー.あるのかなぁー🤔調べてみます.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

コード, コピー, セット, ソースコード, バグ, パスワード, パスワード生成, ほしいところ, ランダム, 修正, 初期化, 数値, 数字, 文字, 次第, 生成, 補助, 補完機能, 記号, 選択,

Reactの簡単なものなら今でも作れるのだけども.#簡単止まり.

2025.04.20

Logging

おはようございます.Reactの簡単なものなら今でも作れるのだけども簡単止まりなところを1UPしたいなと思っています.Xにもポストしたんだけどパスワード生成出来るものをReactで作ったのでソースコードを公開しますね.

Reactは基本そのままだとさくらレンタルサーバーなどでは動かないだけど、viteというモノを使用してビルドするとJavascriptに変換されたソースコードが出力されるので、それをレンタルサーバーにファイルアップロードする事によりレンタルサーバーでも動くようになります.

Reactにviteというモノを導入するに当たってDockerにUbuntuかcentOSなどを構築してその中にNodeJsとApache2を入れて自分はビルドしたモノを確認しています.

普通はNodeJsでサーバー立ててそちらで確認するのが普通なんだと思うのだけど、それだとレンタルサーバーで動いているかどうかが分からないので自分はビルド後のdistフォルダを中をApacheと紐づけて確認している形です.

トイウコトデ、ソースコードとサイトのリンクを貼っときます.

import RingLoader from "react-spinners/RingLoader";
import { useState } from "react";
import "./App.css";

function PasswordTmp() {
  const [passwordLength, setPasswordLength] = useState(8);
  const [password, setPassword] = useState("");
  const [includeSymbols, setIncludeSymbols] = useState(false);
  const [includeNumbers, setIncludeNumbers] = useState(false);

  function makePassword(passwordLength, includeSymbols, includeNumbers) {
    const lowercase = "abcdefghijklmnopqrstuvwxyz";
    const uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const numbers = "0123456789";
    const symbols = "!@#$%^&*()_+[]{}|;:,.<>?";
    let characters = lowercase + uppercase; // 文字のセットを初期化
    if (includeNumbers) {
      characters += numbers; // 数字を追加
    }
    if (includeSymbols) {
      characters += symbols; // 記号を追加
    }
    let passwords = "";
    for (let i = 0; i < passwordLength; i++) {
      const randomIndex = Math.floor(Math.random() * characters.length);
      passwords += characters[randomIndex]; // ランダムな文字を選択
    }
    setPassword(passwords); // パスワードを更新
  }

  return (
    <>
      <div>
        <h1>パスワード生成</h1>
        <p>
          <input
            type="number"
            value={passwordLength}
            placeholder="パスワードの長さ"
            max={99}
            min={3}
            onChange={(e) => setPasswordLength(e.target.value)}
          />
        </p>
        <p>
          <input id={'Symbols'}
            type="checkbox"
            value={1}
            checked={includeSymbols}
            onChange={(e) => setIncludeSymbols(e.target.checked)}
          />
          <label for={'Symbols'}>記号を含める</label>
        </p>
        <p>
          <input id={'Numbers'}
            type="checkbox"
            value={1}
            checked={includeNumbers}
            onChange={(e) => setIncludeNumbers(e.target.checked)}
          />
          <label for={'Numbers'}>数字を含める</label>
        </p>
        <button
          className="btn"
          onClick={() =>
            makePassword(passwordLength, includeSymbols, includeNumbers)
          }
        >
          パスワードを生成
        </button>
        <button
          className="btn"
          onClick={() => navigator.clipboard.writeText(password)}
        >
          パスワードをコピー
        </button>
        <p>生成されたパスワード: {password}</p>
        <p>パスワードの長さ: {passwordLength}</p>
        <p>記号を含める: {includeSymbols ? "はい" : "いいえ"}</p>
        <p>数字を含める: {includeNumbers ? "はい" : "いいえ"}</p>
      </div>
    </>
  );
}

export default PasswordTmp;

https://zxz.sakura.ne.jp

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

コピー, さくらレンタルサーバー, セット, ソースコード, トイウコトデ, ところ, パスワード, パスワード生成, ビルド後, フォルダ, ランダム, レンタルサーバー, 初期化, , 数字, 文字, 普通, 生成, , 記号,

CSSだけで3Dボックス(箱)が作れるようにいつの間にかなっていた.自動回転!?

2025.04.16

Logging

おはようございます.CSSだけで3Dボックス(箱)が作れるようにいつの間にかなっていた話を書いていきます.生成AIにCSSだけで3Dボックス(箱)を作ってと指示を行ったら自動回転してくれるものを出力してくれて驚愕している.

CSSだけで3Dボックスが作れることは知っていたのだけど、自動回転はJSを使用しないと無理だろうと思っていたので、実際生成AIが出力されたのを見て驚きでした.こんな感じで旧の知識を生成AIはアップデートしてくれるのには、凄く良いと思っています.

ただ、質問して実際動かないものも出力されるので要は使う側もそれなりに知識を持っていないと嘘を信じてしまうことにもなるので、生成AIを使う側も最低限の知識は必要になると思っています.

因みにソースコードは下記になります.これをテキストファイルに保存して拡張子をhtmlに変えた後に、そのファイルをブラウザにドロップすると表示されます.

明日へ続く

デモページ:https://zip358.com/tool/demo96/

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>3D Box</title>
  <style>
    body {
      margin: 0;
      background: #111;
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      perspective: 1000px;
    }

    .scene {
      width: 200px;
      height: 200px;
      position: relative;
      transform-style: preserve-3d;
      animation: rotate 10s infinite linear;
    }

    .face {
      position: absolute;
      width: 200px;
      height: 200px;
      background: rgba(0, 150, 255, 0.7);
      border: 2px solid #fff;
    }

    .front  { transform: translateZ(100px); }
    .back   { transform: rotateY(180deg) translateZ(100px); }
    .right  { transform: rotateY(90deg) translateZ(100px); }
    .left   { transform: rotateY(-90deg) translateZ(100px); }
    .top    { transform: rotateX(90deg) translateZ(100px); }
    .bottom { transform: rotateX(-90deg) translateZ(100px); }

    @keyframes rotate {
      from { transform: rotateX(0deg) rotateY(0deg); }
      to   { transform: rotateX(360deg) rotateY(360deg); }
    }
  </style>
</head>
<body>
  <div class="scene">
    <div class="face front"></div>
    <div class="face back"></div>
    <div class="face right"></div>
    <div class="face left"></div>
    <div class="face top"></div>
    <div class="face bottom"></div>
  </div>
</body>
</html>

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

ソースコード, テキストファイル, デモページ, ファイル, ブラウザ, ボックス, 下記, , , 実際, 実際生成, 感じ, 拡張子, 指示, , 最低限, 生成, 知識, , 自動回転は,

FF14のエオルゼア時間を表示するツールのソースコードを作りましたのでお裾分け.

2025.04.10

Logging

おはようございます.先人の知恵を拝借して人工知能にぶん投げてソースコードを作っていただきました.尚、ツワモノさんがいて天候などもいつ起きるのか把握できるそうです.どういうアルゴリズムなのかは見ていないので分からないけど自分でも可能そうな気もします.

因みにソースコードをこちらに貼り付けておきますのでご自由にご使用ください.それにしてもオンラインゲームなのに自分の狩り場には人っ子一人いないのが悲しいです.

function lt2et(date) {
  // UNIX時間(秒)を取得
  const ut = date.getTime() / 1000;

  // エオルゼア時間1/1/1 00:00:00から経過した秒数
  const et_seconds = (ut * 60.0) / 175.0;

  // 各エオルゼア単位を計算
  const et_hours = ut / 175.0;
  const et_days = et_hours / 24.0;
  const et_months = et_days / 32.0;

  const et_year = et_months / 12.0 + 1.0;
  const et_month = (et_months % 12.0) + 1.0;
  const et_date = (et_days % 32.0) + 1.0;
  const et_hour = et_hours % 24.0;
  const et_minute = et_seconds % 60.0;

  return {
    year: Math.floor(et_year),
    month: Math.floor(et_month),
    date: Math.floor(et_date),
    hour: Math.floor(et_hour),
    minute: Math.floor(et_minute),
  };
}
setInterval(() => {
  let date;

  date = new Date(); // 現在時刻

  const et = lt2et(date);

  // 出力(例: 0001-01-01 00:00)
  document.getElementById("output").textContent = `
  ${et.month.toString().padStart(2, "0")}-${et.date
    .toString()
    .padStart(2, "0")} ${et.hour.toString().padStart(2, "0")}:${et.minute
    .toString()
    .padStart(2, "0")}
`;
}, 0);

Lv30なったらチョコボに乗れるらしいのでいまはそれを楽しみにしてソロで狩り続けています.

最後にZen foxで活動しています.
※Hades【Mana】で活動しています.
フォロー等よろしくお願いいたします🙇.
https://jp.finalfantasyxiv.com/lodestone/character/34913141/

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

```, アルゴリズム, エオルゼア時間, オンラインゲーム, ソースコード, ソロ, チョコボ, ツワモノさん, 人工知能, , 出力, 各エオルゼア単位, 天候, 時刻, 最後, 狩り場, 知恵, , 秒数, 計算,

アナログ時計をTOPページに追加しました.ソースコードはこちら.

2025.03.26

Logging

おはようございます.アナログ時計をTOPページに追加しました.ソースコードはこちらに記載していきます.尚、ソースコードは生成AI、Grokを使用して制作しました.

<div class="clock">
    <div class="hand hour-hand"></div>
    <div class="hand minute-hand"></div>
    <div class="hand second-hand"></div>
    <div class="center-clock"></div>
</div>
.clock {
  /* width: 200px;
  height: 200px;
  border: 2px solid rgb(226, 226, 226); */
  border-radius: 50%;
}

.hand {
  position: absolute;
  bottom: 50%;
  left: 50%;
  transform-origin: bottom;
  background: #333!important;
}

.hour-hand {
  width: 4px;
  height: 60px;
  background: #333!important;;
}

.minute-hand {
  width: 3px;
  height: 80px;
  background: #666!important;;
}

.second-hand {
  width: 2px;
  height: 90px;
  background: rgb(94, 93, 93)!important;;
}

.center-clock {
  width: 10px;
  height: 10px;
  background: rgb(95, 95, 95)!important;;
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 4;
}
        function updateClock() {
            const now = new Date();
            const hours = now.getHours();
            const minutes = now.getMinutes();
            const seconds = now.getSeconds();

            // 角度の計算
            const hourDeg = (hours % 12 + minutes / 60) * 30; // 12時間で360度
            const minuteDeg = (minutes + seconds / 60) * 6; // 60分で360度
            const secondDeg = seconds * 6; // 60秒で360度

            // 針の回転
            document.querySelector('.hour-hand').style.transform = `translateX(-50%) rotate(${hourDeg}deg)`;
            document.querySelector('.minute-hand').style.transform = `translateX(-50%) rotate(${minuteDeg}deg)`;
            document.querySelector('.second-hand').style.transform = `translateX(-50%) rotate(${secondDeg}deg)`;
        }

        // 初回実行
        updateClock();
        // 1秒ごとに更新
        setInterval(updateClock, 1000);

生成AIが最初登場した時はここまで出来なかったので一回目の指示でちゃんとしたものを制作していけるようになったというのは正直なところ驚きです.やっぱり指数関数的に人工知能は成長するのかなとたまに思うことがありますが、それと相反する思いも持っています.

相反するとは、あと5年ぐらいで人工知能も頭打ちになるじゃないかなとも思っています.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

```, アナログ時計, ソースコード, ところ, 人工知能, , 初回実行, 回転, , , 指数, 指示, 最初, 生成, , 秒ごと, 角度, 計算, , 頭打ち,

クラシックAPIを使用してGitHub APIから草データを取得.

2025.03.12

Logging

おはようございます.クラシックAPIを使用してGitHub APIから草データを取得するコードをAPI使用しつつ手直してモノの数分で完成しました.こういうのを思うと少人数の開発でも希望を持てるなって思います.ちなみに自分は未だに無料枠でコードを生成してもらっています.

正直なところ、無料枠で事が足りるという印象ですね.コードの改善や命名は生成AIにやってもらった方が優秀です、自分の無能がよくわかります.

草データの使用方法はタイトル通りなので特に問題ないかなって思います.コンフィグファイルは書かずしても変数に代入してあげれば良いわけですからね.一応、github上にソースコードを掲載しています.

https://github.com/taoka3/GitHubGrass

良かったらいいね👍️(⭐️)宜しくお願い致します.

<?php
class GitHubGrass
{
    private string $token;
    private string $username;
    private array $weeks = [];
    private int $cellSize = 12;
    private int $padding = 2;
    private array $colors = [];

    public function __construct(string $username, string $token)
    {
        $this->username = $username;
        $this->token = $token;

        // 色の設定(GitHub風)
        $this->colors = [
            'level0' => [235, 237, 240],
            'level1' => [155, 233, 168],
            'level2' => [64, 196, 99],
            'level3' => [48, 161, 78],
            'level4' => [33, 110, 57]
        ];
    }

    /**
     * GitHub APIから草データを取得
     */
    public function fetchContributions(): bool
    {
        $url = 'https://api.github.com/graphql';
        $query = <<<'JSON'
        {
          user(login: "USERNAME") {
            contributionsCollection {
              contributionCalendar {
                weeks {
                  contributionDays {
                    contributionCount
                  }
                }
              }
            }
          }
        }
        JSON;

        // ユーザー名を埋め込む
        $query = str_replace("USERNAME", $this->username, $query);

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $this->token,
            'User-Agent: ContributionsApp'
        ]);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['query' => $query]));

        $response = curl_exec($ch);
        curl_close($ch);
        $data = json_decode($response, true);
        if (!isset($data['data']['user']['contributionsCollection']['contributionCalendar']['weeks'])) {
            $this->weeks = []; // 空の配列を設定
            return false;
        }

        $this->weeks = $data['data']['user']['contributionsCollection']['contributionCalendar']['weeks'];
        return true;
    }

    /**
     * 草画像を生成
     */
    public function generateImage(): string
    {
        if (count($this->weeks)) {
            die('No data available.');
        }

        // 画像サイズ設定
        $width = (count($this->weeks) * ($this->cellSize + $this->padding)) + $this->padding;
        $height = (7 * ($this->cellSize + $this->padding)) + $this->padding;

        // 画像作成
        $image = imagecreatetruecolor($width, $height);
        $bgColor = imagecolorallocate($image, 255, 255, 255);
        imagefill($image, 0, 0, $bgColor);

        // 色の作成
        $colorPalette = [];
        foreach ($this->colors as $key => $rgb) {
            $colorPalette[$key] = imagecolorallocate($image, ...$rgb);
        }

        // セル描画
        foreach ($this->weeks as $x => $week) {
            foreach ($week['contributionDays'] as $y => $day) {
                $count = $day['contributionCount'];
                $color = $this->getColor($count, $colorPalette);

                // 四角形を描画
                imagefilledrectangle(
                    $image,
                    $x * ($this->cellSize + $this->padding) + $this->padding,
                    $y * ($this->cellSize + $this->padding) + $this->padding,
                    ($x + 1) * ($this->cellSize + $this->padding),
                    ($y + 1) * ($this->cellSize + $this->padding),
                    $color
                );
            }
        }

        // 出力
        ob_start();
        imagepng($image);
        $imageData = ob_get_contents();
        ob_end_clean();
        imagedestroy($image);

        $base64 = base64_encode($imageData);

        return $base64;
    }

    /**
     * コントリビューション数に応じた色を取得
     */
    private function getColor(int $count, array $colorPalette)
    {
        if ($count == 0) {
            return $colorPalette['level0'];
        } elseif ($count < 5) {
            return $colorPalette['level1'];
        } elseif ($count < 10) {
            return $colorPalette['level2'];
        } elseif ($count < 20) {
            return $colorPalette['level3'];
        } else {
            return $colorPalette['level4'];
        }
    }
}

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

```, $代, から草データ, クラシック, コード, コントリビューション数, コンフィグファイル, セル描画, ソースコード, 出力, 命名, 四角形, 変数, 少人数, 手直し, 描画, 未だ, 生成, 配列,

Photo by Suzy Hazelwood on Pexels.com

「so」は「shared object(シェアード・オブジェクト)」の略です.古い環境をWEB構築する方法.

2025.03.09

Logging

おはようございます.以前の職場でPHPのソースコードをビルドしてPHPのバージョン何パターンか作っていましたが、今でもテスト環境というものはあるのでしょうか?アンサー無いでしょうね、きっと.今ではDockerという便利な物がありますから.

さて古い環境をWEB構築する手順を箇条書きに記載していきます.まず古いPHPを動かすには古いOpenSSLが必要になってきます.まずはOpenSSLのソースコードが必要になりそれをビルドします.OpenSSLがPHPで必要になってくると書きましたが、必要になるパターンはphp-opensslを使用する場合です.例えばphpのフレームワークなどを導入している環境では必ずと言って良いほど、php-opensslを使用しているので古いOpenSSLも必要になってきます.

sudo yum groupinstall -y "Development Tools"
sudo yum install -y perl gcc make
wget https://www.openssl.org/source/openssl-1.1.1.tar.gz
tar xvf openssl-1.1.1.tar.gz
cd openssl-1.1.1
./config --prefix=/usr/local/openssl1.1.1 --openssldir=/usr/local/openssl1.1.1 shared zlib
make
make install

上記のような感じでOpenSSLのソースコードをダウンロード=>解凍=>ビルドします.ここでミソなのがso(拡張子:shared object(シェアード・オブジェクト))を作って上げることです.ここで自分は躓きました.soを作らずにphp-opensslをビルドしていたのでビルド時にエラーが出力されました.

phpのビルドは下記のような感じです.他にも拡張モジュールが必要な場合はそれに合わして追記記載が必要になってきます.

sudo yum groupinstall -y "Development Tools"
sudo yum install -y autoconf bison re2c libxml2-devel sqlite-devel \
    libcurl-devel openssl-devel git gcc make
git clone https://github.com/php/php-src.git
cd php-src
git checkout PHP-7.0.0
./buildconf
./configure --prefix=/usr/local/php7.0 --with-openssl=/usr/local/openssl1.1.1
make
make install

こうするとPHPの古いフレームワークなどが使用できるようになります.尚、フレームワークなどを使用する場合は他の拡張モジュールがもう少し必要になってきますが原理原則を理解すると出来ると思います.Apacheで動かすには「–with-apxs2=/usr/sbin/apxs」の記載も必要になってきます.尚、php-fpmを使用したい場合は「–enable-fpm」を追記してFirstCGIで動かすということで良いと思います.両者ともApacheの設定は必要となります.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

アンサー, エラー, シェアード・オブジェクト, ソースコード, パターン, ビルド, ビルド時, フレームワーク, ミゾ, 両者, 原理原則, 古い, 古いフレームワーク, 手順, 拡張モジュール, 拡張子, 箇条書き, 職場, 解凍, 追記記載,

業務でGitHubの通知にメールを使用していたけど遅すぎて

2025.03.01

Logging

おはようございます.業務でGitHubの通知にメールを使用していたけど遅すぎて困ると思ったので、GitHubのChrome拡張を使用することにしました.因みに自分が使用しているのはNotifier for GitHubではなくてGitHub Desktop Notificationの方です.

理由はAPI機能を使用していない点です.DOM構造で見に行って新着があるかを判断している.DOM構造はローカルストレージに保存しているだということなので良さげかなと思ったのと、日本人開発者だった点、そしてソースコードはオープンにしている点です.

一週間ぐらい試してみて不具合などが無ければこちらを使用してみようと思っています.それにしても何故にメールのデスクトップ通知が遅くなったのかは謎です.

リモートワーク勤務をしているのでレスだけは早くしたいなって思います.因みにGitHubデスクトップを導入している人はデスクトップ通知を許可することで通知が来るらしいです.

追記:どうも重い.PCが落ちだしたのでアンイストール.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

アンイストール, ソースコード, デスクトップ, デスクトップ通知, メール, リモートワーク勤務, レス, ローカルストレージ, 一週間, 拡張, 新着, 業務, 構造, 機能, , 理由, 良さげ, , 追記, 通知,

低学年向けの学習サイトを作ってみました. 今のところ無広告で運営中.

2025.02.10

Logging

おはようございます.低学年向けの学習サイトを作ってみました. 今のところ無広告で運営中です、因みにこのサービスは数年前にこのサイトにも存在しているものをlaravelとvueで再構築した形になります.

このサイト制作に費やした時間は1時間ぐらいです、いやー結構かんたんにそれらしい物が出来たので、自分としては満足です.アクセス数が多くなれば広告掲載などを考えています.

楽しんで学ぶ

広告掲載はトップのみに表示させるようにします.学習中に広告があるのは気が散りますからね.尚、このサイトは生成AIのちからを借りて制作したのでものの1時間ぐらいで完成した形になります.これから先こんな感じで自然言語の命令でコードを生成AIに書かして人はソースコードのチェックや動作チェックだけをするようになるのかも知れないなと思いましたが、やはり100%と生成AIが生成したものに対して保証が担保出来ない限り、コーダーさんやプログラマーさんの職が無くなることはなさそうです.

因みに自分は生成AIに課金していません.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

アクセス数, コーダーさん, コード, ソースコード, ちから, ところ無広告, プログラマーさん, 低学年向け, 保証, 再構築, 動作チェック, 命令, 学習サイト, 学習中, , , 生成, , 言語, 限り,

Vue.jsでコードを書き直してみたけどバニラJSが良い時もある技術的な話といえばそんな感じ.

2025.02.09

Logging

おはようございます.何もしていないわけではないけど毎日小銭が入ってきた頃を思うといまは前に戻った感じがあります、やっぱり無いよりある方が良いですね.さてHxH-moji.comサービスのバニラJSコードをVue.jsへ置き換えてみたのだけどもレンダリングが遅くなってこれは駄目だなと思ったので元の状態に戻しました.

たまにバックのソースコードがどんな感じに動いているのかを調べている人がいるのだけど、そんなに大したソースコードが動いているわけではないのでお恥ずかしいですね.最近やっと名前付けを変更してソースコードを見たらわかる感じにしたつもりでいます.

因みに下記がレンダリングが遅くてボツにしたコードです.本当ならVue.jsでサクサクと動くコードを作りたいのですがVue.jsはまだまだ初心者さんレベルです..あまりVue.jsもReactもあまり分からないのが現状です、業務で使用することはあるものの一から作るとなるとあんまり上手く作れないです.

トホホ・・・.

この頃思うのは広告掲載だけで何とか回るものを作りたいなとサブスクは個人ではちょっと荷が重い.重いもありますが何せ審査が通りそうにないECサービスはまだ手を付けていないのはそんな理由です.自分のテンション上がるのを待って作りたいと思います.

const { createApp, ref, onMounted, nextTick } = Vue;

const app = createApp({
    setup() {
        const canvas = ref(null);
        const languageInput = ref('');
        const fontsize = ref(16);
        const alertMessage = ref('');
        const mobileText = ref('');
        const isMobile = ref(window.innerWidth <= 768);

        const fetchText = async (flg) => {
            try {
                const body = new FormData();
                body.append('txt', languageInput.value);

                const response = await fetch("/common/jpcvn", {
                    method: "POST",
                    headers: { "X-CSRF-TOKEN": document.querySelector("[name='token']").value },
                    body: body
                });
                const resultdata = await response.json();
                drawCanvas(resultdata.txt);
                mobileHxH(resultdata.txt);

                canvas.value.toBlob((blob) => {
                    const formData = new FormData();
                    formData.append("upload_data", blob, "canvas_image.png");
                    formData.append("name", document.getElementsByName("name")[0].value);
                    formData.append("sns_name", document.getElementById("sns").value);
                    formData.append("text_data", resultdata.txt);
                    if (!flg) formSave(formData);
                }, "image/png");
            } catch (error) {
                console.error(error);
            }
        };

        const drawCanvas = async (text) => {
            await nextTick();
            if (!canvas.value) return;  // canvasがnullの場合は処理を中止
            const ctx = canvas.value.getContext("2d");
            ctx.clearRect(0, 0, canvas.value.clientWidth, canvas.value.clientHeight);

            const background = new Image();
            background.src = "/images/paper_00107.jpg";
            background.onload = () => {
                ctx.drawImage(background, 0, 0, canvas.value.clientWidth, canvas.value.clientHeight);
                ctx.fillStyle = "rgba(0, 0, 0)";
                ctx.font = `${fontsize.value}px HUNTERxHUNTER`;
                const lines = textChange(text, fontsize.value);
                lines.forEach((line, i) => {
                    ctx.fillText(line, 3, 10 + fontsize.value * (1.1618 * i + 1));
                });
            };
        };


        const textChange = (t, f) => {
            let n = parseInt(350 / f);
            let s = t.split("");
            let LLine = 0;
            for (let i = 0; i < s.length; i++) {
                if (LLine && (LLine + 1) % n === 0) {
                    if (s[i] !== "\n") s[i] += "\n";
                    LLine = 0;
                } else {
                    LLine++;
                    if (s[i] === "\n") LLine = 0;
                }
            }
            return s.join("").split("\n");
        };

        const formSave = async (formData) => {
            alertMessage.value = '';
            try {
                const response = await fetch("/common/image_save", {
                    method: "POST",
                    headers: { "X-CSRF-TOKEN": document.querySelector("[name='token']").value },
                    body: formData,
                });
                const result = await response.json();
                if (result.ret === "ok" && result.url) {
                    window.location.href = result.url;
                } else {
                    alertMessage.value = result.txt;
                }
            } catch (error) {
                console.error(error);
            }
        };

        const mobileHxH = (tt) => {
            if (isMobile.value) {
                mobileText.value = tt;
            }
        };

        const adjustTextareaRows = () => {
            isMobile.value = window.innerWidth <= 768;
        };

        onMounted(() => {
            adjustTextareaRows();
            window.addEventListener("resize", adjustTextareaRows);
        });

        return {
            canvas,
            languageInput,
            fetchText,
            alertMessage,
            mobileText,
            isMobile,
            fontsize
        };
    }
});

app.mount('#app');

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

```, コード, サブスク, ソースコード, テンション, トホホ, バニラコード, ボツ, ももあまり, レンダリング, 下記, 中止, 何せ審査, , 処理, 名前付け, 小銭, 業務, 現状, ,

日本でもそろそろ発売されると思う.ビル・ゲイツの自伝ソースコード洋書はAmazonから.

2025.02.08

Logging

おはようございます.日本でもそろそろ発売されると思う.ビル・ゲイツの自伝ソースコード洋書はAmazonから「Source Code: My Beginnings」と検索するとヒットします😌.英語が読める方は洋書で読むことをオススメします.自分は英語がわからないので翻訳(和訳)が出るまで待ちます.恐らく日本で発売される時の本の題名も「ソースコード ビル・ゲイツ」でしょう.

ビル・ゲイツが語る学生時代、家庭環境、マイクロソフト成功への野望について | The Big Interview | WIRED Japan

技術レベルは違えども自分も何故だかわからないけど、ソースコードを読んだり理解したりするのは好きですね.謎解きゲームのようなもので、複雑怪奇なソースコードも何か何度か見るとわかるようになる不思議なものです.昔はソースコードを読んだりするのは今みたいに好きではなかったのですが、いつの頃から何かわかるようになりました.仕様書がないソースコードを読む場合、全体把握は難しいので一つの関数がどういう振る舞いになっているのかを探っていくことで一つの機能を理解するという感じで徐々に全体像を理解していきます.

トイウコトデ、ソースコードの日本書籍が発売されたら読むつもりでいます.なんとなくですがソースコードは映画化されそうな気がします.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

ソースコード, トイウコトデ, ビル・ゲイツ, 仕様書, 何度, 全体像, 全体把握, 和訳, 技術, 日本書籍, , 映画化, , 洋書, 翻訳, 自伝ソースコード洋書, 英語, 謎解きゲーム, 関数, 題名,

使っていないドメインだけど一番値が高いドメインに暇つぶしでコードを埋め込んでみました.

2025.02.02

Logging

おはようございます.使っていないドメインだけど一番値が高いドメインに暇つぶしでコードを埋め込んでみました.これでソースコードを読める人は少しは楽しめると思います.とくに駆け出しのエンジニアさんには響きそうです.ちなみにドメインは9up.meです、このドメイン更新費用結構お高いけどいま全く使っていなかったドメインです.

少しは活用できたのではと….因みに業者でもないのにドメイン代で年間、1万5千円飛んでいくので自分でも馬鹿だなと思いますが、もっていると何かのとき役に立つのではとか思い込んでいます.恐らくそんな事はないと思いますが心の底あたりにあるですあるです欲が…..w

あと、こちらのドメインに限らずですがSSLのCNが変なんですよねぇ.どうやって直せばよいでしょうか🤔.リニューでもしないといけないのかなぁ?そもそもSSLのCNがFQDN(ドメイン)が不一致でも良いらしいですよねぇなのでまぁ良いかと思っています.

あと続きでVueの読み方はヴューが正しいらしいのですがビューと日本人は読んでいるらしいですよ.そしてそちらが定着していますよね、やっぱ日本人にはヴューは読みづらいですよね.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

ヴュー, エンジニアさん, コード, ソースコード, ドメイン, ドメイン代, ドメイン更新費用, ビュー, リニュー, 一番値, 不一致, 少し, 年間, 底あたり, , , 業者, , 読み方, 高いドメイン,

生成AIでポートフォリオサイトを作ってでどれぐらい物(単純な指示で)が生成されるのか?

2025.01.09

Logging

おはようございます.生成AIでポートフォリオサイトを作ってでどれぐらい物(単純な指示で)が生成されるのか?を試してみた結果、ダークモードにも対応出来ていたけどもやっぱ微妙かなと思いました.確かにまずまずの物は作れるようになっているけど、凝ったものを作るのは知識が必要になる.

生成AIでポートフォリオサイトを作ってでどれぐらい物(単純な指示で)が生成されるのか?

ひろゆき氏の切り抜きの動画をたまたま見たけど、ひろゆき氏の生成AIに対しての考え方は今のところ間違っていない感じがします.生成AIは平均的なものが生成されます、そして生成AIで生成されたコードを直せない人は生成AIを使えない.それはソースコードも絵や音楽でも同じでそれなりものは出来るけど、その調整を出来るのはそれを専門にしている人だけです.

そして生成AIが作ったものが正しいものなのかが判断する人がいないと難しい.生成AIの提供会社が100%保証してくれるわけでもなく、生成AIで生成されるものは間違いがあることを認めている現状ではやはり普及はしないし専門家の仕事は奪われないというのがひろゆき氏の見解です.AGI(汎用人工知能)やASI(人工超知能)というのは幻想かもしれない.

シンギュラリティは当分来ない、早くても10年、20年後になるじゃないだろうかと.

ただAIはこれからも徐々に進化していくとは思っています.それに伴って医療などの進展は今まで以上に加速すると思っています.そういう訳でエヌビディアの株も今年が天井なのかもしれません.

最後に今回、生成AIが生成したhtmlファイルを添付致します.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Portfolio</title>
  <!-- Bootstrap CSS -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    body {
      font-family: Arial, sans-serif;
      transition: background-color 0.3s, color 0.3s;
    }
    .hero {
      background: url('https://picsum.photos/1200/600') no-repeat center center/cover;
      height: 60vh;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
    }
    .project img {
      border-radius: 8px;
    }
    footer {
      background: #343a40;
      color: white;
      padding: 1.5rem 0;
      text-align: center;
    }
    .dark-mode {
      background-color: #121212;
      color: #e0e0e0;
    }
    .dark-mode .hero {
      text-shadow: 2px 2px 4px rgba(255, 255, 255, 0.7);
    }
    .dark-mode footer {
      background: #1f1f1f;
    }
  </style>
</head>
<body>
  <header>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <div class="container">
        <a class="navbar-brand" href="#">My Portfolio</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav ms-auto">
            <li class="nav-item"><a class="nav-link" href="#about">About</a></li>
            <li class="nav-item"><a class="nav-link" href="#projects">Projects</a></li>
            <li class="nav-item"><a class="nav-link" href="#contact">Contact</a></li>
            <li class="nav-item">
              <button class="btn btn-outline-light ms-3" id="darkModeToggle">Toggle Dark Mode</button>
            </li>
          </ul>
        </div>
      </div>
    </nav>
  </header>

  <section class="hero text-center">
    <div>
      <h1>Welcome to My Portfolio</h1>
      <p>Showcasing my work and projects</p>
    </div>
  </section>

  <section id="about" class="py-5">
    <div class="container">
      <div class="row">
        <div class="col-md-6">
          <img src="https://picsum.photos/500/400" alt="About Me" class="img-fluid rounded">
        </div>
        <div class="col-md-6">
          <h2>About Me</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce aliquam magna in odio malesuada, vitae vulputate libero sodales. Nulla facilisi.</p>
        </div>
      </div>
    </div>
  </section>

  <section id="projects" class="py-5 bg-light">
    <div class="container">
      <h2 class="text-center mb-4">Projects</h2>
      <div class="row">
        <div class="col-md-4 project mb-4">
          <img src="https://picsum.photos/400/300" alt="Project 1" class="img-fluid">
          <h4 class="mt-2">Project 1</h4>
          <p>Short description of the project goes here.</p>
        </div>
        <div class="col-md-4 project mb-4">
          <img src="https://picsum.photos/400/300" alt="Project 2" class="img-fluid">
          <h4 class="mt-2">Project 2</h4>
          <p>Short description of the project goes here.</p>
        </div>
        <div class="col-md-4 project mb-4">
          <img src="https://picsum.photos/400/300" alt="Project 3" class="img-fluid">
          <h4 class="mt-2">Project 3</h4>
          <p>Short description of the project goes here.</p>
        </div>
      </div>
    </div>
  </section>

  <section id="contact" class="py-5">
    <div class="container">
      <h2 class="text-center mb-4">Contact Me</h2>
      <form>
        <div class="mb-3">
          <label for="name" class="form-label">Name</label>
          <input type="text" class="form-control" id="name" placeholder="Your Name">
        </div>
        <div class="mb-3">
          <label for="email" class="form-label">Email</label>
          <input type="email" class="form-control" id="email" placeholder="Your Email">
        </div>
        <div class="mb-3">
          <label for="message" class="form-label">Message</label>
          <textarea class="form-control" id="message" rows="4" placeholder="Your Message"></textarea>
        </div>
        <button type="submit" class="btn btn-primary">Send Message</button>
      </form>
    </div>
  </section>

  <footer>
    <p>© 2025 My Portfolio. All Rights Reserved.</p>
  </footer>

  <!-- Bootstrap Bundle with Popper -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
  <script>
    const darkModeToggle = document.getElementById('darkModeToggle');
    darkModeToggle.addEventListener('click', () => {
      document.body.classList.toggle('dark-mode');
    });
  </script>
</body>
</html>

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

エヌビディア, シンギュラリティ, ソースコード, それなりもの, ダークモード, ひろゆき氏, ポートフォリオサイト, 人工超知能, 天井, 幻想, 指示, 普及, 最後, , 汎用人工知能, 現状, 生成, 見解, 進展, 難しい生成,

blueskyAPIが処理されなくなったので、対応を行った話.

2025.01.06

Logging

おはようございます.今日から仕事始めの方も多いはず自分もそんな感じです.さてblueskyAPIが処理されなくなったので対応を行った話を書いていきます.ブルースカイの独自処理が上手く処理されなくなったのでその対応を行っていました.今まで公式に落ちているPHP言語のライブラリーを使用していたんだけど、レンタルサーバーの環境が変わった関係により処理がされなくなったので、自前のAPI処理を他のエンジニアが公開されているコードを参考にしてカード板自動投稿を作りました.

ソースコードは下記になります.

    public function cardPost($text, $imagePath = null, $link = null)
    {
        $imageUri = $imagePath ? $this->uploadImage($imagePath) : null;

        $record = [
            "\$type" => "app.bsky.feed.post",
            "text" => $text,
            "createdAt" => Carbon::now()->format('c'),
        ];

        if ($imageUri && $link) {
            $record['embed'] = [
                "\$type" => "app.bsky.embed.external",
                "external" => [
                    "uri" => $link,
                    "title" => $text,
                    "description" => $text,
                    "thumb" => $imageUri
                ]
            ];
        }

        $ch = curl_init("https://bsky.social/xrpc/com.atproto.repo.createRecord");
        curl_setopt_array($ch, [
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                "Content-Type: application/json",
                "Authorization: Bearer {$this->jwt}",
            ],
            CURLOPT_POSTFIELDS => json_encode([
                "repo" => $this->handle,
                "collection" => "app.bsky.feed.post",
                "record" => $record,
            ]),
        ]);

        $response = curl_exec($ch);
        curl_close($ch);

        return json_decode($response, true);
    }

これでカード型のポストが出来ます.参考にしたサイトはこちらの@ma7ma7pipipiさんのソースコードになります.そのコードにカード型のコードを追加した形になります.

https://qiita.com/ma7ma7pipipi/items/bf7fda65ee71c873c70a

一からコードを書かないで良かったのでとても助かりました.感謝ですね😌、ありがとうございます.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

```, エンジニア, カード型, カード板自動投稿, コード, ソースコード, ライブラリー, レンタルサーバー, 下記, 仕事始め, 公式, 処理, 参考, 多いはず自分, , 感謝, 環境, 自前, 言語,

ブログ通知を付けました.4時間置きに通知が飛びます.#サービスワーカー

2025.01.05

Logging

おはようございます.去年の暮にブログ通知を付けました.4時間置きに通知が飛びます.ソースコードは以前に書いたコードをベースとして再構築した形になります.平たく言うとLaravelを使用しないでWEB通知を行うものになります.一度作ってしまえば使いましが出来るようにコードを今回は書いたので使いまわそうと考えています.

以前、Laravelで作っていたので考え方は苦労せずに出来たのですが…

今まで知らないことが出てきてしまってそこでロスしてしまいました.知らなかったこととはjavascriptのfetchです.使用する機会は結構多めなんだけど知らないことがありました.それはurlのパラムに/exampleと書くか/example/index.phpと書くかでphp言語のグローバル変数$_SERVER[‘REQUEST_METHOD’]の値がPOSTで送っているのにも関わらずGETになるのです.

fetchを書く場合は/example/index.phpと書くことでPOST送信と判断されます.これをデバックもせずに悩んでいました(笑).デバック大事.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

グローバル変数, コード, ソースコード, デバッグ, デバック大事, パラム, ブログ通知, ベース, 一度, , 去年, , 時間置き, , 機会, , 考え方, 言語, 送信, 通知,

LaravelのViteが使用できない環境でログイン画面などを表示させたい対処法.

2025.01.02

Logging

おはようございます.さて正月、2日目の記事はLaravelのViteが使用できない環境でログイン画面などを表示させたい対処法です.レンタルサーバーではnpmコマンドが使えないのでローカルでビルドしてサーバーにビルド後のファイルをUPしている方が殆どだと思いますが、npmをビルドするのも面倒、ビルドが出来ない方はソースコードを読んで何のコードが使われているかを判断して使用されているライブラリーのcdnを貼り付けるだけで大体の解決します.

LaravelのViteが使用できない環境でログイン画面などを表示させたい対処法.

尚、viteで参照しているところは削除してください(viteと差し替える形になります.).

viteでエラーが出る話はこれで終わりです.ここから余談です今年から無料になったGitHub Copilotを個人開発では使用するようにしました、この事によって今までより開発効率が上がるということならば有料プランも検討したいなと思っています.今のところ、無料プランで使っていくというスタンスです.

因みに自分は正月そうそうからコードを書いています.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

エラー, コード, コマンド, サーバー, さて正月, スタンス, ソースコード, ビルド, ビルド後, ファイル, ライブラリー, レンタルサーバー, ログイン画面, 余談, 対処法, , 有料プラン, 正月そうそう, 殆ど, 開発効率,

ハッキングかもしくは不具合か分からないので.オーバーフローかな?

2024.12.24

Logging

おはようございます.ハッキングかもしくは不具合か分からないので問い合わせを行いました.これを書いているのは、問い合わせを行った当日なので、今のところ、自分のプログラムコードの不具合なのか、それともハッキングなのか分からない.

ソースコードは単純なソースコードなので当初はオーバーフローと考えたけど、32ビット際のオーバーフローの桁に加算した値を入れたがオーバーフローはしなかったんです.だとすると何らかのサーバー異常でデータを取得できなかったというそれぐらいの事しか思い当たらない.

念の為にサポートセンターに投げた.あり得ないかもしれないけどハッキングという可能性もあるので、問い合わせした感じになります.

昔、VPSサーバーで運営していた時に何度か変なログインの痕跡があったのでもしかしたらハッキングしたファイルを引き継いでいる可能性もという懸念があり.

こういう時に知識の無さを痛感しますね.

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

32ビット際, オーバーフロー, サーバー, サーバー異常, サポートセンター, ソースコード, データ, ハッキング, ファイル, プログラムコード, ログイン, , 当初, 感じ, 懸念, , , 無さ, 痕跡, 知識,

Push通知ってブラウザ閉じても通知出来る様に出来るのか?

2024.11.04

Logging

おはようございます.Push通知ってブラウザ閉じても通知出来る様に出来るのか?答えは出来るのですが無料でその機能を実装できるのか.こたえはYesに近い?.有料のサービス機能push7を使用すればもっと簡単に可能です.

サービスワーカーとかいう機能を使えば良いみたいですね.知らないは一時の恥ですね.サービスワーカーとGCPやララベルの拡張Webpushなどを使えば出来そうですがまだ試していません.

因みにPusherサービスを使用して実装しました.当分、無料枠で対応可能な感じですね💁.

下記はリアルタイムPush通知の動作とソースコードの一部になります.

<?php
namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\Channel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class NotificationEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $title;
    public $message;
    public $userId;

    public function __construct($title, $message,$userId='')
    {
        $this->title = $title;
        $this->message = $message;
        $this->userId = $userId;
    }

    public function broadcastOn()
    {
        return new Channel('notifications.' . $this->userId);
    }

    public function broadcastAs()
    {
        return 'notification-event';
    }
}

明日へ続く

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

```, サービス, サービスワーカー, サービス機能, ソースコード, ブラウザ, ララベル, リアルタイム通知, 一部, 下記, 動作, , 拡張, 有料, 機能, 無料, 無料枠, 答え, 通知,

指定日に記事を削除するWPのプラグインの雛形.

2024.10.24

Logging

おはようございます.指定日に記事を削除するWPのプラグインの雛形を作りましたが記事の削除部分(article_del_R)はご自身で作ってください.削除部分をご自身で作り自分のサイト(WP)を定期的にcronで叩けば削除される仕組みです.
毎度のことですみませんがソースコードを解析してお使いいただければと思います.また、このコードは試作品になります.

WPプラグインの画面はこんな感じです.

ソースコードはQiitaで公開しています.

因みにワードプレスで非同期処理を行うのは少し面倒です、たまに間違った情報を掲載しているサイトがあるので注意が必要です.下記で非同期処理を設定しまうとログアウトした状態でも叩けるらしいので気おつけてください!.

“wp_ajax_nopriv_{$action}”

明日へ続く.

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

Action, article_del_R, cron, qiita, wp, wp_ajax_nopriv, WPプラグイン, コード, ソースコード, プラグイン, ワードプレス, 下記, 削除部分, 毎度, 注意, 状態, 画面, 試作品, 雛形, 非同期処理,

Lightbox2をカスタマイズしてみました.右クリック禁止.

2024.08.12

Logging

おはようございます.先日、Lightbox2をカスタマイズしてみました.Lightbox2は画像をポップアップ表示できるJavaScriptのライブラリ機能です.そのソースコードをカスタマイズし右クリック禁止の機能を追加しました.

ソースコードの編集箇所はlightbox.jsファイルの307行目の下に下記のコードを追加することで、対応可能です.

      $image.on('contextmenu', function(event) {
        event.preventDefault();
      });

なお、lightbox.jsはJqueryが動作している環境で動作するライブラリです、Jqueryが入っていない場合はlightbox.jsが入っていたフォルダに有るlightbox-plus-jquery.jsかlightbox-plus-jquery.min.jsを読み込ましてください.lightbox-plus-jquery.jsかlightbox-plus-jquery.min.jsを読み込ました場合は変更箇所が違いますので注意が必要です.

ちなみにソースコードを覗いて見ると案外自分でも作れそうな構造でした、昔に比べて自分も少しは技術が上がったのかもと思った瞬間でした.

先人のオープンソースコードを見ると本当にためになります.

明日へ続く.

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

$image.on, contextmenu&#39, EVENT, event.preventDefault, function, jquery, Lightbox, lightbox-plus-jquery.jsかlightbox-plus-jquery.min.js, lightbox.js, lightbox.jsファイル, LightBox2, オープンソースコード, ソースコード, フォルダ, ポップアップ, ライブラリ機能, 先人, 構造, 瞬間, 編集箇所,

LineメッセージAPIの雛形を作りました.おすそ分け #php

2024.07.28

Logging

おはようございます.LineメッセージAPIの雛形を作りました.おすそ分けです、メッセージAPIのプッシュのみに対応しており、アクセストークンなどや送信先のuserIdは事前に発行してください.
対応したメッセージは下記になります.

  • テキストメッセージ
  • スタンプメッセージ
  • 画像メッセージ
  • 動画メッセージ
  • 音声メッセージ
  • 位置情報メッセージ
  • イメージマップメッセージ
  • テンプレートメッセージ
  • Flex Message

所感

イメージマップメッセージは自分が使用するつもりがないので作っていないです.テキストメッセージで送るのも良いですが、やはりテンプレートが良い感じがしました.

参考したサイト

https://developers.line.biz/ja/reference/messaging-api

Github

https://github.com/taoka3/linePostMessage

尚、どういう様なパラメーターを投げれば良いのかなどもソースコードのコメントアウトしている所に記載しているのでコメントアウトを解除して試してみてください.画像URLはダミーですので変更が必要になります.

明日へ続く.

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

Flex Message, github, LineメッセージAPI, userid, アクセストークン, イメージマップメッセージ, コメントアウト, スタンプメッセージ, ソースコード, ダミー, テキストメッセージ, テンプレート, テンプレートメッセージ, パラメーター, プッシュ, メッセージAPI, 事前, 所感, 雛形, 音声メッセージ,

【#Chrome拡張機能開発】先日の休みにお名前.comのIP自動入力

2024.07.17

Logging

おはようございます.先日の休みにお名前.comのDNS設定のAレコードのIPアドレス入力欄がいちいち入力するのが、面倒くさいと感じたのでIPアドレスをコピーしたものをAレコードの最初の入力箇所にペーストするとIPアドレスを分離して自動入力してくれるChrome拡張機能を作りました.

Chrome拡張機能-お名前.com-動作方法

単なる面倒くさいと自分が感じたものだけで、人が使用することはあまり考えて作った訳ではないです.

Chrome拡張機能のソースコードも結構単純なものであり開発と言えるかどうか不明です.

同じ様に面倒くさいと感じた方はご使用いただけたらと思っています😌.拡張機能はこちら.

https://chromewebstore.google.com/detail/iponamep/mkgffpkffmpfmcpdnmealfpgabaeoghd

明日へ続く.

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

Aレコード, Chrome拡張機能, DNS設定, IPアドレス, IPアドレス入力欄, お名前.com, ご使用, ソースコード, , 休み, 入力箇所, 拡張機能, 最初, 自分, , 開発,

php8.1からのEnums.

2024.05.09

Logging

おはようございます、php8.1から導入された?Enums(列挙型)について@ucan-labさんが解説しているのでそちらを参考に試しにプログラムを組んでみました.自分の場合、あまり使わない気がするのだけども使えるようになったというのは有り難いですね.

ふと昔思い出したのですが職場で列挙型の話がでた事があります.あれから数年が経過した現場はどんな感じになっているのだろうか?自分がいた頃にはもうスパゲッティ化していたソースコードはどこまで改良したのだろうかとか、もう独自のシステムは使わなくなっているのだろうかとか、今となっては知る由もないですが.昔、勤めていた職場はオンプレミスではないのでPHPのバージョンアップがあれば対応しないといけなくなることもありました.そういう面ではXサーバーはユーザーファーストであるなって思います.結構まえのPHPバージョンも使用できたりするわけですからね.

PHPのバージョンが上がれば新しい機能を使ってみたいエンジニアの気持ちは分かりますが、この頃、導入するタイミングって難しいなって思います.そしてアプリはもっと大変だなって思います、、、.

明日へ続く.

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

Enums, php, PHPバージョン, ucan-labさん, Xサーバー, エンジニア, オンプレミス, スパゲッティ化, ソースコード, タイミング, バージョン, プログラム, まえ, ユーザーファースト, 列挙型, , 現場, , 職場, ,

Photo by FOX on Pexels.com

干支計算2024

2024.04.05

Logging

おはようございます、干支計算2024を作りました.ソースコードは下記になります.

干支計算2024 #js #javascript #初級
// 干支の計算方法は?
// 十二支は、西暦を12で割り、同様に余りを求めます。 
let eto = ['申', '酉', '戌', '亥', '子', '丑', '寅', '卯', '辰', '巳', '午', '未'];
document.querySelector('.input').addEventListener('input', function () {
    let index = isNaN(Number(document.querySelector('.input').value)) ? -1 : (Number(document.querySelector('.input').value) % 12);
    document.querySelector('#res').innerText = index === -1 ? '' : eto[index];
});

過去に同じことをしていたのを見つけて、今ならどう書くのだろうかと書いてみた感じです.

求める方法は変わっていますが、コードをみると今の方が短くかけていると思います.昔、コードを書き出した頃から比べると全く違うようになってきた気がしますね.最初から短くかける人でなくても続けていれば短くかけるようになってきますので、滅気ずに頑張ってコードを書いてみてください.

明日へ続く.

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

addEventListener, document.querySelector, eto, function, index, innerText, isNaN, let, let eto, Number, querySelector, res&#39, value, ソースコード, 十二支, , 干支, 干支計算2024, 滅気, 西暦,