UZB25 qanday qilib yaratilgan edi? Yohud deadline paytida uxlamaslik kerak!!!

UZB25 qanday qilib yaratilgan edi? Yohud deadline paytida uxlamaslik kerak!!!

Hammaga salom! UZB25.TEXNOMAN.UZ - loyihasini qanday yaratilishi jaroyonini aytib bermoqchi edim, ya'ni qanaqa texnologiyalar ishlatildi, qanday vaqt sarflandi va qanday maqsadda yaratilgan edi. Loyiha open source bo'lib uni GitHubda ko'rishingiz mumkin: https://github.com/WebStyle/uzb25

Loyihadan maqsad O'zbekistonning 25-yilliga kichik bo'lsa ham sovg'a yaratish edi va eng asosiysi, o'zim uchun kichik deadline asosida hakaton uyushtirish edi.

Avvaliga 18 avgust kuni, Expressjs yordamida, faqatgina faylni serverga upload qilib, sodda rasmni qayta ishlash imkoniyati bilan loyihani GitHubga commit qilgandim. Rasmni qayta ishlash uchun Linuxdagi grafika bilan ishlashni imkoniyatini beruvchi GraphicsMagick ishlatilgan edi. Ya'ni Node.jsda yozilgan paket: gm bajarar edi. Boshqacha qilib aytganda, gm orqali GraphicsMagickni ishlatish mumkin bo'ladi.

Misol uchun, gm orqali serverga upload qilingan rasmning o'rtasiga logo joylashtiramiz:

var watermark = 'logo.png';
var uploadedImage = 'image.jpg';
gm()
    .command('composite')
    .in("-gravity", "center")
    .in(watermark)
    .in("-gravity", "center")
    .in(uploadedImage)
    .write("./uploads/result.jpg", function(e) {
        if (err) // Error handling qilamiz
        // Rasm saqlandi
    });

Shunday usulda, serverga upload(yuklangan) rasmning ustiga logotip joylashtirish imkoniyati bor edi. Lekin GraphicsMagick orqali rasmlar juda ham sekin qayta ishlanar edi, shu sababli boshqa yo'l topish kerak edi.

Bir necha kunlar o'tib ketti, 23 avgust kuni GraphicsMagick o'rniga libvips ishlatishga qarar qildim, chunki libvips juda ham tez rasmlarni qayta ishlay olar edi. libvipsni ishlatish uchun esa sharp paketi ishlatildi. sharpda yozilgan metodlar orqali libvipsni ishga tushurish imkoniyati bor edi.


26 avgust ham keldi. Deadline yaqinlashmoqda lekin loyihada deyarli hech nima qilinmagan edi. Shu kunlarda bitirib qolarman degan hayolda davom ettirdim. Facebook orqali kirish imkoniyatini qo'shish kerak edi. Buning uchun Passportjs ishlatdim.

Passportjsda eng qulayi shundaki, siz passportjsga o'zingizning avtorizatsiya tizimingizni yozishingiz mumkin bo'ladi. Siz unga ijtimoiy tarmoqlar orqali kirish imkoniyatini qo'shishingiz mumkin bo'ladi. Facebook orqali kirish uchun passport-facebook paketini ishlatgandim, ya'ni passportjs orqali Facebook oAuth2ga, client id va client_secrect jo'natiladi, brauzer facebookning avtorizatsiya qismiga yuboriladi. Foydalanuvchi Facebookdan avtorizatsiyadan o'tgandan so'ng, oldindan Facebook App sozalamarida ko'rsatilgan Callback urlga jo'natiladi, uyerdan menga Facebookdan foydalanuvchi haqida ma'lumotlar qaytadi. Masalan, foydalanuvchining ismi, email va albatta accessToken. Avval accessToken mening MongoDbda joylashgan ma'lumotlar omboridan tekshiriladi agar bor bo'lsa, kirish uchun ruxsat beradi, agar bunday accessToken bo'lmasa yangi foydalanuvchini ro'yxatga olib, ya'ni ma'lumotlar omboriga yozib ,saytga kirish uchun imkon beradi. Shunday tizim orqali Facebook orqali kirish va libvips orqali foydalanuvchi yuklagan rasmga logo joylashtirish imkoniyati bor edi.


Lekin baribir foydalanuvchi uchun loyiha tayyor emas edi.

31 avgust ham keldi, bu ish kuni edi. Ish vaqtida hech ham bo'sh vaqt topa olmas edim. Ish tugagandan keyin ham vaqt yo'q edi, Bowlingga borish kerak edi :) Bowlingga borib kelgandan keyin esa vaqt bo'lishi mumkin. Soat 22:00 edi, loyiha hali ham bitmagan edi, sodda fayl upload, faylni sodda qayta ishlash va hech qanday interface yo'q edi. Shu paytda o'zimga o'zim hakaton qilishga qaror qildim. 1 sentabr kuniga loyihani tugatishim kerak edi, hech bo'lmaganda 100 ta kishi kirsa ham katta yutuq.


23:00 loyihani to'g'ri ishlaydigan qilish kerak edi, ya'ni muammo nimada edi. Rasm upload qilgan uni sharp orqali qayta ishlash routerning handlerida yozilar edi, uni alohida paketga chiqarish kerak edi. Zo'r, bemalol boshqa bir faylga yozib, uni handler yordamida chaqirish mumkin bo'lgan metod yozildi. Lekin muammo shundaki, sharpga jo'natilgan rasm manzillarini uncha yaxshi o'qiy olmadi, bir-necha variantlar sinab ko'rildi, bo'lmadi. Qani hammasini orqasiga ishlab turgan joyiga qaytaramiz.

Soat 1:00 atrofida - rasmni o'z nomi bilan emas, balki qandaydir nom bilan saqlab qo'yish kerak edi. Masalan UUID bilan. Foydalanuvchi rasm upload qiladi, rasm nomini yangi generatsiya qilingan UUID bilan o'zgartiradi va uni uploads papkasiga saqlaydi. Keyin esa shu UUID orqali uploads papkasidan rasmni qidirib topib, uni sharp orqali qayta ishlash boshlanadi. Qayta ishlab bo'linganidan so'ng esa yana o'sha UUID bilan results papkaga rasmni saqlab qo'yadi. Foydalanuvchiga esa o'sha saqlagan faylni ko'chirib olish uchun berib yuboriladi.

Shu yerda ham, ko'nglim to'lmagani uchun rasmlarni sharp orqali qayta ishlash paytida ularni ma'lumotlar omboriga yozish kerak bo'lib qoldi. Unga bitta model yozildi, modelga attributlar yozildi va tayyor.

Qayta ishlab bo'linganidan keyin esa ma'lumotlar omborida saqlab, keyin foydalanuvchiga ko'chirish uchun berib yuborilardi.

Soat 3:00 atofida - Demak bizda foydalnuvchi ro'yxatdan o'ta oladi, rasm upload qila oladi va uni ko'chirishga yuboriladi. Lekin bu ham hali homroq tuyildi. Rasm uchun modelga foydalanuvchi id raqami attributi qo'shildi, endi foydalnuvchi o'zi rasmlarini ko'ra oladi. Endi bitta sahifa qilish kerak, bu sahifada tayyor yuklangan rasmni ko'rish va yuklab olish imkoniyati bo'lishi kerak edi. Bitta route yaratildi, /view/:uuid, bu routeda urldan UUIDni olib, shu UUIDga tegishli rasm ma'lumotlarini MongoDbdan olib berishi kerak edi. Natijani esa HTML ko'rinishida render qilish kerak. Node.js HTMLda ma'lumotlarni uzatish, umuman olganda render qilish uchun HTML template engine ishlatish kerak edi. Mening tanlovim EJS bo'ldi. Endi yangi yaratgan sahifaning qiladigan ishi quyidagicha bo'ldi. URLdan UUID olinadi, ma'lumotlar omboridan shu UUIDga tegishli rasm ma'lumotlari qidiriladi, qidiriladi, natijasa esa EJSga jo'natiladi va EJS sahifa HTMLdaga render qilinadi.

4:00 Loyihada umuman interface degan narsa yo'q edi, hullas Bootstrap ishlatishga qaror qildim. Template engine sifatida esa EJS edi. Bosh sahifa(index), Foydalanuvchining sahifasi(profile), Natijani ko'rish sahifasi(view) sahifalari sodda ko'rinishda yozib chiqildi, tayyor namunalar ko'rildi, qisqasi vaqt qanday o'tgani bilinmadi ham, orada o'zimga yoqmaydigan kodlar ozgina o'zgartirib chiqdim. Share qilish imkoniyatiga vaqt kelgan edi, Facebook standart vidjetlaridan foydalanib ko'rdim, boshqa tayyor namunalarni ishlatib ko'rdim, lekin hech ham rasmni share qilish imkoniyatini topa olmadim, DEADLINE ham yaqinlashayotgan edi. Share qilish imkoniyatini qo'shmaslikga qaror qildim :(

5:00 atrofida - loyiha sal bo'lsa ham epaqaga kelib qolgan edi, lekin landing page qilish kerak. Tayyor landing pagelarni qidirib, o'zimga yoqganini topdim va matnlarni yozib chiqdim. Endi esa landing pagega qiziqroq bir narsa kerak. Mover.uzdan Toshkent haqida videoni ko'chirib oldim va Adobe Premiere Pro CC? dasturi orqali videoni kerakli ko'rinishda kesib olib unga blur effektini berdim. Landing page uchun background video tayyor bo'ldi. Uni har doim qaytarilib turadigan ko'rinishda landing pagega qo'yildi.

6:00 atrofida loyiha mening fikrimcha deyarli tayyor degan fikrga kelgan edim. Loyiha Amazon Web Serverga joyladim, lekin bir narsa umuman esdan chiqgan ekan, AWSga domen ulanmagan edi :( Domeni bog'lash esa ko'p vaqt ketishi mumkin edi. Texnoman.uz domenidan poddomen olindi, uzb25.texnoman.uz va iframe orqali amazondagi server ip saytni ko'rsatib beradigan qilgandim. Lekin bu ham xato yo'l bo'lib chiqdi. Facebook iframe orqali ko'rsatilayotgan saytlar uchun avtorizatsiya qilish imkoniyatini ta'qiqlar ekan. Loyiha Amazonga deploy qilingan lekin domen ulanmagan, Deadline esa oynadan yorug'lik tushurib yanada tezlashtirishga undayotgan edi :) Google, StackOverflow qilib amazon domen ulashni topdim, lekin ulashga vaqt ko'p ketishi mumkin edi. uzb25.texnoman.uzga esa oddiygina JavaScriptda redirect yozib qo'ydim, muammo "g*vnokod" yordamida hal qilindi :) To'g'ri, bunday qilish umuman to'g'ri emas, lekin deadline bunaqa narsalarga qarab o'tirmas edi. Qisqasi bir amallab soat 8:00 da loyihani tayyor qildim, commit qildim, uxlashga kettim :)

Negadir uyqu kelmadi, soat 11:00larda turib saytdagi katta muammoni ko'rib qoldim :) Landing pagedagi video mobile telefonlarda ko'rinmas ekan. U yerga rasm qo'yish kerak ekan. Mayli deb, background uchun rasm topib qo'ydim. Agar videoni ocha olsa backgroundda video ko'rsatadi, agar ocha olmasa rasmni ko'rsatidigan qildim. Lekin katta xato bor edi, rasm qayta ishlaganda logoni bir necha joylari qiyshiq kesilgan ekan, rasmga esa logo hech mos kelgisi kelmaydi. Bir amallab photoshopdan O'zbekiston bayrog'ini "kesish"ga harakat qildim. Hammasi yaxshi, loyihani ishga tushirishdan oldin bironta odamdan feedback eshitmoqchi edim. Tanishlarga manzilni jo'natdim, Troll.uz administratoriga ham, birinchi feedbackni ham undan oldim :) Mayda-mayda narsalarni to'g'rilab soat 13:00 bo'lganini ham sezmay qolibman. Loyiha tayyor, "g*vnokod" qilib qo'ygan joylarimdan havotirlanib loyihani ishga tushurdik. Troll.uz Facebookda e'lon berdi. Shu bilan o'zimga-o'zim qo'ygan deadlinega ulgurganimni sezdim va birinchi natijani ko'rdim :)


Statistika uchun, 1 sentabr kuni:

Saytga tashrif buyurganlar soni: 595 ta;

Sessiyalar: 739 ta;

Yuklangan rasmlar soni: 1200ta.

Unchalik katta loyiha bo'lgani yo'q, hamma narsa shoshib, "g*vnokod" qilib yozib tashlangan edi. Masalan, ba'zi rasmlarni umuman qayta ishlay olmas edi, rasmni hajmi qancha katta bo'lsa, logo shunchalik kichik bo'lib qolar edi, rasm kichik bo'lsa, logo katta bo'lib ketar edi. Lekin, o'zimga yoqgan loyiha bo'ldi, o'zimga qo'ygan deadlinega ulgurdim!!! :)

Good Luck!


Mamatxalilov Farrux - Texnoman foydalanuvchisi

Muallif haqida

Mamatxalilov Farrux dasturchi


Blogdagi so‘nggi maqolalar:


Fikrlar 1

WinStyle
WinStyle
Odatda hakaton bo'lgan joyda xohlesizmi, yo'qmi, "g*vnokod" bo'lishi aniq(boshdan o'tgan)! Loyiha ishlasa bo'ldi. Qolgani ikkinchi darajali masala!!!
Iltimos, fikr bildirish uchun saytga kiring yoki ro‘yxatdan o‘ting!