Giter VIP home page Giter VIP logo

libfetlife's Introduction

libFetLife - README

libFetLife is a PHP class implementing a simple API useful for interfacing with the amateur porn and fetish dating website FetLife.com. Learn more about the political motivation for this library.

System requirements

To run libFetLife, you need PHP version 5.3.6 or greater (with PHP's cURL extension installed).

Getting started

To use libFetLife, include it in your project and instantiate a new FetLifeUser object:

// Load FetLife API.
require_once 'libFetLife/FetLife.php';

// Make a FetLifeUser (like a database handle).
$FL = new FetLifeUser('username', 'password');

You can optionally instruct libFetLife to use a proxy instead of making direction connections to FetLife.com:

$FL->connection->setProxy('example.proxy.com:9050', CURLPROXY_SOCKS5); // Optional.
$FL->connection->setProxy('auto'); // or, set a new randomized proxy automatically.

When you're ready, login with the FetLifeUser::logIn() method:

$FL->logIn();

Now $FL represents you on FetLife:

// Print some basic information about the account you're using.
print $FL->id;       // your user's numeric ID.
print $FL->nickname; // your user's nickname, the name you signed in with
//etc.

You use the FetLifeUser object's various public methods to send queries to FetLife. Replies depend on the query method:

// Query FetLife for information about other users.
print $FL->getUserIdByNickname('JohnBaku'); // prints "1"
print $FL->getUserNicknameById(1254);       // prints "maymay"

Other FetLife users are represented as FetLifeProfile objects:

// Object-oriented access to user info is available as FetLifeProfile objects.
$profile = $FL->getUserProfile(1);          // Profile with ID 1
$profile->nickname;                         // "JohnBaku"
$profile->age;
$profile->gender;
$profile->role;

// the `adr` member is an array keyed like its eponymous microformat:
$profile->adr['locality'];     // "Vancouver"
$profile->adr['region'];       // "British Columbia"
$profile->adr['country-name']; // "Canada"

// Some FetLifeProfile methods:
$profile->getAvatarURL();     // optional $size parameter retrieves larger images
$profile->isPayingAccount();  // true if the profile has a "supporter" badge
$profile->getEvents();        // array of FetLifeEvent objects listed on the profile
$profile->getEventsGoingTo(); // array of FetLifeEvent the user has RSVP'ed "going" to
$profile->getGroups();        // array of FetLifeGroup objects listed on the profile
$profile->getGroupsLead();    // array of FetLifeGroups the user moderates

Many methods return arrays of FetLifeProfile objects. Since queries are live, they can also be passed an optional page limiter.

// Get a user's friends list as an array of FetLifeProfile objects.
$friends = $FL->getFriendsOf('maymay');
// A numeric FetLife user ID also works.
$friends = $FL->getFriendsOf(1254);
// If there are many pages, you can set a limit.
$friends_partial = $FL->getFriendsOf('maymay', 3); // Only first 3 pages.

// Numerous other functions also return arrays, with optional page limit.
$members = $FL->getMembersOfGroup(11708); // "Kink On Tap"
$kinksters = $FL->getKinkstersWithFetish(193); // "Corsets"
$local_kinksters = $FL->getKinkstersInLocation('cities/5898'); // all kinksters in Balitmore, MD.
$attendees = $FL->getKinkstersGoingToEvent(149379);
$maybes = $FL->getKinkstersMaybeGoingToEvent(149379, 2); // Only 2 pages.

Most data objects, including FetLifeProfile, FetLifeWriting, and FetLifePicture are descended from a common FetLifeContent base class. Such descendants have a populate() method that fetches supplemental information about the object from FetLife:

// You can also fetch arrays of a user's FetLife data as objects this way.
$writings = $FL->getWritingsOf('JohnBaku'); // All of JohnBaku's Writings.
$pictures = $FL->getPicturesOf(1);          // All of JohnBaku's Pictures.

// If you want to fetch comments, you need to populate() the objects.
$writings_and_pictures = array_merge($writings, $pictures);
foreach ($writings_and_pictures as $item) {
    $item->comments;   // currently, returns an NULL
    $item->populate();
    $item->comments;   // now, returns an array of FetLifeComment objects.
}

FetLife events can be queried much like profiles:

// If you already know the event ID, you can just fetch that event.
$event = $FL->getEventById(151424);
// "Populate" behavior works the same way.
$event = $FL->getEventById(151424, true); // Get all availble event data.

// You can also fetch arrays of events as FetLifeEvent objects.
$events = $FL->getUpcomingEventsInLocation('cities/5898'); // Get all events in Balitmore, MD.
// Or get just the first couple pages.
$events_partial = $FL->getUpcomingEventsInLocation('cities/5898', 2); // Only 2 pages.

// FetLifeEvent objects are instantiated from minimal data.
// To fill them out, call their populate() method.
$events[0]->populate(); // Flesh out data from first event fetched.
// RSVP lists take a while to fetch, but you can get them, too.
$events[1]->populate(2); // Fetch first 2 pages of RSVP responses.
$events[2]->populate(true); // Or fetch all pages of RSVP responses.

// Now we have access to some basic event data.
print $events[2]->getPermalink();
print $events[2]->venue_name;
print $events[2]->dress_code;
// etc...

// Attendee lists are arrays of FetLifeProfile objects, same as friends lists.
// You can collect a list of all participants
$everyone = $events[2]->getParticipants();

// or interact with the separate RSVP lists individually
foreach ($events[2]->going as $profile) {
    print $profile->nickname; // FetLife names of people who RSVP'd "Going."
}
$i = 0;
$y = 0;
foreach ($events[2]->maybegoing as $profile) {
    if ('Switch' === $profile->role) { $i++; }
    if ('M' === $profile->gender) { $y++; }
}
print "There are $i Switches and $y male-identified people maybe going to {$events[2]->title}.";

You can also perform basic searches:

$kinksters = $FL->searchKinksters('maymay'); // All Kinksters whose username contains the query.
$partial_kinksters = $FL->searchKinksters('maymay', 5) // only first 5 pages of above results.

Patches welcome. :)

Testing

libFetLife uses PHPUnit for unit testing. The tests/ directory includes a phpunit.xml.sample file with a default configuration. To run live tests, you need to edit this file so that the global variables fetlife_username, fetlife_password, and fetlife_proxyurl have the values you want to use to create the test runner's FetLifeUser object, as described above, and then copy it to phpunit.xml.

cd libFetLife/tests               # Inside the tests directory...
vi phpunit.xml.sample             # is a sample PHPUnit configuration file. Edit it.
cp phpunit.xml.sample phpunit.xml # Then copy it to PHPUnit's expected location.

Projects that use libFetLife

Are you using libFetLife? Let me know.

libfetlife's People

Contributors

corsair avatar fabacab avatar hornygeek avatar ineffyble avatar raincoats avatar shandadf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

libfetlife's Issues

Add function to get events by organiser

My draft:

In class FetLifeContent

    public function getEventsOrganised () {
        return $this->events_organised;
    }

In ParseHtml() of class FetLifeContent

        // Parse out event info
        $x = $this->usr->parseAssociatedContentInfo($doc, 'event', true);
        $ret['events_going'] = $x->item_ids;
        $ret['events'] = $x->items;
        $ret['events'] = array_merge($ret['events'], $x->items);

        //Parse out organised event info
        $x = $this->usr->parseAssociatedContentInfo($doc, 'organizing', false);
        $ret['events_organised'] = $x->items;

In parseAssociatedContentInfo() of class FetLifeUser

switch ($obj_type) {
            case 'event':
                $str = ($is_leader) ? 'Events going to' : 'Events maybe going to';
                break;
            case 'organizing':
                $str = 'Events organizing';
                $obj_type = 'event';
                break;
            case 'writing':
                $str = 'Writing';
                break;
            case 'group':
                $str = ($is_leader) ? 'Groups I lead' : 'Groups member of';
                break;
        }

Usage:

$organiser = $fetlifeUser->getUserProfile($organiser_id);
$events = $organiser->getEventsOrganised();

Allow easy debug (or just give that as an option) - htmlentities

In doHttpRequest() of class FetLife:

$r = array();
        $this->cur_page = $r['body'] = curl_exec($ch); // Grab FetLife response body.
        $this->setCsrfToken($this->findCsrfToken($r['body'])); // Update on each request.
        $r['curl_info'] = curl_getinfo($ch);
        curl_close($ch);
        $this->cur_page = htmlentities($this->cur_page, ENT_COMPAT, 'UTF-8');

In all the getContentHtml methods:

// Add a parameter
getContentHtml ($pristine = true) 
$html = $pristine ? $html : htmlentities($html, ENT_COMPAT, 'UTF-8');
return $html;

FindUserId always returns false

/**
     * Given some HTML from FetLife, this finds the current user ID.
     *
     * @param string $str Some raw HTML expected to be from FetLife.com.
     * @return mixed User ID on success. False on failure.
     */
    public function findUserId ($str) {
        $matches = array();
        preg_match('/var currentUserId = ([0-9]+);/', $str, $matches);
        return $matches[1];
    }

the regex seems to be wrong - that one works:

'/FetLife.currentUser.id          = ([0-9]+);/'

Add function to get a single writing

My draft:

    /**
     * Retrieves a user's single Writing.
     *
     * @param mixed $id ID of a FetLife Writing.
     * @param mixed $who User whose FetLife Writings to fetch. If a string, treats it as a FetLife nickname and resolves to a numeric ID. If an integer, uses that ID. By default, the logged-in user.
     * @return mixed $writing A FetLifeWriting object, false if not found.
     */
    function getWritingOf ($id, $who = NULL) {
        $author_id = $this->resolveWho($who);

        $x            = array();
        $x['creator'] = $this->getUserProfile($author_id);
        $x['id']      = $id;
        $x['usr']     = $this;
        $ret = new FetLifeWriting($x);
        $ret->populate();

        return $ret;
    }

Make objects serializable

My draft:
In class FetLife:

function __sleep () {
        if (isset($this->content) && !empty($this->content)) {
            $this->content = $this->getContentHtml();
        }
        return array_keys(get_object_vars($this));
    }

    function __wakeup () {
        $html = $this->content;
        $nodes = array();
        $doc = new DOMDocument();
        @$doc->loadHTML("<html>{$html}</html>");
        $child = $doc->documentElement->firstChild;
        while($child) {
            $nodes[] = $doc->importNode($child,true);
            $child = $child->nextSibling;
        }
        $this->content = reset($nodes);
    }

Recent Fetlife Login / Session Changes

In the last couple weeks, changes were made on Fetlife internally that changed the way login sessions and cookies are handled, and as such it appears it has caused the entire library to break.

Attempting to get user profiles results in errors, and attempting to collect a profile's ID results in "login" instead of an integer.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.