diff --git a/modules/downloadalbum/controllers/downloadalbum.php b/modules/downloadalbum/controllers/downloadalbum.php new file mode 100644 index 00000000..83f4ab0c --- /dev/null +++ b/modules/downloadalbum/controllers/downloadalbum.php @@ -0,0 +1,258 @@ +init($id); + $files = $this->getFilesList($album); + + // Calculate ZIP size (look behind for details) + $zipsize = 22; + foreach($files as $f) { + $zipsize += 76 + 2*strlen($f) + filesize($f); + } + + // Send headers + $this->prepareOutput(); + $this->sendHeaders($album->name.'.zip', $zipsize); + + // Generate and send ZIP file + // http://www.pkware.com/documents/casestudies/APPNOTE.TXT (v6.3.2) + $lfh_offset = 0; + $cds = ''; + $cds_offset = 0; + foreach($files as $f) { + $f_namelen = strlen($f); + $f_size = filesize($f); + $f_mtime = $this->unix2dostime(filemtime($f)); + $f_crc32 = hexdec(hash_file('crc32b', $f, false)); + + // Local file header + echo pack('VvvvVVVVvva' . $f_namelen, + 0x04034b50, // local file header signature (4 bytes) + 0x0a, // version needed to extract (2 bytes) => 1.0 + 0x0800, // general purpose bit flag (2 bytes) => UTF-8 + 0x00, // compression method (2 bytes) => store + $f_mtime, // last mod file time and date (4 bytes) + $f_crc32, // crc-32 (4 bytes) + $f_size, // compressed size (4 bytes) + $f_size, // uncompressed size (4 bytes) + $f_namelen, // file name length (2 bytes) + 0, // extra field length (2 bytes) + + $f // file name (variable size) + // extra field (variable size) => n/a + ); + + // File data + readfile($f); + + // Data descriptor (n/a) + + // Central directory structure: File header + $cds .= pack('VvvvvVVVVvvvvvVVa' . $f_namelen, + 0x02014b50, // central file header signature (4 bytes) + 0x031e, // version made by (2 bytes) => v3 / Unix + 0x0a, // version needed to extract (2 bytes) => 1.0 + 0x0800, // general purpose bit flag (2 bytes) => UTF-8 + 0x00, // compression method (2 bytes) => store + $f_mtime, // last mod file time and date (4 bytes) + $f_crc32, // crc-32 (4 bytes) + $f_size, // compressed size (4 bytes) + $f_size, // uncompressed size (4 bytes) + $f_namelen, // file name length (2 bytes) + 0, // extra field length (2 bytes) + 0, // file comment length (2 bytes) + 0, // disk number start (2 bytes) + 0, // internal file attributes (2 bytes) + 0x81b40000, // external file attributes (4 bytes) => chmod 664 + $lfh_offset, // relative offset of local header (4 bytes) + + $f // file name (variable size) + // extra field (variable size) => n/a + // file comment (variable size) => n/a + ); + + // Update local file header/central directory structure offset + $cds_offset = $lfh_offset += 30 + $f_namelen + $f_size; + } + + // Archive decryption header (n/a) + // Archive extra data record (n/a) + + // Central directory structure: Digital signature (n/a) + echo $cds; // send Central directory structure + + // Zip64 end of central directory record (n/a) + // Zip64 end of central directory locator (n/a) + + // End of central directory record + $numfile = count($files); + $cds_len = strlen($cds); + echo pack('VvvvvVVv', + 0x06054b50, // end of central dir signature (4 bytes) + 0, // number of this disk (2 bytes) + 0, // number of the disk with the start of + // the central directory (2 bytes) + $numfile, // total number of entries in the + // central directory on this disk (2 bytes) + $numfile, // total number of entries in the + // central directory (2 bytes) + $cds_len, // size of the central directory (4 bytes) + $cds_offset, // offset of start of central directory + // with respect to the + // starting disk number (4 bytes) + 0 // .ZIP file comment length (2 bytes) + // .ZIP file comment (variable size) + ); + } + + + /** + * Init + */ + private function init($id) { + $item = ORM::factory("item", $id); + + // Only send an album + if (!$item->is_album()) { + // @todo: throw an exception? + Kohana::log('error', 'item is not an album: '.$item->relative_path()); + exit; + } + + // Must have view_full to download the originals files + access::required("view_full", $item); + + return $item; + } + + /** + * Return the files that must be included in the archive. + */ + private function getFilesList($album) { + $files = array(); + + // Go to the parent of album so the ZIP will not contains all the + // server hierarchy + if (!chdir($album->file_path().'/../')) { + // @todo: throw an exception? + Kohana::log('error', 'unable to chdir('.$item->file_path().'/../)'); + exit; + } + $cwd = getcwd(); + + $items = $album->viewable() + ->descendants(null, null, array(array("type", "<>", "album"))); + foreach($items as $i) { + if (!access::can('view_full', $i)) { + continue; + } + + $relative_path = str_replace($cwd.'/', '', realpath($i->file_path())); + if (!is_readable($relative_path)) { + continue; + } + + $files[] = $relative_path; + } + + if (count($files) === 0) { + // @todo: throw an exception? + Kohana::log('error', 'no zippable files in ['.$album->relative_path().']'); + exit; + } + + return $files; + } + + + /** + * See system/helpers/download.php + */ + private function prepareOutput() { + // Close output buffers + Kohana::close_buffers(FALSE); + // Clear any output + Event::add('system.display', create_function('', 'Kohana::$output = "";')); + } + + /** + * See system/helpers/download.php + */ + private function sendHeaders($filename, $filesize = null) { + if (!is_null($filesize)) { + header('Content-Length: '.$filesize); + } + + // Retrieve MIME type by extension + $mime = Kohana::config('mimes.'.strtolower(substr(strrchr($filename, '.'), 1))); + $mime = empty($mime) ? 'application/octet-stream' : $mime[0]; + header("Content-Type: $mime"); + header('Content-Transfer-Encoding: binary'); + + // Send headers necessary to invoke a "Save As" dialog + header('Content-Disposition: attachment; filename="'.$filename.'"'); + + // Prevent caching + header('Expires: Thu, 01 Jan 1970 00:00:00 GMT'); + + if (request::user_agent('browser') === 'Internet Explorer' + AND request::user_agent('version') <= '6.0') + { + // HTTP 1.0 + header('Pragma:'); + + // HTTP 1.1 with IE extensions + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + } + else + { + // HTTP 1.0 + header('Pragma: no-cache'); + + // HTTP 1.1 + header('Cache-Control: no-cache, max-age=0'); + } + } + + /** + * @return integer DOS date and time + * @param integer _timestamp Unix timestamp + * @desc returns DOS date and time of the timestamp + */ + private function unix2dostime($timestamp) + { + $timebit = getdate($timestamp); + + if ($timebit['year'] < 1980) { + return (1 << 21 | 1 << 16); + } + + $timebit['year'] -= 1980; + + return ($timebit['year'] << 25 | $timebit['mon'] << 21 | + $timebit['mday'] << 16 | $timebit['hours'] << 11 | + $timebit['minutes'] << 5 | $timebit['seconds'] >> 1); + } +} diff --git a/modules/downloadalbum/css/downloadalbum_menu.css b/modules/downloadalbum/css/downloadalbum_menu.css new file mode 100644 index 00000000..e3c4c67e --- /dev/null +++ b/modules/downloadalbum/css/downloadalbum_menu.css @@ -0,0 +1,3 @@ +#g-view-menu #g-download-album-link { + background-image: url('../images/ico-view-downloadalbum.png'); +} diff --git a/modules/downloadalbum/helpers/downloadalbum_event.php b/modules/downloadalbum/helpers/downloadalbum_event.php new file mode 100644 index 00000000..e2fe4420 --- /dev/null +++ b/modules/downloadalbum/helpers/downloadalbum_event.php @@ -0,0 +1,32 @@ +item)) { + $downloadLink = url::site("downloadalbum/zip/{$theme->item->id}"); + $menu + ->append(Menu::factory("link") + ->id("downloadalbum") + ->label(t("Download Album")) + ->url($downloadLink) + ->css_id("g-download-album-link")); + } + } +} diff --git a/modules/downloadalbum/helpers/downloadalbum_theme.php b/modules/downloadalbum/helpers/downloadalbum_theme.php new file mode 100644 index 00000000..2fd23552 --- /dev/null +++ b/modules/downloadalbum/helpers/downloadalbum_theme.php @@ -0,0 +1,26 @@ +item && access::can("view_full", $theme->item)) { + $theme->css("downloadalbum_menu.css"); + } + } +} diff --git a/modules/downloadalbum/images/ico-view-downloadalbum.png b/modules/downloadalbum/images/ico-view-downloadalbum.png new file mode 100644 index 00000000..ce7804d2 Binary files /dev/null and b/modules/downloadalbum/images/ico-view-downloadalbum.png differ diff --git a/modules/downloadalbum/module.info b/modules/downloadalbum/module.info new file mode 100644 index 00000000..177ad4a8 --- /dev/null +++ b/modules/downloadalbum/module.info @@ -0,0 +1,3 @@ +name = "DownloadAlbum" +description = "Displays a link to download a ZIP archive of the current album." +version = 1 diff --git a/modules/html_uploader/controllers/uploader.php b/modules/html_uploader/controllers/uploader.php new file mode 100644 index 00000000..e1232dda --- /dev/null +++ b/modules/html_uploader/controllers/uploader.php @@ -0,0 +1,107 @@ +is_album()) { + $album = $album->parent(); + } + + print json_encode(array("form" => (string) $this->_get_add_form($album))); + } + + public function add($id) { + $album = ORM::factory("item", $id); + access::required("view", $album); + access::required("add", $album); + access::verify_csrf(); + + $form = $this->_get_add_form($album); + if ($form->validate()) { + batch::start(); + + foreach (array("file1", "file2", "file3") as $key) { + if ($form->add_photos->$key->value == "") { + continue; + } + + try { + $temp_filename = $form->add_photos->$key->value; + $item = ORM::factory("item"); + $item->name = basename($temp_filename); + $item->title = item::convert_filename_to_title($item->name); + $item->parent_id = $album->id; + $item->set_data_file($temp_filename); + + $path_info = @pathinfo($temp_filename); + if (array_key_exists("extension", $path_info) && + in_array(strtolower($path_info["extension"]), array("flv", "mp4", "m4v"))) { + $item->type = "movie"; + $item->save(); + log::success("content", t("Added a movie"), + html::anchor("movies/$item->id", t("view movie"))); + } else { + $item->type = "photo"; + $item->save(); + log::success("content", t("Added a photo"), + html::anchor("photos/$item->id", t("view photo"))); + } + module::event("add_photos_form_completed", $item, $form); + + } catch (Exception $e) { + // Lame error handling for now. Just record the exception and move on + Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); + + // Ugh. I hate to use instanceof, But this beats catching the exception separately since + // we mostly want to treat it the same way as all other exceptions + if ($e instanceof ORM_Validation_Exception) { + Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1)); + } + } + + if (file_exists($temp_filename)) { + unlink($temp_filename); + } + } + batch::stop(); + print json_encode(array("result" => "success")); + } else { + print json_encode(array("result" => "error", "form" => (string) $form)); + } + } + + private function _get_add_form($album) { + $form = new Forge("uploader/add/{$album->id}", "", "post", array("id" => "g-add-photos-form")); + $group = $form->group("add_photos") + ->label(t("Add photos to %album_title", array("album_title" => html::purify($album->title)))); + $group->upload("file1")->add_rule("foo"); + $group->upload("file2"); + $group->upload("file3"); + + module::event("add_photos_form", $album, $form); + + $group = $form->group("buttons")->label(""); + $group->submit("")->value(t("Upload")); + + return $form; + } +} diff --git a/modules/html_uploader/module.info b/modules/html_uploader/module.info new file mode 100644 index 00000000..f3dc5dc8 --- /dev/null +++ b/modules/html_uploader/module.info @@ -0,0 +1,3 @@ +name = "HTML Uploader" +description = "Simple HTML uploader that replaces the Flash based uploader" +version = 1 diff --git a/modules/ldap/config/identity.php b/modules/ldap/config/identity.php index 3a4772c9..370d973a 100644 --- a/modules/ldap/config/identity.php +++ b/modules/ldap/config/identity.php @@ -1,7 +1,7 @@ "ldap", "allow_updates" => false, "params" => array( - "groups" => array("users", "guest"), + "groups" => array("eng", "google", "guest"), "everybody_group" => "guest", - "registered_users_group" => "users", - "admins" => array("jdoe"), - "url" => "ldap://127.0.0.1/", - "group_domain" => "ou=groups,dc=gallery,dc=local", - "user_domain" => "ou=people,dc=gallery,dc=local" + "registered_users_group" => "google", + "admins" => array("mediratta", "martinm"), + "url" => "ldaps://ldap.corp.google.com/", + "group_domain" => "ou=Posix,ou=Groups,dc=google,dc=com", + "user_domain" => "ou=People,dc=google,dc=com", + "bind_rdn" => null, + "bind_password" => null, ) ); diff --git a/modules/ldap/libraries/drivers/IdentityProvider/Ldap.php b/modules/ldap/libraries/drivers/IdentityProvider/Ldap.php index 9bde44b9..8fc45758 100644 --- a/modules/ldap/libraries/drivers/IdentityProvider/Ldap.php +++ b/modules/ldap/libraries/drivers/IdentityProvider/Ldap.php @@ -31,7 +31,11 @@ class IdentityProvider_Ldap_Driver implements IdentityProvider_Driver { self::$_params = $params; self::$_connection = ldap_connect(self::$_params["url"]); ldap_set_option(self::$_connection, LDAP_OPT_PROTOCOL_VERSION, 3); - ldap_bind(self::$_connection); + if (self::$_params["bind_rdn"]) { + ldap_bind(self::$_connection, self::$_params["bind_rdn"], self::$_params["bind_password"]); + } else { + ldap_bind(self::$_connection); + } } /** diff --git a/modules/moduleupdates/controllers/admin_moduleupdates.php b/modules/moduleupdates/controllers/admin_moduleupdates.php index fc9d1905..ba812515 100644 --- a/modules/moduleupdates/controllers/admin_moduleupdates.php +++ b/modules/moduleupdates/controllers/admin_moduleupdates.php @@ -47,16 +47,24 @@ class Admin_Moduleupdates_Controller extends Admin_Controller { foreach (module::available() as $this_module_name => $module_info) { + $remote_version = ''; + $remote_server = ''; + list ($remote_version, $remote_server) = $this->get_remote_module_version($this_module_name); $font_color = "black"; if ($remote_version == "DNE") { $font_color = "blue"; - } else if ($remote_version < $module_info->code_version) { + } else if ($module_info->version != '' and $module_info->code_version < $module_info->version) { + $font_color = "pink"; + } else if ($module_info->version != '' and $module_info->code_version > $module_info->version) { + $font_color = "orange"; + } else if ($remote_version < $module_info->code_version or ($module_info->version != '' and $remote_version < $module_info->version)) { $font_color = "green"; - } else if ($remote_version > $module_info->code_version) { + } else if ($remote_version > $module_info->code_version or ($module_info->version != '' and $remote_version > $module_info->version)) { $font_color = "red"; } + $all_modules->$this_module_name = array ("name" => $module_info->name, "locked" => $module_info->locked, "code_version" => $module_info->code_version, "active" => $module_info->active, "version" => $module_info->version,"description" => $module_info->description, @@ -91,7 +99,9 @@ class Admin_Moduleupdates_Controller extends Admin_Controller { try { $file = fopen ("http://github.com/gallery/gallery3/raw/master/modules/".$module_name."/module.info", "r"); - $server = '(G3)'; + if ($file != null) { + $server = '(G3)'; + } } catch (Exception $e) { //echo 'Message: ' .$e->getMessage() . '
'; @@ -100,7 +110,9 @@ class Admin_Moduleupdates_Controller extends Admin_Controller { if ($file == null) { try { $file = fopen ("http://github.com/gallery/gallery3-contrib/raw/master/modules/".$module_name."/module.info", "r"); - $server = '(G3CC)'; + if ($file != null) { + $server = '(G3CC)'; + } } catch (Exception $e) { //echo 'Message: ' .$e->getMessage() . '
'; diff --git a/modules/moduleupdates/views/admin_moduleupdates.html.php b/modules/moduleupdates/views/admin_moduleupdates.html.php index e4e3f038..8a7c6494 100644 --- a/modules/moduleupdates/views/admin_moduleupdates.html.php +++ b/modules/moduleupdates/views/admin_moduleupdates.html.php @@ -1,11 +1,13 @@
-

+


") ?> - Red = Out of Date
") ?> - Green = Your version is newer
") ?> + Red = Your version is older than the GitHub
") ?> + Green = Your version is newer than the GitHub
") ?> + Orange = Your file version is newer than the installed version
") ?> + Pink = Your installed version is newer than file version
") ?> Blue = Does Not Exist/No information available
") ?>

@@ -17,14 +19,14 @@ - + "> - + diff --git a/modules/user_homes/helpers/user_homes_event.php b/modules/user_homes/helpers/user_homes_event.php index 7cb0a487..65077809 100644 --- a/modules/user_homes/helpers/user_homes_event.php +++ b/modules/user_homes/helpers/user_homes_event.php @@ -178,13 +178,13 @@ class user_homes_event_Core { } } - static function album_add_form($form){ + static function album_add_form($parent, $form){ $group = $form->group("privacy") ->label(t("album privacy settings")); $group->checkbox("private")->label(t("Private"))->id("uh_private")->onClick("pc()"); $group->input("username")->label(t("Username"))->id("uh_username") - ->callback("user_homes_event::user_already_exists") + ->callback("user_homes_event::valid_name") ->error_messages("in_use", t("There is already a user with that username")) ->error_messages("required", t("You must enter a username"))->callback("user_homes_event::valid_name")->rules("length[1,32]"); $group->password("password")->label(t("Password"))->id("uh_password") diff --git a/themes/sobriety/js/ui.init.js b/themes/sobriety/js/ui.init.js index 2e1e6e89..4393a04a 100644 --- a/themes/sobriety/js/ui.init.js +++ b/themes/sobriety/js/ui.init.js @@ -43,6 +43,9 @@ $(document).ready(function() { }); } + // Remove titles for menu options since we're displaying that text anyway + $(".sf-menu a, .sf-menu li").removeAttr("title"); + // Album and search results views /*if ($("#g-album-grid").length) { // Set equal height for album items and vertically align thumbnails/metadata diff --git a/themes/sobriety/theme.info b/themes/sobriety/theme.info index f2bcb5f3..545a0815 100644 --- a/themes/sobriety/theme.info +++ b/themes/sobriety/theme.info @@ -4,5 +4,5 @@ version = 1 author = "Romain LE DISEZ" site = 1 admin = 0 -;wind commit = 2bbce8dddb0ab0a00aee727e2f639b793988a1d1 -;wind date = Thu Jun 17 09:10:01 2010 -0700 +;wind commit = 3b05db2685d92ca538d7993c960b06ea32f3a8df +;wind date = Wed Jun 23 11:16:56 2010 -0700 diff --git a/themes/sobriety/views/album.html.php b/themes/sobriety/views/album.html.php index eabe07c3..b9072e2b 100644 --- a/themes/sobriety/views/album.html.php +++ b/themes/sobriety/views/album.html.php @@ -29,7 +29,7 @@ admin || access::can("add", $item)): ?> - id") ?> + id") ?>
  • Add some.", array("attrs" => html::mark_clean("href=\"$addurl\" class=\"g-dialog-link\""))) ?>
  • diff --git a/themes/sobriety/views/form_uploadify.html.php b/themes/sobriety/views/form_uploadify.html.php index 6012f40b..62171c04 100644 --- a/themes/sobriety/views/form_uploadify.html.php +++ b/themes/sobriety/views/form_uploadify.html.php @@ -49,7 +49,7 @@ uploader: "", script: "id}") ?>", scriptData: , - fileExt: "*.gif;*.jpg;*.jpeg;*.png;*.flv;*.mp4;*.GIF;*.JPG;*.JPEG;*.PNG;*.FLV;*.MP4", + fileExt: "*.gif;*.jpg;*.jpeg;*.png;*.flv;*.mp4;*.m4v;*.GIF;*.JPG;*.JPEG;*.PNG;*.FLV;*.MP4;*.M4V", fileDesc: for_js() ?>, cancelImg: "", simUploadLimit: , @@ -166,4 +166,4 @@ */ -?> \ No newline at end of file +?> diff --git a/themes/sobriety/views/page.html.php b/themes/sobriety/views/page.html.php index 040ec1c5..cf10b85e 100644 --- a/themes/sobriety/views/page.html.php +++ b/themes/sobriety/views/page.html.php @@ -95,11 +95,13 @@ the immediate parent so that when you go back up a level you're on the right page. --> item()->id}" : null) ?>">title) ?> + "show={$theme->item()->id}" : null) ?>">title), 15) ?> -
  • ">item()->title) ?>
  • +
  • "> + item()->title), 15) ?> +
  • [File/Installed]") ?>
    "; ?> "; ?> "; ?> "; ?> "; ?>