سایت The Coding Love رو قبلا معرفیش کردم، یک سایت جمع و جور که گیفهای گیکی میذاره که هرکسی از اون گیفها سردر نمیاره. من هم به این سایت علاقه زیادی دارم و هر روز چکش میکنم ولی مسالهای که وجود داشت این بود که گاهی این سایت توی یک ساعت چندتا گیف جدید میذاشت و گاهی هم چند روز خبری نبود که یکم این مورد من رو اذیت میکرد. دیدم الآن که چند وقتیه بازار کانالهای تلگرامی گرم شده بد نیست که بگردم و ببینم برای این سایت کانال تلگرامی وجود داره یا نه. کمی گشتم و یک کانال تلگرام تونستم براش پیدا کنم ولی این کانالی که پیدا کردم و آدرس دقیقش هم یادم نیست یک مشکل داشت و اون هم این بود که فقط لینک گیفهای جدید رو میذاشت و باز هم نیاز بود چندتا کلیک انجام بدم و از داخل مرورگر گیف ها رو بینم که اصلا برام جالب نبود. به همین خاطر تصمیم گرفتم یک کانال درست کنم که مطالب داخلش توسط یک بات به صورت خودکار گذاشته میشه و گیفها هم مستقیما داخل کانال گذاشته شده باشن و راحت ببینمشون. خب بریم ببینیم چه کارها کردم!!!
احتمالا اگه شما جای من بودین تصمیم میگرفتین از آخرین گیفی که تو سایت the coding love (از این به بعد خلاصش میکنم به tcl) گذاشته شده شروع کنین و فقط گیفهای جدید رو اضافه کنین ولی من نمیخواستم این کار رو بکنم 🙂 تصمیم گرفتم اول از همه هرچی گیف تو سایت tcl هست رو بذارم رو کانال و بعد از اون هم گیف های جدید رو بذارم. خب از اون جایی که یک بات قراره تو کانال پست بذاره پس اول نیاز به یک بات داریم، بات ساختن هم که کاری ندارهِ، فقط کافیه چندتا پیام به @BotFather بدیم تا باتمون ساخته بشه. چون بات قراره پشت صحنه فقط تو کانالمون پست بذاره پس اسم و توضیحات و بقیه مواردش مهم نیستن، فقط لازمه که یک بات داشته باشیم و توکنش برای این که مدیریتش کنیم. مرحله بعدی هم که مشخصه، ساخت کانالمون، کانالمون رو میسازیم و باتمون رو هم به عنوان مدیر بهش اضافه میکنیم. برای اضافه کردن بات به عنوان مدیر هم میریم تو بخش اضافه کردن ادمین جدید به کانالمون و از بخش جستجو اسم باتمون رو سرچ میکنیم و تمام! حالا کار اصلیمون شروع میشه، نوشته برنامهای که توسط باتمون پستهای tcl رو بذاره تو کانال! و تا یادم نرفته این نکته رو هم اضافه کنم که وقتی میخوایم با یک بات تو کانال پست بذاریم، chat_it میشه @bot_name.
همونطور که اول کار گفتم اول از همه میخوام تمام پستهای tcl رو بذارم رو کانالی که ساختم و بعد برم سراغ پستهای جدید. نکته جالبی که متوجه شدم این وسط این بود که تعداد صفحه های سایت tcl روی ۷۷۵ ثابت مونده و صفحه آخر هم یک گیف ثابت داره که تغییر نمیکنه. بگذریم… اولین کاری که میکنم این هست که سورس هر ۷۷۵تا صفحه رو میگیرم و تو یه سری فایل که اسمشون از ۱ تا ۷۷۵ هست میریزم تا سورسها برای ادامه کار دم دستم باشن و به علاوه هر ۷۷۵تا صفحه سورسشون رو به صورت همزمان میگیرم تا مطمئن بشم که اگه پست جدیدی در حین گرفتن سورسها رو tcl رفت تو سورسهایی که من گرفتم مشکلی ایجاد نمیشه و باعث نمیشه مثلا یک گیف چندبار تو سورسها باشن. خب کدش میشه این (اگه واستون سواله این کدها چین، بش اسکریپت هستن):
for i in {1..775} do curl "http://thecodinglove.com/page/$i" > $i & done wait
حالا که سورسها رو دارم لازمه از آخر به اول تو سورسها بگردم و لینک پستها رو از تو سورس صفحه پیدا کنه. با یکم سر و کله زدن با ریجکس و اینجور چیزا تو سورسها میگردم تا لینک پستها رو پیدا کنم و بعد لینکهای پستها که ۴تا تو هر صفحه هست رو میدم به دستور tac تا تریتبشون برعکس بشه و آخرین لینک بیاد بشه اولین لینک تا ترتیب آخر به اول پستها حفظ و بشه و در نهایت هم لینکهای پستها رو داخل فایل links.txt بذاره و کدش این شد:
for i in {775..1} do egrep 'class="bodytype"' $i | grep -P -o "a href.+?>" | sed -r 's/^.{8}//' | sed -r 's/.{2}$//' | tac >> links.txt done
این نکته رو هم اضافه کنم که من دارم تمام این کدها رو روی یک سرور اجرا میکنم که فکر کنم بدیهی باشه چون واقعا اینترنت شاهکارمون پایداری درستی نداره بشه با خیال راحت روش این کدها رو اجرا کرد 😐 حالا ببینیم چندتا لینک داریم
اگه یه حساب سر انگشتی کنیم میبینیم که تعداد لینکها باید ۳۰۹۷ باشه یعنی ۳تا بیشتر از این تعداد لینکی که الآن داریم، من هنوز دلیل اون ۳تا اختلاف رو کشف نکردم! شما پیدا کردین حتما زیر همین پست یه کامنت بذارین دلیلش رو بگین 😀 محتوای فایل links.txt لینک مربوط به پستها هست که به این شکلن:
http://thecodinglove.com/post/145704378592/when-i-find-an-unexpected-workaround
بریم ببینیم چجوری میشه توضیحات هر پست و لینک گیف هر پست رو در آورد! به صورت تصادفی فهمیدم اگه آخر لینک هر پست عبارت /xml رو اضافه کنم میتونم محتویات اون صفحه رو با فرمت xml ببینم. آخ جون! با xml خیلی راحتتر میتونم اطلاعات لازم رو از صفحه بکشم بیرون تا اینکه بخوام تو html بگردم. خوشبختانه برای کار با xml ابزاری داریم به اسم xml_grep که از اسمش مشخصه برای چه کاریه و تو پکیج (برای اوبونتو) xml-twig-tools هست و در ادامه هم چون درخواستهام رو با متد get میخوام به تلگرام بفرستم نیاز به برنامه urlencode هم دارم تا لینک گیف و توضیحاتش رو انکود کنم و خیالم راحت باشه برای ارسالشون مشکلی نخواهم داشت. برنامه urlencode هم تو پکیج gridsite-clients هست که نصبش میکنم. موندم چرا درست یه پکیج به اسم urlencode نداریم و این برنامه باید توسط یه پکیج دیگه با یه اسم عجیب نصب بشه. بریم سراغ خود کد، از داخل xml صفحه لینک فایل گیف و توضیحات رو در میارم، انکود میکنمشون و لینک درخواستی که باید اجرا بشه تا گیف رو کانال توسط بات گذاشته بشه رو به اضافه curl در اولش تو فایل dopost.sh میذارم تا بعد فایل dopost.sh رو مثل یک اسکریپت اجرا کنم و همه گیفها پشت سر هم تو کانال قرار بگیرن. درباره %0A@tclunofficial هم که آخر توضیحات گیف گذاشتم بگم که %0A حکم اینتر رو داره و هرچیزی که ادامش بیاد تو خط بعدی توضیحات نوشته میشه و @tclunofficial هم آدرس کانال هست که در ادامه توضیحات هر گیف میاد.
while read -r LINK do SOURCE="$(curl $LINK/xml)" TITLE="$(echo $SOURCE | xml_grep regular-title --text_only)" ENCODED_TITLE="$(urlencode $TITLE)" IMGLINK="$(echo $SOURCE | xml_grep regular-body --text_only | grep -P -o "(http:\/\/|https:\/\/).+?\/.+?\"" | sed -r 's/.{1}$//')" ENCODED_IMGLINK="$(urlencode $IMGLINK)" echo "curl \"https://api.telegram.org/botTOKEN/sendDocument?chat_id=@tclunofficial&document=$ENCODED_IMGLINK&caption=$ENCODED_TITLE%0A@tclunofficial\"" >> dopost.sh done < links.txt
حالا کافیه فایل dopost.sh رو اجرا کنیم تا گیفها برن رو کانال. من از برنامه sceen هم استفاده کردم که اگه اتصالم به سرور قطع شد باز هم اسکریپت در حال اجرا بمونه و گیف برن رو کانال و خب دستور نهایی برای اجرای اسکریپت این شد:
screen bash dopost.sh
بعد از کمی صبر (برای من ۳ساعت) میبینیم که کانالمون پر از گیف هست! گیفها رو نشمردم و نمیدونم همشون رو کانال رفتن یا نه، امیدوارم که همشون رفته باشن.
حالا تازه میرسیم به قسمت اصلی کار! نوشتن یک اسکریپت که پستهای جدید رو تشخیص بده و پستهای جدید tcl رو بذاره رو کانال! لازمه که اول از همه اسکریپتی که میخوایم بنویسیم بدونه لینک آخرین پستی که رو کانال هست چیه، یک نگاه به کانال میندازم تا ببینم آخرین گیف چیه و اون گیف رو روی tcl هم پیدا میکنم که البته مشخصه تو صفحه اول یا دوم tcl هست. لینک پست مربوط بهش رو برمیدارم و قسمتای اضافه ته لینک که توضیحات گیف هست رو برمیدارم تا به لینکی مثل این برسم
http://thecodinglove.com/post/145704378592
این لینک رو تو فایل
~/.tcllastpostlink
میذارم تا همیشه لینک آخرین پست رو توی این فایل داشته باشم. بریم سراغ کد! من از rss سایت tcl که به فرمت xml هم هست استفاده میکنم برای این که ببینم پست جدید اومده یا نه. اول از همه از داخل rss با کمک xml_grep فقط لینک پستها رو میکشم بیرون، ترتیب لینکها رو برعکس میکنم و لینکها رو دونه دونه چک میکنم تا ببینم کدوم مثل لینک داخل فایل ~/.tcllastpostlink هست، از اون اون لینک به بعد میشن لینکهایی که مربوط به پستهای جدید هستن و باید برن رو کانال.
POST=0 LASTPOSTLINK=$(cat ~/.tcllastpostlink) for LINK in $(curl http://thecodinglove.com/rss | xml_grep item | xml_grep link --text_only | tac) do if [ "$POST" = "0" ] then if [ "$LASTPOSTLINK" = "$LINK" ] then POST=1 fi else SOURCE="$(curl $LINK/xml)" TITLE="$(echo $SOURCE | xml_grep regular-title --text_only)" ENCODED_TITLE="$(urlencode $TITLE)" IMGLINK="$(echo $SOURCE | xml_grep regular-body --text_only | grep -P -o "(http:\/\/|https:\/\/).+?\/.+?\"" | sed -r 's/.{1}$//')" ENCODED_IMGLINK="$(urlencode $IMGLINK)" curl "https://api.telegram.org/botTOKEN/sendDocument?chat_id=@tclunofficial&document=$ENCODED_IMGLINK&caption=$ENCODED_TITLE%0A@tclunofficial" echo "$LINK" > ~/.tcllastpostlink fi done
لازم هم هست که این اسکریپت رو هر چند دقیقه یکبار اجرا کنیم تا اگه گیف جدیدی رو tcl رفته بود رو کانالمون بذاره. من فرض میکنم که این اسکریپت رو تو فایل به اسم poster.shذخیره کردین. بدیهیه که اول باید به اسکریپت قابلیت اجرایی بدیم و با دستور
chmod +x poster.sh
بهش قابلیت اجرایی میدیم. برای اینکه هر ۱۰ دقیقه هم این اسکریپت اجرا بشه میذارمش رو کرون تب. با دستور
crontab -e
کرون تب رو باز میکنم و این خط رو آخر کرون تب اضافه میکنم:
*/10 * * * * /path/to/poster.sh > /dev/null 2>&1
حالا با خیال راحت پا رو پا میندازم و این اسکریپت وظیفه گذاشتن پستهای جدید رو کانالی که زدم و یوزرش هم @tclunofficial هست رو انجام میده 🙂 دوتا نکته رو هم به عنوان اختتامیه کار بگم و تمام:
۱- به خاطر محدودیتی که تلگرام در حال حاضر برای باتها داره اگه حجم گیفی بیشتر از ۲۰مگ باشه ارسال نمیشه که البته احتمالش خیلی کم هست و تا الآن فقط یک گیف دیدم که حجمش بالای ۲۰مگ بوده و رو کانال نرفته. البته میشه کد رو جوری درست کرد که وقتی حجم گیف بالای ۲۰ مگ باشه لینک پست مربوط به اون گیف رو بفرسته رو کانال ولی خب تا الآن فقط یک گیف دیدم که اینجوری باشه و برای اون یکی نمیصرفه فعلا بشینم کد بزنم :)))
۲- سایت tcl انگشت شمار دیده شده که بجای گیف یک عکس معمولی میذاره که کد فعلی باعث میشه اون عکس به عنوان فایل رو کانال آپلود بشه که مجددا اون رو هم میشه درست کرد ولی برای چندتا عکس در بین چند هزارتا گیف باز هم نمیصرفه کد رو تغییر بدم :)))