Jump to content
Sergio

How to get and save Flickr albums to a page via API

Recommended Posts

Hello everyone,

greetings from Belo Horizonte / Brazil.

I'm on the process of converting a site from WP to Processwire, this one: http://www.ricardo-vargas.com 

I needed a simple Flickr Gallery and tried to find a way to create album pages via API and download the images to the local filesystem (just a few, for cache purposes).

So I created yesterday a simple script that, given an album ID, download its data using cURL and save the photos to a temp dir. After that, add them to a new page under /pictures/

Feel free to comment on the code, I'm a designer, not a developer, and this is my first time using PW API  :)

You can grab it on GitHub: https://github.com/sjardim/processwire-simple-flickr-album

Instructions

  1. Download the files
  2. Put the templates/get_flickr_sets.php on your templates/ folder.
  3. Create a page on Processwire using this template
  4. Create or edit the page where the albums will be created. In my case it was /pictures/
  5. IMPORTANT: Add guest edit/create permissions to this /pictures/ page, otherwise the script won't work
  6. Create a temp dir on your server and set it on the previous file
  7. Get a Flickr API on https://www.flickr.com/services/apps/create/
  8. Add one or more Flickr album IDs on get_flickr_sets.php
  9. Open the page using the get_flickr_sets.php template on your browser
<?php

include "../lib/curl.class.php";

// You will need to get a Flick API Key
// Get it here: https://www.flickr.com/services/apps/create/
// Load it on the file below
include "../lib/flickr_album_utils.php";

function download_file($url) {

  // Save the image on local filesystem (You need to create this folder first)
  // On your server it can be /var/www/name_of_folder/
  $tempdir = '/Users/XXX/phpFlickrCache/';
  
  $fp = $tempdir . basename(parse_url($url, PHP_URL_PATH));

  // if we already downloaded the images for some reason (like testing), just return it
  if (!file_exists($fp)) {

    $fh = fopen($fp, 'wb');
    
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1);
    curl_setopt($curl, CURLOPT_FILE, $fh);

    curl_exec($curl);
    curl_close($curl);
    fclose($fh);

  }

  return $fp;
}

// Get some public album id to test
$albumID = ["72157636029541784"];

//$albumID = ["72157649576832173", "72157633296236495", "72157644132091553", "72157636029541784"];

// Load ProcessWire API
$pages = wire('pages')->get('/pictures/');

 /* 
  --------------------------
  GET ALBUM INFO FROM FLICKR
  --------------------------
  */
 
foreach($albumID as $album) {

  // Via GET, return album and its photos info
	$album = fa_get_album($album);
  
  // create a new post
  $page = new Page();
  $page->template = 'picture_album';
  $page->parent = $pages;
    
  // disable page output formatting
  $page->of(false);

  
  $page->name = wire('sanitizer')->pageName($album['title'], true);  
  
  $page->flickr_album_id = $album['id'];
  $page->title = $album['title'];
  $page->generic_integer = $album['total']; //total number of photos on flickr album – OPTIONAL

  //My client albums descriptions have two phrases, one in English and other in Portuguese
  // let's separate then by the period, but sometimes there is no period, so the PT description will remain blank
  $description = explode('.', $album['description']);

  $en = $languages->get("default");  
  $page->summary->setLanguageValue($en, $description[0]);

  $pt = $languages->get("portuguese");  
  $page->summary->setLanguageValue($pt, $description[1]);
  
  $page->set("status$pt", 1); //activate portuguese page

  $page->save(); // We need to save the page BEFORE adding images
  
  /* 
  ------------------------------------
  DOWNLOAD AND SAVE IMAGES FROM FLICKR
  ------------------------------------
  */

  $images = array();

  $i=1;
  $maxImages = 11;

  foreach($album["all_images"] as $f) {

    //we do not want all the photos, just a little bit
    if ($i >= $maxImages) break;
    
    // mount the flickr photo url using its attributes
    $photo_url = 'https://farm'.$f["farm"].'.staticflickr.com/'.$f["server"].'/'.$f["id"].'_'.$f["secret"].'_b.jpg';
    
    // download and return the image file in the filesystem
    $images[$album['id']][$i] = download_file($photo_url);
    
    // add images to the current page in the loop
    $page->images->add($images[$album['id']][$i]);
    
    $i++;
  }

  $page->save();

  echo "<p>Created page for album: <strong>".$album['title']. "</strong></p>";

  // Tip: Now, after we saved the images to ProcessWire /site/assets/files/, we can safely delete them from the $tempdir if needed
 
}
print "<pre>";
print_r($images);
print "</pre>";

Admin Screenshot 

Screenshot.png

  • Like 7

Share this post


Link to post
Share on other sites

Big thanks for you. I modified your code because I didn't want to fetch images for downloading but just for linking.

I made a new template 'kuvat' (means photos) with fields for Flickr gallery id and image field for main page listing. Only bad thing is that user have to add each gallery separately. But works pretty well and better urls than what we had on Drupal.

I use smaller thumbnails (q is 150 x 150) for faster loading and Photobox effect for normal photos.

<?php
include "../lib/curl.class.php";
include "../lib/flickr_album_utils.php";
$album = fa_get_album($item);
$images = array();
foreach($album["all_images"] as $f) {    
$photo = 'https://farm'.$f["farm"].'.staticflickr.com/'.$f["server"].'/'.$f["id"].'_'.$f["secret"].'_b.jpg';
$thumb = 'https://farm'.$f["farm"].'.staticflickr.com/'.$f["server"].'/'.$f["id"].'_'.$f["secret"].'_q.jpg';
echo "<a class='event' href='$photo'><img src='$thumb' alt=''/>";
}
?>

 

  • Like 2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Chris Bennett
      Hi all, I am going round and round in circles and would greatly appreciate if anyone can point me in the right direction.
      I am sure I am doing something dumb, or missing something I should know, but don't. Story of my life 😉

      Playing round with a module and my basic problem is I want to upload an image and also use InputfieldMarkup and other Inputfields.
      Going back and forth between trying an api generated page defining Fieldgroup, Template, Fields, Page and the InputfieldWrapper method.

      InputfieldWrapper method works great for all the markup stuff, but I just can't wrap my head around what I need to do to save the image to the database.
      Can generate a Field for it (thanks to the api investigations) but not sure what I need to do to link the Inputfield to that. Tried a lot of stuff from various threads, of varying dates without luck.
      Undoubtedly not helped by me not knowing enough.

      Defining Fieldgroup etc through the api seems nice and clean and works great for the images but I can't wrap my head around how/if I can add/append/hook the InputfieldWrapper/InputfieldMarkup stuff I'd like to include on that template as well. Not even sure if it should be where it is on ___install with the Fieldtype stuff or later on . Not getting Tracy errors, just nothing seems to happen.
      If anyone has any ideas or can point me in the right direction, that would be great because at the moment I am stumbling round in the dark.
       
      public function ___install() { parent::___install(); $page = $this->pages->get('name='.self::PAGE_NAME); if (!$page->id) { // Create fieldgroup, template, fields and page // Create new fieldgroup $fmFieldgroup = new Fieldgroup(); $fmFieldgroup->name = MODULE_NAME.'-fieldgroup'; $fmFieldgroup->add($this->fields->get('title')); // needed title field $fmFieldgroup->save(); // Create new template using the fieldgroup $fmTemplate = new Template(); $fmTemplate->name = MODULE_NAME; $fmTemplate->fieldgroup = $fmFieldgroup; $fmTemplate->noSettings = 1; $fmTemplate->noChildren = 1; $fmTemplate->allowNewPages = 0; $fmTemplate->tabContent = MODULE_NAME; $fmTemplate->noChangeTemplate = 1; $fmTemplate->setIcon(ICON); $fmTemplate->save(); // Favicon source $fmField = new Field(); $fmField->type = $this->modules->get("FieldtypeImage"); $fmField->name = 'fmFavicon'; $fmField->label = 'Favicon'; $fmField->focusMode = 'off'; $fmField->gridMode = 'grid'; $fmField->extensions = 'svg png'; $fmField->columnWidth = 50; $fmField->collapsed = Inputfield::collapsedNever; $fmField->setIcon(ICON); $fmField->addTag(MODULE_NAME); $fmField->save(); $fmFieldgroup->add($fmField); // Favicon Silhouette source $fmField = new Field(); $fmField->type = $this->modules->get("FieldtypeImage"); $fmField->name = 'fmFaviconSilhouette'; $fmField->label = 'SVG Silhouette'; $fmField->notes = 'When creating a silhouette/mask svg version for Safari Pinned Tabs and Windows Tiles, we recommend setting your viewbox for 0 0 16 16, as this is what Apple requires. In many cases, the easiest way to do this in something like illustrator is a sacrificial rectangle with no fill, and no stroke at 16 x 16. This forces the desired viewbox and can then be discarded easily using something as simple as notepad. Easy is good, especially when you get the result you want without a lot of hassle.'; $fmField->focusMode = 'off'; $fmField->extensions = 'svg'; $fmField->columnWidth = 50; $fmField->collapsed = Inputfield::collapsedNever; $fmField->setIcon(ICON); $fmField->addTag(MODULE_NAME); $fmField->save(); $fmFieldgroup->add($fmField); // Create: Open Settings Tab $tabOpener = new Field(); $tabOpener->type = new FieldtypeFieldsetTabOpen(); $tabOpener->name = 'fmTab1'; $tabOpener->label = "Favicon Settings"; $tabOpener->collapsed = Inputfield::collapsedNever; $tabOpener->addTag(MODULE_NAME); $tabOpener->save(); // Create: Close Settings Tab $tabCloser = new Field(); $tabCloser->type = new FieldtypeFieldsetClose; $tabCloser->name = 'fmTab1' . FieldtypeFieldsetTabOpen::fieldsetCloseIdentifier; $tabCloser->label = "Close open tab"; $tabCloser->addTag(MODULE_NAME); $tabCloser->save(); // Create: Opens wrapper for Favicon Folder Name $filesOpener = new Field(); $filesOpener->type = new FieldtypeFieldsetOpen(); $filesOpener->name = 'fmOpenFolderName'; $filesOpener->label = 'Wrap Folder Name'; $filesOpener->class = 'inline'; $filesOpener->collapsed = Inputfield::collapsedNever; $filesOpener->addTag(MODULE_NAME); $filesOpener->save(); // Create: Close wrapper for Favicon Folder Name $filesCloser = new Field(); $filesCloser->type = new FieldtypeFieldsetClose(); $filesCloser->name = 'fmOpenFolderName' . FieldtypeFieldsetOpen::fieldsetCloseIdentifier; $filesCloser->label = "Close open fieldset"; $filesCloser->addTag(MODULE_NAME); $filesCloser->save(); // Create Favicon Folder Name $fmField = new Field(); $fmField->type = $this->modules->get("FieldtypeText"); $fmField->name = 'folderName'; $fmField->label = 'Favicon Folder:'; $fmField->description = $this->config->urls->files; $fmField->placeholder = 'Destination Folder for your generated favicons, webmanifest and browserconfig'; $fmField->columnWidth = 100; $fmField->collapsed = Inputfield::collapsedNever; $fmField->setIcon('folder'); $fmField->addTag(MODULE_NAME); $fmField->save(); $fmFieldgroup->add($tabOpener); $fmFieldgroup->add($filesOpener); $fmFieldgroup->add($fmField); $fmFieldgroup->add($filesCloser); $fmFieldgroup->add($tabCloser); $fmFieldgroup->save(); /////////////////////////////////////////////////////////////// // Experimental Markup Tests $wrapperFaviconMagic = new InputfieldWrapper(); $wrapperFaviconMagic->attr('id','faviconMagicWrapper'); $wrapperFaviconMagic->attr('title',$this->_('Favicon Magic')); // field show info what $field = $this->modules->get('InputfieldMarkup'); $field->name = 'use'; $field->label = __('How do I use it?'); $field->collapsed = Inputfield::collapsedNever; $field->icon('info'); $field->attr('value', 'Does this even begin to vaguely work?'); $field->columnWidth = 50; $wrapperFaviconMagic->add($field); $fmTemplate->fields->add($wrapperFaviconMagic); $fmTemplate->fields->save(); ///////////////////////////////////////////////////////////// // Create page $page = $this->wire( new Page() ); $page->template = MODULE_NAME; $page->parent = $this->wire('pages')->get('/'); $page->addStatus(Page::statusHidden); $page->title = 'Favicons'; $page->name = self::PAGE_NAME; $page->process = $this; $page->save(); } }  
    • By marcus
      wireshell 1.0.0 is out    
      See Bea's post
       


      -------- Original post -----------
        Now this one could be a rather long post about only an experimental niche tool, but maybe a helpful one for some, so stay with me   Intention Do you guys know "Artisan" (Laravel) or "Drush" (Drupal)? If not: These are command line companions for said systems, and very useful for running certain (e.g. maintenance, installation) task quickly - without having to use the Admin Interface, first and foremost when dealing with local ProcessWire installations. And since it has a powerful API and an easy way of being bootstrapped into CLIs like this, I think such a tool has a certain potential in the PW universe.    It's totally not the first approach of this kind. But: this one should be easily extendable - and is based on PHP (specifically: the Console component of the Symfony Framework). Every command is tidily wrapped in its own class, dependencies are clearly visible, and so on.   ( Here was the outdated documentation. Please visit wireshell.pw for the current one )
    • By horst
      Hi, on a site I want to disable access to original images and only allow to access thumbnails and watermarked image variations.
      EDIT:
      A good solution for protecting original images can be found a bit down in this thread:
       
      Old content of this initial post:
       
    • By Guy Incognito
      I seem to be running into a repeated fatal error in a fresh PW install version 3.0.148. I can't quite put my finger on the pattern but it seems to be around deleting image fields or removing images from certain image fields.
      This is the trace from the log generated by trying to save a page and delete an image from an image field:
      Fatal Error: Uncaught Error: Cannot access protected property Pageimage::$original in /wire/core/PageimageVariations.php:256 Stack trace: 1. /wire/core/Pageimage.php(1327): PageimageVariations->getInfo() 2. /wire/core/Wire.php(386): Pageimage->___isVariation() 3. /wire/core/WireHooks.php(823): Wire->_callMethod() 4. /wire/core/Wire.php(450): WireHooks->runHooks() 5. /wire/core/Pageimage.php(1369): Wire->__call() 6. /wire/core/Pageimage.php(399): Pageimage->getOriginal() 7. /wire/core/WireData.php(333): Pageimage->get() 8. /wire/core/PageimageVariations.php(256): Pro Line 256 of /wire/core/PageimageVariations.php Earlier in the day I was experimenting with custom fields for images for the first time and kept running into this error, thinking it was me using this feature wrong and not having time to read up I deleted the custom image fields template and went about my business. So now I don't know if I triggered an issue or whether it was never related to the custom image fields in the first place?
      Any ideas?
    • By humanafterall
      I'm using some Custom fields for images: 
      https://processwire.com/blog/posts/pw-3.0.142/#custom-fields-for-files-images

      When I save the page, and return the fields are blank. When I re-add the text to the fields and save again then the fields save as expected.

      I know this is stated as being quite experimental but it's super useful feature I'd love to get working correctly.
      I have fields that are CKEditor fields but have overidden this on the image specific template. I've also tried it with regular text fields and I get the same bug.
      (currently using Processwire 3.0.155)
      **UPDATE**
      I've found this issue is specific to editing on pages using the PageTable fieldtype. The fields are not saving when I save the page in the PageTable.
×
×
  • Create New...