Skip to content

U fajlu

.gitignore

navodimo putanje do fajlova i foldera koje treba na nivou projekta isključiti iz Gita. U fajlu

.git/info/exclude

možemo da navedemo putanje do fajlova i foldera koje treba lokalno isključiti iz Gita. Ako nam je Git već uhvatio izmenu na nekom od fajlova koje treba ignorisati, kucamo

git update-index --skip-worktree fajl

Prelazak sa jedne major verzije PostgreSQL-a na drugu (npr. sa verzije 10 na 11) zahteva migraciju baze. Procedura:

Najpre zaustavimo servis:

systemctl stop postgresql.service

Zatim izmestimo naše podatke i kreiramo direktorijum za nove podatke:

mv /data/postgres/data /data/postgres/olddata
mkdir /data/postgres/data /data/postgres/tmp
chown postgres:postgres /data/postgres/data /data/postgres/tmp

Pošto ja baze čuvam na nestandardnom mestu, imam dodatni korak da postgresu kažem gde se nalaze podaci. To se radi tako što se u fajlu

/usr/lib/systemd/system/postgresql.service

izmene putanje za Environment i PIDFile. Ili, još bolje, napravimo simbolički link tako da

/var/lib/postgres/data

pokazuje na naš novi data direktorijum.

Sledeći korak je da se ulogujemo kao korisnik postgres i kreiramo novi klaster baza:

su - postgres
initdb -D '/data/postgres/data'

Na kraju ide sama migracija podataka:

pg_upgrade -b /opt/pgsql-10/bin - B /usr/bin -d /data/postgres/olddata -D /data/postgres/data

U slučaju da radimo migraciju između verzija PostgreSQL-a koje "nisu jedna do druge" (npr. sa verzije 9.5 na 11), lakše će biti da bazu još dok smo pod starim PostgreSQL-om snimimo u fajl pa da je nakon nadogradnje vratimo iz fajla u klaster.

Kao i u gornjem primeru, prvo izmestimo naše podatke:

mv /data/postgres/data /data/postgres/olddata
mkdir /data/postgres/data /data/postgres/tmp
chown postgres:postgres /data/postgres/data /data/postgres/tmp

Zatim pokrećemo stari server:

/opt/pgsql-9.5/bin/pg_ctl -D /data/postgres/olddata/ start

i prebacujemo bazu u fajl:

pg_dumpall -f /data/postgres/old_backup.sql

Sada možemo da zaustavimo server

/opt/pgsql-9.6/bin/pg_ctl -D /data/postgres/olddata/ stop

instaliramo novi PostgreSQL, kreiramo novi klaster baza, pokrenemo servis i vratimo podatke iz fajla u bazu sa:

psql -f /data/postgres/old_backup.sql postgres

Ako sve radi kako treba možemo da obrišemo /data/postgres/old_backup.sql, /data/postgres/olddata i /data/postgres/tmp.

<?php
$url = "https://store.steampowered.com/app/658850/";

$doc = new DOMDocument;
libxml_use_internal_errors(true);
$doc->loadHTMLFile($url);
libxml_clear_errors();

$xpath = new DOMXpath($doc);

$title = $xpath->query('//div[@class="apphub_AppName"]');
if(count($title)) echo $title[0]->nodeValue . "\n";

$price = $xpath->query('//div[@class="discount_final_price"]');
if(count($price)){
    echo $price[0]->nodeValue . "\n";
} else{
    $price = $xpath->query('//div[@class="game_purchase_price price"]');
    if(count($price)){
        echo trim($price[0]->nodeValue) . "\n";
    }
}


Sajt https://free.scorespro.com/ je sajt sa kojeg možemo besplatno preuzimati sportske rezultate a koje kasnije možemo kao uslugu da ponudimo u različitim aplikacijama: IPTV, Android, veb itd. Radi poboljšanja ažurnosti sportskih rezultata javlja se potreba za optimizacijom procesa preuzimanja podataka.

Korak 1

Preuzimanje rezultata trenutno funkcioniše na sledeći način: sistemski šedjuler na svaka tri minuta pokreće skript koji skida rezultate za sve sportove redom (fudbal pa zatim košarka pa zatim tenis itd). Prvi korak je da se preuzimanje rezultata razdvoji po sportovima, odnosno, da se preuzimanje rezultata vrši nezavisno za svaki sport što samo po sebi neće ubrzati proces ali će biti dobra osnova za korak 2.

Korak 2

Potrebno je uvesti pravila za preuzimanje podataka. Npr., ako u nekom sportu nema utakmica koje su u toku, frekvencija preuzimanja podataka treba da se smanji sa jednom u tri minuta na npr. jednom u pet ili deset minuta. Sa druge strane, ako u sportu imamo aktivne utakmice, frekvencija preuzimanja podataka može da se poveća na npr. svaki minut.

Drugi primer je sport za koji nemamo zakazane utakmice u datom danu. U ovom slučaju ne bi bila greška ako ne bismo pozivali skript za preuzimanje podataka za taj sport više u tom danu ili, da bismo bili 100% sigurni, možemo za dati sport proveravati rezultate jednom u sat vremena.

Ovaj korak zahteva prelazak sa sistemskog šedjulera na deamon koji ima sopstveni šedjuler preuzimanja podataka.

Korak 3

Za svaki sport imamo listu utakmica, svaka utakmica ima vreme početka. Ako prva utakmica dana počinje u 17 sati, nema razloga proveravati rezultate za ovaj sport barem sat vremena pre početka prve utakmice. U ovom scenariju možemo da ne dobijemo pravovremenu informaciju o promenu statusa zakazane utakmice (npr. vreme početka je pomereno ili je utakmica odložena).

Korak 4

Ako u datom trenutku ne postoji aplikacija koja preko našeg API-ja preuzimaju rezultate, onda verovatno ne postoji potreba ni da mi u tom trenutku preuzimamo rezultate sa https://free.scorespro.com/ 🙂

U nekom ekstremnom scenariju, za svaki sport bi u bazi bilo zabeleženo vreme kada sledeći put treba preuzeti podatke sa https://free.scorespro.com/. Kada aplikacija preko našeg API-ja zatraži rezultate za određeni sport, prvo se proverava da li je prošao trenutak sledećeg preuzimanja podataka. Ako nije prošao, aplikacija dobija natrag postojeće rezultate iz baze. Ako jeste prošao trenutak, rezultati se prvo preuzimaju sa https://free.scorespro.com/, upisuju u bazu, ažurira se vreme kada sledeći put treba preuzeti podatke i onda se aplikaciji vraćaju ti ažurirani podaci (iz baze). U ovom slučaju, taj prvi korisnik koji inicira preuzimanje podataka sa https://free.scorespro.com/ će imati kašnjenje od par sekundi.

 

Za početak:

git clone <source> ~/projekat
cd ~/projekat
composer update
git clone https://github.com/laravel/homestead.gt ~/Homestead
cd ~/Homestead
git checkout v7.4.2
bash init.sh

Zatim editujemo ~/Homestead/Homestead.yaml u nešto poput ovog:

---
ip: "192.168.10.10"
memory: 2048
cpus: 1
provider: virtualbox

authorize: ~/.ssh/id_rsa.pub

keys:
    - ~/.ssh/id_rsa

folders:
    - map: ~/projekat
      to: /home/vagrant/code

sites:
    - map: projekat.local
      to: /home/vagrant/code/public

databases:
    - homestead

Nakon toga je potrebno dodati zapis u datoteku /etc/hosts:

192.168.10.10 projekat.local

I za kraj iz ~/Homestead direktorijuma pokrećemo virtuelnu mašinu:

vagrant up

October CMS možemo instalirati pomoću instalera, što je i preporučljiv način, a možemo i preko Kompozera:

composer create-project october/october projekat
cd projekat
php artisan october:install

Ako instalaciju vršimo preko Kompozera, onda ćemo u datoteci config/cms.php promenljivu disableCoreUpdates da postavimo na true.

Pošto ja imam običaj da projekte držim u svom home direktorijumu i da pravim simboličke linkove u /srv/http/, moraćemo da podesimo dozvole. Kao prvo i osnovno je da sebe dodam u grupu http. Nakon toga mogu ovako da podesim dozvole i da to sve manje-više radi kako treba 🙂

chown -R benke:http projekat/
chown -R http:http projekat/storage/
chmod -R ug+w projekat/

Na ovaj način mogu da menjam kod i iz Atoma i iz October CMS integrisanog editora i da nemam problema sa snimanjem dokumenata.

Na primeru jednostavnog HTML dokumenta:

<!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Modern JavaScript</title>
    <link rel="stylesheet" href="https://bootswatch.com/4/cyborg/bootstrap.min.css">
  </head>
  <body>
    <main role="main" class="container">
      <br>
      <div class="jumbotron">
        <h1 id="heading">Sample text</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia libero, laudantium at laboriosam neque repudiandae! Vel quae corporis debitis, asperiores, autem provident quaerat beatae totam possimus quia, esse necessitatibus porro.</p>
        <p>Necessitatibus sint vel animi magni, omnis ducimus libero, expedita nemo eveniet voluptatum in rerum temporibus quam provident perspiciatis delectus ex asperiores doloribus voluptatem tempora non soluta id. Deserunt, nihil, ad recusandae quisquam dicta deleniti dolorum ipsam magni, voluptatibus esse temporibus. Architecto, quaerat!</p>
        <p id="toRemove">To be removed</p>
      </div>

      <a href="#" id="link" class="btn btn-danger btn-lg">Don't push me</a>
    </main>
  </body>
</html>

imamo:

CSS stilizovanje

<script>
document.querySelector('.jumbotron').style.color('red');
document.querySelector('.jumbotron').style.color = 'cornflowerblue';
document.querySelectorAll('main p').forEach(p => p.style['font-family'] = 'arial');
</script>

CSS klase

<script>
document.querySelector('.jumbotron').classList.remove('jumbotron');
document.querySelector('.container').classList.add('active');
document.querySelectorAll('p').forEach(p => p.classList.add('active'));
</script>

Loading Events

<script>
document.addEventListener('DOMContentLoaded', init);
window.addEventListener('load', load);
</script>

forEach()

<script>
let p = document.querySelectorAll(".jumbotron p");
p.forEach((item, index) => {
console.log(index, item.textContent);
});
</script>

DOM manipulacije

<script>
  let heading = document.querySelector('#heading')
  console.log(heading.innerText)

  alert("Last paragraph will be removed")

  let el = document.querySelector('#toRemove')
  el.remove()

  let paragraphs = document.querySelectorAll(".jumbotron p")
  //console.log(jumbotron[0].innerText)
  Array.from(paragraphs).forEach(p => {
    console.log(p.innerText)
  })

  alert("Adding text")

  let jumbotron = document.querySelector('.jumbotron')
  jumbotron.prepend('And now something completely different...')
  jumbotron.before('Here goes Jumbotron:')

  let parent = jumbotron.parentNode
  console.log(parent)

let main = document.querySelector('main');
let par = document.createElement('p');
par.textContent = 'New paragraph';
main.insertAdjacentElement('beforeend', par);
//beforebegin, afterbegin, beforeend, afterend </script>

Događaji

<script>
  let link = document.querySelector('#link')
  link.addEventListener('click', e => {
    e.preventDefault()
    alert("Don't push me!")
  })

document.querySelector('.jumbotron').addEventListener('click', function(ev){
//this.style.color = 'purple';
ev.currentTarget.style.color = 'gold';
});

document.querySelectorAll('p').forEach(function(p, index){
p.addEventListener('mouseover', function(ev){
ev.currentTarget.style.backgroundColor = 'skyblue';
});
p.addEventListener('mouseout', function(ev){
ev.currentTarget.style.backgroundColor = 'transparent';
});
}); </script>

Ajax & vanilla JavaScript

<script>
const URL = 'http://jsonplaceholder.typicode.com/albums'; document.addEventListener('DOMContentLoaded', () => {
let req = new Request(URL, {
method: 'GET'
});
});
fetch(req)
.then(response => response.json())
.then(data => {
console.log(data);
console.log(JSON.stringify(data, null, 2));
})
.catch(err => {
console.log('error')
}); </script>

Ajax & Axios

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
  axios.get('https://swapi.co/api/starships')
  .then(res => console.log(res.data))
  .catch(error => console.log(error))
</script>

Izvor: Traversy Media, Steve Griffith

PHP funkcija mail() služi za slanje mejlova eksternim programom sendmail. sendmail je jako star program koji je bio dobar za ove stvari sve dok nije otkriveno da ima znatne propuste u pogledu sigurnosti. Zbog ovakve reputacije, mnoge Linuks distribucije ga više ne uvrštavaju u svoje repozitorijume već nude alternativna rešenja. Problem nastaje u tome što, ako PHP ne nađe program sendmail na sistemu, više ne može da pošalje mejl funkcijom mail(). Stoga ova alternativna rešenja za slanje mejlova često obezbeđuju "simulirani" sendmail kako bi se funkcionisanje programa koji zavise od njega nastavilo nesmetano.

Pošto se sendmail više ne nalazi u zvaničnim Arč repozitorijumima, instaliraćemo sSMTP, pojednostavljeno rešenje za slanje mejlova putem SMTP protokola. sSMTP nije kompletan mejl server i nema mogućnost primanja mejlova već služi samo da isporuči mejl sa lokalnog računara do mejl servera a to je ono što nama treba. Plus, sSMTP je kompatibilan sa programom sendmail i pravi simbolički link /usr/bin/sendmail 🙂

lrwxrwxrwx 1 root root 5 феб 18 2017 /usr/bin/sendmail -> ssmtp

sSMTP-u je potrebno navesti kojem mejl serveru treba da šalje mejlove, koji su kredencijali i slično. Sve to se čuva u konfiguracionom fajlu /etc/ssmtp/ssmtp.conf . Primer konfiguracionog fajla:

root=postmaster
mailhub=mail.server.com:465
AuthUser=username
AuthPass=password
rewriteDomain=server.com
FromLineOverride=YES
UseTLS=YES

A log možemo da vidimo sa

journalctl -f | grep sSMTP

 

Najpre instaliramo Javu i Gradle:

pacman -S jdk8-openjdk gradle

Sledeći na redu je Android Studio koji se nalazi u AUR repozitorijumu:

yaourt -S android-studio

Pokrenemo Android Studio i instaliramo SDK. Ja preferiram instalaciju u svom home direktorijumu, npr. u ~/android-sdk pošto ionako nemam dozvolu za snimanje u /opt direktorijum 🙂 Zatim bitna stvar, treba da prihvatimo licence:

cd ~/android-sdk/tools/bin
./sdkmanager --licenses

i odgovorimo sa yes na sva pitanja. Za kraj u promenljivu ANDROID_HOME postavimo putanju do SDK kako bi Gradle znao gde da ga traži:

export ANDROID_HOME=~/android-sdk

Sada možemo da radimo na našem projektu u Ionic-u.

Kada budemo bili spremni da napravimo APK, kucamo

ionic cordova plugin rm cordova-plugin-console
ionic cordova build --release android

Čime ćemo dobiti "nepotpisanu" verziju aplikacije. Nakon toga generišemo privatan ključ

keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

a "potpisivanje" aplikacije se vrši sa

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore platforms/android/build/outputs/apk/Projekat-release-unsigned.apk alias_name

Za kraj nam ostaje da pokrenemo zipalign:

~/android-sdk/build-tools/26.0.1/zipalign -v 4 platforms/android/build/outputs/apk/Projekat-release-unsigned.apk Projekat.apk

Izvor: ionicframework.com